Transpiled version (5451L) is out of date.
1 | // uses hash sets as inner sets unless subclassed |
2 | // uses a hash map as the outer map by default |
3 | sclass MultiSetMap<A, B>is IMultiMap<A, B> { |
4 | Map<A, Set<B>> data = new HashMap<A, Set<B>>(); |
5 | int size; // number of values |
6 | |
7 | *() {} |
8 | *(bool useTreeMap) { if (useTreeMap) data = new TreeMap; } |
9 | *(MultiSetMap<A, B> map) { putAll(map); } |
10 | *(Map<A, Set<B>> *data) {} |
11 | |
12 | bool put(A key, B value) { synchronized(data) { |
13 | Set<B> set = data.get(key); |
14 | if (set == null) |
15 | data.put(key, set = _makeEmptySet()); |
16 | if (!set.add(value)) false; |
17 | ret true with ++size; |
18 | }} |
19 | |
20 | bool add(A key, B value) { ret put(key, value); } |
21 | |
22 | void addAll(A key, Collection<B> values) { synchronized(data) { |
23 | putAll(key, values); |
24 | }} |
25 | |
26 | void addAllIfNotThere(A key, Collection<B> values) { synchronized(data) { |
27 | for (B value : values) |
28 | setPut(key, value); |
29 | }} |
30 | |
31 | void setPut(A key, B value) { synchronized(data) { |
32 | if (!containsPair(key, value)) |
33 | put(key, value); |
34 | }} |
35 | |
36 | boolean containsPair aka contains(A key, B value) { synchronized(data) { |
37 | ret get(key).contains(value); |
38 | }} |
39 | |
40 | void putAll(A key, Collection<B> values) { synchronized(data) { |
41 | for (B value : values) |
42 | put(key, value); |
43 | }} |
44 | |
45 | void removeAll(A key, Collection<B> values) { synchronized(data) { |
46 | for (B value : values) |
47 | remove(key, value); |
48 | }} |
49 | |
50 | public Set<B> get(A key) { synchronized(data) { |
51 | Set<B> set = data.get(key); |
52 | return set == null ? Collections.<B> emptySet() : set; |
53 | }} |
54 | |
55 | L<B> getAndClear(A key) { synchronized(data) { |
56 | L<B> l = cloneList(data.get(key)); |
57 | remove(key); |
58 | ret l; |
59 | }} |
60 | |
61 | // return null if empty |
62 | Set<B> getOpt(A key) { synchronized(data) { |
63 | ret data.get(key); |
64 | }} |
65 | |
66 | // returns actual mutable live set |
67 | // creates the set if not there |
68 | Set<B> getActual(A key) { synchronized(data) { |
69 | Set<B> set = data.get(key); |
70 | if (set == null) |
71 | data.put(key, set = _makeEmptySet()); |
72 | ret set; |
73 | }} |
74 | |
75 | // TODO: this looks unnecessary |
76 | void clean(A key) { synchronized(data) { |
77 | Set<B> list = data.get(key); |
78 | if (list != null && list.isEmpty()) |
79 | data.remove(key); |
80 | }} |
81 | |
82 | public Set<A> keySet aka keys() { synchronized(data) { |
83 | return data.keySet(); |
84 | }} |
85 | |
86 | void remove(A key) { synchronized(data) { |
87 | size -= l(data.get(key)); |
88 | data.remove(key); |
89 | }} |
90 | |
91 | void remove(A key, B value) { synchronized(data) { |
92 | Set<B> set = data.get(key); |
93 | if (set != null) { |
94 | if (set.remove(value)) { |
95 | --size; |
96 | if (set.isEmpty()) |
97 | data.remove(key); |
98 | } |
99 | } |
100 | }} |
101 | |
102 | void clear() { synchronized(data) { |
103 | data.clear(); |
104 | size = 0; |
105 | }} |
106 | |
107 | boolean containsKey(A key) { synchronized(data) { |
108 | return data.containsKey(key); |
109 | }} |
110 | |
111 | B getFirst(A key) { synchronized(data) { |
112 | return first(get(key)); |
113 | }} |
114 | |
115 | void addAll(MultiSetMap<A, B> map) { putAll(map); } |
116 | |
117 | void putAll(MultiSetMap<A, B> map) { synchronized(data) { |
118 | for (A key : map.keySet()) |
119 | putAll(key, map.get(key)); |
120 | }} |
121 | |
122 | void putAll(Map<A, B> map) { synchronized(data) { |
123 | if (map != null) for (Map.Entry<A, B> e : map.entrySet()) |
124 | put(e.getKey(), e.getValue()); |
125 | }} |
126 | |
127 | public int keysSize aka keyCount() { synchronized(data) { ret l(data); }} |
128 | |
129 | // full size |
130 | public int size() { synchronized(data) { |
131 | ret size; |
132 | }} |
133 | |
134 | // count values for key |
135 | int getSize(A key) { ret l(data.get(key)); } |
136 | int count(A key) { ret getSize(key); } |
137 | |
138 | // expensive operation |
139 | Set<A> reverseGet(B b) { synchronized(data) { |
140 | new Set<A> l; |
141 | for (A key : data.keySet()) |
142 | if (data.get(key).contains(b)) |
143 | l.add(key); |
144 | ret l; |
145 | }} |
146 | |
147 | // expensive operation |
148 | A keyForValue(B b) { synchronized(data) { |
149 | for (A key : data.keySet()) |
150 | if (data.get(key).contains(b)) |
151 | ret key; |
152 | null; |
153 | }} |
154 | |
155 | Map<A, Set<B>> asMap() { synchronized(data) { |
156 | ret cloneMap(data); |
157 | }} |
158 | |
159 | public bool isEmpty() { synchronized(data) { ret data.isEmpty(); }} |
160 | |
161 | // override in subclasses |
162 | Set<B> _makeEmptySet() { |
163 | ret new HashSet; |
164 | } |
165 | |
166 | Collection<Set<B>> allLists() { |
167 | synchronized(data) { |
168 | ret new Set(data.values()); |
169 | } |
170 | } |
171 | |
172 | L<B> allValues() { |
173 | ret concatLists(values(data)); |
174 | } |
175 | |
176 | LPair<A, B> allEntries() { synchronized(data) { |
177 | LPair<A, B> l = emptyList(size); |
178 | for (A a, Set<B> set : data) |
179 | for (B b : set) |
180 | l.add(pair(a, b)); |
181 | ret l; |
182 | }} |
183 | |
184 | O mutex() { ret data; } |
185 | |
186 | toString { ret "mm" + str(data); } |
187 | |
188 | Pair<A, B> firstEntry() { synchronized(data) { |
189 | if (empty(data)) null; |
190 | Map.Entry<A, Set<B>> entry = data.entrySet().iterator().next(); |
191 | ret pair(entry.getKey(), first(entry.getValue())); |
192 | }} |
193 | |
194 | A firstKey() { synchronized(data) { ret main firstKey(data); }} |
195 | A lastKey() { synchronized(data) { ret (A) ((NavigableMap) data).lastKey(); }} |
196 | |
197 | A higherKey(O a) { synchronized(data) { ret (A) ((NavigableMap) data).higherKey(a); }} |
198 | } |
Began life as a copy of #1001296
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: | #1024456 |
Snippet name: | MultiSetMap - synchronized MultiMap with a Set as value structure |
Eternal ID of this version: | #1024456/36 |
Text MD5: | c4f8af3eadfd34c901b932e1093084f7 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2023-02-14 12:47:36 |
Source code size: | 5118 bytes / 198 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 512 / 1305 |
Version history: | 35 change(s) |
Referenced in: | [show references] |