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: | 806 / 1659 |
| Version history: | 35 change(s) |
| Referenced in: | [show references] |