[libgee] Extract AbstractMultiMap from HashMultiMap



commit f55b31c5453acf84a2c68081706e38021ff2d698
Author: Didier 'Ptitjes <ptitjes free fr>
Date:   Mon Sep 28 13:07:44 2009 +0200

    Extract AbstractMultiMap from HashMultiMap

 gee/Makefile.am           |    1 +
 gee/abstractmultimap.vala |  129 +++++++++++++++++++++++++++++++++++++++++++++
 gee/hashmultimap.vala     |  107 +++++--------------------------------
 3 files changed, 143 insertions(+), 94 deletions(-)
---
diff --git a/gee/Makefile.am b/gee/Makefile.am
index 74adec8..e6294f7 100644
--- a/gee/Makefile.am
+++ b/gee/Makefile.am
@@ -17,6 +17,7 @@ libgee_la_VALASOURCES = \
 	abstractcollection.vala \
 	abstractlist.vala \
 	abstractmap.vala \
+	abstractmultimap.vala \
 	abstractmultiset.vala \
 	abstractqueue.vala \
 	abstractset.vala \
diff --git a/gee/abstractmultimap.vala b/gee/abstractmultimap.vala
new file mode 100644
index 0000000..4020f43
--- /dev/null
+++ b/gee/abstractmultimap.vala
@@ -0,0 +1,129 @@
+/* abstractmultimap.vala
+ *
+ * Copyright (C) 2009  Ali Sabil
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	Ali Sabil <ali sabil gmail com>
+ * 	Didier 'Ptitjes Villevalois <ptitjes free fr>
+ */
+
+/**
+ * Skeletal implementation of the { link MultiMap} interface.
+ *
+ * @see HashMultiMap
+ * @see TreeMultiMap
+ */
+public abstract class Gee.AbstractMultiMap<K,V> : GLib.Object, MultiMap<K,V> {
+	public int size {
+		get { return _nitems; }
+	}
+
+	protected Map<K, Collection<V>> _storage_map;
+	private int _nitems = 0;
+	private Set<V> _empty_value_set;
+
+	public AbstractMultiMap (Map<K, Collection<V>> storage_map) {
+		this._storage_map = storage_map;
+		this._empty_value_set = Set.empty<V> ();
+	}
+
+	protected abstract Collection<V> create_value_storage ();
+
+	protected abstract MultiSet<K> create_multi_key_set ();
+
+	protected abstract EqualFunc get_value_equal_func ();
+
+	public Set<K> get_keys () {
+		return _storage_map.keys;
+	}
+
+	public MultiSet<K> get_all_keys () {
+		MultiSet<K> result = create_multi_key_set ();
+		foreach (var entry in _storage_map.entries) {
+			for (int i = 0; i < entry.value.size; i++) {
+				result.add (entry.key);
+			}
+		}
+		return result;
+	}
+
+	public Collection<V> get_values () {
+		var result = new ArrayList<V> (get_value_equal_func ());
+		foreach (var entry in _storage_map.entries) {
+			foreach (var value in entry.value) {
+				result.add (value);
+			}
+		}
+		return result;
+	}
+
+	public bool contains (K key) {
+		return _storage_map.contains (key);
+	}
+
+	public new Collection<V> get (K key) {
+		if (_storage_map.contains (key)) {
+			return _storage_map.get (key).read_only_view;
+		} else {
+			return _empty_value_set;
+		}
+	}
+
+	public new void set (K key, V value) {
+		if (_storage_map.contains (key)) {
+			if (_storage_map.get (key).add (value)) {
+				_nitems++;
+			}
+		} else {
+			var s = create_value_storage ();
+			s.add (value);
+			_storage_map.set (key, s);
+			_nitems++;
+		}
+	}
+
+	public bool remove (K key, V value) {
+		if (_storage_map.contains (key)) {
+			var values = _storage_map.get (key);
+			if (values.contains (value)) {
+				values.remove (value);
+				_nitems--;
+				if (values.size == 0) {
+					_storage_map.remove (key);
+				}
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public bool remove_all (K key) {
+		if (_storage_map.contains (key)) {
+			int size = _storage_map.get (key).size;
+			if (_storage_map.remove (key)) {
+				_nitems -= size;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public void clear () {
+		_storage_map.clear ();
+		_nitems = 0;
+	}
+}
diff --git a/gee/hashmultimap.vala b/gee/hashmultimap.vala
index 3e4258a..0961d19 100644
--- a/gee/hashmultimap.vala
+++ b/gee/hashmultimap.vala
@@ -23,121 +23,40 @@
 /**
  * Hash table implementation of the { link MultiMap} interface.
  */
-public class Gee.HashMultiMap<K,V> : GLib.Object, MultiMap<K,V> {
-	public int size {
-		get { return _nitems; }
+public class Gee.HashMultiMap<K,V> : AbstractMultiMap<K,V> {
+	public HashFunc key_hash_func {
+		get { return ((HashMap<K, Set<V>>) _storage_map).key_hash_func; }
 	}
 
-	public HashFunc key_hash_func { private set; get; }
-
-	public EqualFunc key_equal_func { private set; get; }
+	public EqualFunc key_equal_func {
+		get { return ((HashMap<K, Set<V>>) _storage_map).key_equal_func; }
+	}
 
 	public HashFunc value_hash_func { private set; get; }
 
 	public EqualFunc value_equal_func { private set; get; }
 
-	private Map<K, Collection<V>> _items;
-	private int _nitems = 0;
-	private Set<V> _empty_value_set;
-
 	public HashMultiMap (HashFunc? key_hash_func = null, EqualFunc? key_equal_func = null, HashFunc? value_hash_func = null, EqualFunc? value_equal_func = null) {
-		if (key_hash_func == null) {
-			key_hash_func = Functions.get_hash_func_for (typeof (K));
-		}
-		if (key_equal_func == null) {
-			key_equal_func = Functions.get_equal_func_for (typeof (K));
-		}
+		base (new HashMap<K, Set<V>> (key_hash_func, key_equal_func, direct_equal));
 		if (value_hash_func == null) {
 			value_hash_func = Functions.get_hash_func_for (typeof (V));
 		}
 		if (value_equal_func == null) {
 			value_equal_func = Functions.get_equal_func_for (typeof (V));
 		}
-		this.key_hash_func = key_hash_func;
-		this.key_equal_func = key_equal_func;
 		this.value_hash_func = value_hash_func;
 		this.value_equal_func = value_equal_func;
-		this._items = new HashMap<K, Set<V>> (key_hash_func, key_equal_func, direct_equal);
-		this._empty_value_set = new ReadOnlySet<V> (new HashSet<V> (_value_hash_func, _value_equal_func));
-	}
-
-	public Set<K> get_keys () {
-		return _items.keys;
-	}
-
-	public MultiSet<K> get_all_keys () {
-		MultiSet<K> result = new HashMultiSet<K> (_key_hash_func, _key_equal_func);
-		foreach (var entry in _items.entries) {
-			for (int i = 0; i < entry.value.size; i++) {
-				result.add (entry.key);
-			}
-		}
-		return result;
 	}
 
-	public Collection<V> get_values () {
-		var result = new ArrayList<V> (_value_equal_func);
-		foreach (var entry in _items.entries) {
-			foreach (var value in entry.value) {
-				result.add (value);
-			}
-		}
-		return result;
+	protected override Collection<V> create_value_storage () {
+		return new HashSet<V> (_value_hash_func, _value_equal_func);
 	}
 
-	public bool contains (K key) {
-		return _items.contains (key);
-	}
-
-	public new Collection<V> get (K key) {
-		if (_items.contains (key)) {
-			return new ReadOnlyCollection<V> (_items.get (key));
-		} else {
-			return _empty_value_set;
-		}
-	}
-
-	public new void set (K key, V value) {
-		if (_items.contains (key)) {
-			if (_items.get (key).add (value)) {
-				_nitems++;
-			}
-		} else {
-			var s = new HashSet<V> (_value_hash_func, _value_equal_func);
-			s.add (value);
-			_items.set (key, s);
-			_nitems++;
-		}
-	}
-
-	public bool remove (K key, V value) {
-		if (_items.contains (key)) {
-			var values = _items.get (key);
-			if (values.contains (value)) {
-				values.remove (value);
-				_nitems--;
-				if (values.size == 0) {
-					_items.remove (key);
-				}
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public bool remove_all (K key) {
-		if (_items.contains (key)) {
-			int size = _items.get (key).size;
-			if (_items.remove (key)) {
-				_nitems -= size;
-				return true;
-			}
-		}
-		return false;
+	protected override MultiSet<K> create_multi_key_set () {
+		return new HashMultiSet<K> (key_hash_func, key_equal_func);
 	}
 
-	public void clear () {
-		_items.clear ();
-		_nitems = 0;
+	protected override EqualFunc get_value_equal_func () {
+		return _value_equal_func;
 	}
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]