Libraryless. Click here for Pure Java version (2925L/19K).
1 | // A = element (e.g. a word) |
2 | // B = instance (e.g. a text snippet) |
3 | // should support concurrent lookups |
4 | transient sclass ElementInstanceMatrix<B, A> { |
5 | new UniqueList<B> instances; |
6 | new Map<A, Entry> index; |
7 | |
8 | swappable int instanceToNumber(B b) { ret instances.addOrGetIndex(b); } |
9 | swappable B numberToInstance(int i) { ret instances.get(i); } |
10 | swappable Set<A> extractElements(B instance) { fail("implement me"); } |
11 | |
12 | bool doneAdding; |
13 | |
14 | // each word can be represented as either an int array, a bit set or both |
15 | // for now, the int array is always there |
16 | sclass Entry { |
17 | new Set<Int> intSet; // while building the index |
18 | int[] intArray; |
19 | BitSet bitSet; |
20 | |
21 | BitSet bitSet() { |
22 | if (bitSet == null) |
23 | bitSet = intArrayToBitSet(intArray); |
24 | ret bitSet; |
25 | } |
26 | |
27 | int count() { ret intArray.length; } |
28 | } |
29 | |
30 | *() {} |
31 | |
32 | void add(B instance, Cl<A> elements default extractElements(instance)) { |
33 | assertFalse(doneAdding); |
34 | int idx = instanceToNumber(instance); |
35 | fOr (A word : elements) addMatrixDot(idx, word); |
36 | } |
37 | |
38 | void addMatrixDot(int idx, A word) { |
39 | Entry e = index.get(word); |
40 | if (e == null) index.put(word, e = new Entry); |
41 | e.intSet.add(idx); |
42 | } |
43 | |
44 | // Call this exactly once before doing queries on the index |
45 | void doneAdding() { |
46 | if (doneAdding) ret; |
47 | set doneAdding; |
48 | for (Entry e : values(index)) { |
49 | e.intArray = sortIntArrayInPlace(toIntArray(e.intSet)); |
50 | e.intSet = null; |
51 | } |
52 | } |
53 | |
54 | L<B> instancesContainingElement(A element) { |
55 | ret instanceListFromIntArray(instancesContainingElement_intArray(element)); |
56 | } |
57 | |
58 | int[] instancesContainingElement_intArray(A element) { |
59 | doneAdding(); |
60 | Entry e = index.get(element); |
61 | ret e == null ? null : e.intArray; |
62 | } |
63 | |
64 | L<B> instanceListFromIntArray(int[] array) { |
65 | ret array == null ? null : listFromFunction(array.length, i -> numberToInstance(array[i])); |
66 | } |
67 | |
68 | // may return null (=empty list) |
69 | L<B> instancesContainingAllElements(Cl<A> elements) { |
70 | ret instanceListFromIntArray(instancesContainingAllElements_intArray(elements)); |
71 | } |
72 | |
73 | // may return null (=empty list). also returns null for 0 elements |
74 | int[] instancesContainingAllElements_intArray(Cl<A> elements) { |
75 | doneAdding(); |
76 | int n = l(elements); |
77 | if (n == 0) null; |
78 | if (n == 1) ret instancesContainingElement_intArray(first(elements)); |
79 | |
80 | // get entries for elements, exit when an element is unknown |
81 | Entry[] entries = new[n]; |
82 | Iterator<A> itElements = iterator(elements); |
83 | for i to n: { |
84 | Entry e = index.get(itElements.next()); |
85 | if (e == null) null; |
86 | entries[i] = e; |
87 | } |
88 | |
89 | // go through elements again, AND-combine all bit sets |
90 | BitSet bs = cloneBitSet(entries[0].bitSet()); |
91 | for (int i = 1; i < n; i++) |
92 | bs.and(entries[i].bitSet()); |
93 | |
94 | ret bitSetToIntArray(bs); |
95 | } |
96 | |
97 | L<B> instancesThatAreSuperSetsOf(B instance, O... _) { |
98 | ret instancesContainingAllElements(extractElements(instance)); |
99 | } |
100 | |
101 | NavigableSet<S> elements() { ret (NavigableSet) keys(index); } |
102 | |
103 | int numElements() { ret l(index); } |
104 | } |
Began life as a copy of #1029068
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1029075 |
Snippet name: | ElementInstanceMatrix |
Eternal ID of this version: | #1029075/20 |
Text MD5: | e4e031dbe5e676713f1d8173eb8b2362 |
Transpilation MD5: | e6028a6b8d929756332ddcb31637e9fe |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-07-19 03:15:14 |
Source code size: | 3201 bytes / 104 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 262 / 600 |
Version history: | 19 change(s) |
Referenced in: | [show references] |