Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

198
LINES

< > BotCompany Repo | #1024456 // MultiSetMap - synchronized MultiMap with a Set as value structure

JavaX fragment (include) [tags: use-pretranspiled]

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  
}

Author comment

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]