441dab3eacd8360714edb1dea566fc39e0ab37cd
[platform/upstream/libgee.git] / gee / abstractmultimap.vala
1 /* abstractmultimap.vala
2  *
3  * Copyright (C) 2009  Ali Sabil
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
18  *
19  * Author:
20  *      Ali Sabil <ali.sabil@gmail.com>
21  *      Didier 'Ptitjes Villevalois <ptitjes@free.fr>
22  */
23
24 /**
25  * Skeletal implementation of the {@link MultiMap} interface.
26  *
27  * @see HashMultiMap
28  * @see TreeMultiMap
29  */
30 public abstract class Gee.AbstractMultiMap<K,V> : Object, MultiMap<K,V> {
31         public int size {
32                 get { return _nitems; }
33         }
34         
35         public bool read_only {
36                 get { return false; }
37         }
38
39         protected Map<K, Collection<V>> _storage_map;
40         private int _nitems = 0;
41
42         public AbstractMultiMap (Map<K, Collection<V>> storage_map) {
43                 this._storage_map = storage_map;
44         }
45
46         public Set<K> get_keys () {
47                 return _storage_map.keys;
48         }
49
50         public MultiSet<K> get_all_keys () {
51                 return new AllKeys<K, V> (this);
52         }
53
54         public Collection<V> get_values () {
55                 return new Values<K, V> (this);
56         }
57
58         public bool contains (K key) {
59                 return _storage_map.has_key (key);
60         }
61
62         public new Collection<V> get (K key) {
63                 Collection<V>? col = _storage_map.get (key);
64                 return col != null ? col.read_only_view : Set.empty<V> ();
65         }
66
67         public new void set (K key, V value) {
68                 if (_storage_map.has_key (key)) {
69                         if (_storage_map.get (key).add (value)) {
70                                 _nitems++;
71                         }
72                 } else {
73                         var s = create_value_storage ();
74                         s.add (value);
75                         _storage_map.set (key, s);
76                         _nitems++;
77                 }
78         }
79
80         public bool remove (K key, V value) {
81                 if (_storage_map.has_key (key)) {
82                         var values = _storage_map.get (key);
83                         if (values.contains (value)) {
84                                 values.remove (value);
85                                 _nitems--;
86                                 if (values.size == 0) {
87                                         _storage_map.unset (key);
88                                 }
89                                 return true;
90                         }
91                 }
92                 return false;
93         }
94
95         public bool remove_all (K key) {
96                 if (_storage_map.has_key (key)) {
97                         int size = _storage_map.get (key).size;
98                         if (_storage_map.unset (key)) {
99                                 _nitems -= size;
100                                 return true;
101                         }
102                 }
103                 return false;
104         }
105
106         public void clear () {
107                 _storage_map.clear ();
108                 _nitems = 0;
109         }
110
111         public Gee.MapIterator<K, V> map_iterator () {
112                 return new MapIterator<K, V> (_storage_map.map_iterator ());
113         }
114
115         protected abstract Collection<V> create_value_storage ();
116
117         protected abstract MultiSet<K> create_multi_key_set ();
118
119         protected abstract EqualDataFunc<V> get_value_equal_func ();
120
121         private class AllKeys<K, V> : AbstractCollection<K>, MultiSet<K> {
122                 protected AbstractMultiMap<K, V> _multi_map;
123
124                 public AllKeys (AbstractMultiMap<K, V> multi_map) {
125                         _multi_map = multi_map;
126                 }
127
128                 public override Gee.Iterator<K> iterator () {
129                         return new KeyIterator<K, V> (_multi_map._storage_map.map_iterator ());
130                 }
131
132                 public override int size { get { return _multi_map.size; } }
133
134                 public override bool read_only { get { return true; } }
135
136                 public override bool contains (K key) {
137                         return _multi_map._storage_map.has_key (key);
138                 }
139
140                 public override bool add (K key) {
141                         assert_not_reached ();
142                 }
143
144                 public override  bool remove (K item) {
145                         assert_not_reached ();
146                 }
147
148                 public override void clear () {
149                         assert_not_reached ();
150                 }
151
152                 public int count (K item) {
153                         Collection<V>? collection = _multi_map._storage_map.get (item);
154                         return collection != null ? collection.size : 0;
155                 }
156         }
157
158         private class Values<K, V> : AbstractCollection<V> {
159                 protected AbstractMultiMap<K, V> _multi_map;
160
161                 public Values (AbstractMultiMap<K, V> multi_map) {
162                         _multi_map = multi_map;
163                 }
164
165                 public override Gee.Iterator<K> iterator () {
166                         return new ValueIterator<K, V> (_multi_map._storage_map.map_iterator ());
167                 }
168
169                 public override int size { get { return _multi_map.size; } }
170
171                 public override bool read_only { get { return true; } }
172
173                 public override bool contains (V value) {
174                         EqualDataFunc<V> func = _multi_map.get_value_equal_func ();
175                         foreach (var col in _multi_map._storage_map.values) {
176                                 if (col.contains (value)) {
177                                         return true;
178                                 }
179                         }
180                         return false;
181                 }
182
183                 public override bool add (K key) {
184                         assert_not_reached ();
185                 }
186
187                 public override  bool remove (K item) {
188                         assert_not_reached ();
189                 }
190
191                 public override void clear () {
192                         assert_not_reached ();
193                 }
194         }
195
196         private class MappingIterator<K, V> : Object {
197                 protected Gee.MapIterator<K, Collection<V>> outer;
198                 protected Iterator<V>? inner = null;
199
200                 public MappingIterator (Gee.MapIterator<K, Collection<V>>? outer) {
201                         this.outer = outer;
202                 }
203
204                 public bool next () {
205                         if (inner != null && inner.next ()) {
206                                 return true;
207                         } else if (outer.next ()) {
208                                 inner = outer.get_value ().iterator ();
209                                 assert (inner.next ());
210                                 return true;
211                         } else {
212                                 return false;
213                         }
214                 }
215
216                 public bool has_next () {
217                         return inner.has_next () || outer.has_next ();
218                 }
219
220                 public void remove () {
221                         assert_not_reached ();
222                 }
223
224                 public virtual bool read_only {
225                         get {
226                                 return true;
227                         }
228                 }
229
230                 public void unset () {
231                         inner.remove ();
232                         if (outer.get_value ().is_empty) {
233                                 outer.unset ();
234                         }
235                 }
236
237                 public bool valid {
238                         get {
239                                 return inner != null && inner.valid;
240                         }
241                 }
242         }
243
244         private class KeyIterator<K, V> : MappingIterator<K, V>, Traversable<K>, Iterator<K> {
245                 public KeyIterator (Gee.MapIterator<K, Collection<V>>? outer) {
246                         base (outer);
247                 }
248
249                 public new K get () {
250                         assert (valid);
251                         return outer.get_key ();
252                 }
253
254                 public void foreach (ForallFunc<K> f) {
255                         if (inner != null && outer.valid) {
256                                 K key = outer.get_key ();
257                                 inner.foreach ((v) => {f (key);});
258                                 outer.next ();
259                         }
260                         outer.foreach ((key, col) => {
261                                 col.foreach ((v) => {f (key);});
262                         });
263                 }
264         }
265
266         private class ValueIterator<K, V> : MappingIterator<K, V>, Traversable<V>, Iterator<V> {
267                 public ValueIterator (Gee.MapIterator<K, Collection<V>>? outer) {
268                         base (outer);
269                 }
270
271                 public new V get () {
272                         assert (valid);
273                         return inner.get ();
274                 }
275
276                 public void foreach (ForallFunc<V> f) {
277                         if (inner != null && outer.valid) {
278                                 inner.foreach (f);
279                                 outer.next ();
280                         }
281                         outer.foreach ((key, col) => {
282                                 col.foreach (f);
283                         });
284                 }
285         }
286
287         private class MapIterator<K, V> : MappingIterator<K, V>, Gee.MapIterator<K, V> {
288                 public MapIterator (Gee.MapIterator<K, Collection<V>>? outer) {
289                         base (outer);
290                 }
291
292                 public K get_key () {
293                         assert (valid);
294                         return outer.get_key ();
295                 }
296
297                 public V get_value () {
298                         assert (valid);
299                         return inner.get ();
300                 }
301
302                 public void set_value (V value) {
303                         assert_not_reached ();
304                 }
305
306                 public bool mutable { get { return false; } }
307         }
308
309         // Future-proofing
310         internal new virtual void reserved0() {}
311         internal new virtual void reserved1() {}
312         internal new virtual void reserved2() {}
313         internal new virtual void reserved3() {}
314         internal new virtual void reserved4() {}
315         internal new virtual void reserved5() {}
316         internal new virtual void reserved6() {}
317         internal new virtual void reserved7() {}
318         internal new virtual void reserved8() {}
319         internal new virtual void reserved9() {}
320 }