1 /* abstractmultimap.vala
3 * Copyright (C) 2009 Ali Sabil
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.
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.
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
20 * Ali Sabil <ali.sabil@gmail.com>
21 * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
25 * Skeletal implementation of the {@link MultiMap} interface.
30 public abstract class Gee.AbstractMultiMap<K,V> : Object, MultiMap<K,V> {
32 get { return _nitems; }
35 public bool read_only {
39 protected Map<K, Collection<V>> _storage_map;
40 private int _nitems = 0;
42 public AbstractMultiMap (Map<K, Collection<V>> storage_map) {
43 this._storage_map = storage_map;
46 public Set<K> get_keys () {
47 return _storage_map.keys;
50 public MultiSet<K> get_all_keys () {
51 return new AllKeys<K, V> (this);
54 public Collection<V> get_values () {
55 return new Values<K, V> (this);
58 public bool contains (K key) {
59 return _storage_map.has_key (key);
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> ();
67 public new void set (K key, V value) {
68 if (_storage_map.has_key (key)) {
69 if (_storage_map.get (key).add (value)) {
73 var s = create_value_storage ();
75 _storage_map.set (key, s);
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);
86 if (values.size == 0) {
87 _storage_map.unset (key);
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)) {
106 public void clear () {
107 _storage_map.clear ();
111 public Gee.MapIterator<K, V> map_iterator () {
112 return new MapIterator<K, V> (_storage_map.map_iterator ());
115 protected abstract Collection<V> create_value_storage ();
117 protected abstract MultiSet<K> create_multi_key_set ();
119 protected abstract EqualDataFunc<V> get_value_equal_func ();
121 private class AllKeys<K, V> : AbstractCollection<K>, MultiSet<K> {
122 protected AbstractMultiMap<K, V> _multi_map;
124 public AllKeys (AbstractMultiMap<K, V> multi_map) {
125 _multi_map = multi_map;
128 public override Gee.Iterator<K> iterator () {
129 return new KeyIterator<K, V> (_multi_map._storage_map.map_iterator ());
132 public override int size { get { return _multi_map.size; } }
134 public override bool read_only { get { return true; } }
136 public override bool contains (K key) {
137 return _multi_map._storage_map.has_key (key);
140 public override bool add (K key) {
141 assert_not_reached ();
144 public override bool remove (K item) {
145 assert_not_reached ();
148 public override void clear () {
149 assert_not_reached ();
152 public int count (K item) {
153 Collection<V>? collection = _multi_map._storage_map.get (item);
154 return collection != null ? collection.size : 0;
158 private class Values<K, V> : AbstractCollection<V> {
159 protected AbstractMultiMap<K, V> _multi_map;
161 public Values (AbstractMultiMap<K, V> multi_map) {
162 _multi_map = multi_map;
165 public override Gee.Iterator<K> iterator () {
166 return new ValueIterator<K, V> (_multi_map._storage_map.map_iterator ());
169 public override int size { get { return _multi_map.size; } }
171 public override bool read_only { get { return true; } }
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)) {
183 public override bool add (K key) {
184 assert_not_reached ();
187 public override bool remove (K item) {
188 assert_not_reached ();
191 public override void clear () {
192 assert_not_reached ();
196 private class MappingIterator<K, V> : Object {
197 protected Gee.MapIterator<K, Collection<V>> outer;
198 protected Iterator<V>? inner = null;
200 public MappingIterator (Gee.MapIterator<K, Collection<V>>? outer) {
204 public bool next () {
205 if (inner != null && inner.next ()) {
207 } else if (outer.next ()) {
208 inner = outer.get_value ().iterator ();
209 assert (inner.next ());
216 public bool has_next () {
217 return inner.has_next () || outer.has_next ();
220 public void remove () {
221 assert_not_reached ();
224 public virtual bool read_only {
230 public void unset () {
232 if (outer.get_value ().is_empty) {
239 return inner != null && inner.valid;
244 private class KeyIterator<K, V> : MappingIterator<K, V>, Traversable<K>, Iterator<K> {
245 public KeyIterator (Gee.MapIterator<K, Collection<V>>? outer) {
249 public new K get () {
251 return outer.get_key ();
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);});
260 outer.foreach ((key, col) => {
261 col.foreach ((v) => {f (key);});
266 private class ValueIterator<K, V> : MappingIterator<K, V>, Traversable<V>, Iterator<V> {
267 public ValueIterator (Gee.MapIterator<K, Collection<V>>? outer) {
271 public new V get () {
276 public void foreach (ForallFunc<V> f) {
277 if (inner != null && outer.valid) {
281 outer.foreach ((key, col) => {
287 private class MapIterator<K, V> : MappingIterator<K, V>, Gee.MapIterator<K, V> {
288 public MapIterator (Gee.MapIterator<K, Collection<V>>? outer) {
292 public K get_key () {
294 return outer.get_key ();
297 public V get_value () {
302 public void set_value (V value) {
303 assert_not_reached ();
306 public bool mutable { get { return false; } }
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() {}