[libgee] Enhanced Map removal to optionally retrieve removed value



commit e21b74622efb59f5e7bbafb8bbb09ea8af1e8931
Author: Didier 'Ptitjes <ptitjes free fr>
Date:   Wed Aug 5 10:26:07 2009 +0200

    Enhanced Map removal to optionally retrieve removed value
    
    Fixes bug 587134.

 gee/abstractmap.vala   |    2 +-
 gee/hashmap.vala       |    6 +++++-
 gee/map.vala           |    5 +++--
 gee/readonlymap.vala   |    2 +-
 gee/treemap.vala       |   18 +++++++++++++-----
 tests/testhashmap.vala |    7 +++++--
 tests/testtreemap.vala |    7 +++++--
 7 files changed, 33 insertions(+), 14 deletions(-)
---
diff --git a/gee/abstractmap.vala b/gee/abstractmap.vala
index fb17b2a..5676a34 100644
--- a/gee/abstractmap.vala
+++ b/gee/abstractmap.vala
@@ -42,7 +42,7 @@ public abstract class Gee.AbstractMap<K,V> : Object, Map<K,V> {
 
 	public abstract new void set (K key, V value);
 
-	public abstract bool remove (K key);
+	public abstract bool remove (K key, out V? value = null);
 
 	public abstract void clear ();
 
diff --git a/gee/hashmap.vala b/gee/hashmap.vala
index 8e48328..d469743 100644
--- a/gee/hashmap.vala
+++ b/gee/hashmap.vala
@@ -103,11 +103,15 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
 		_stamp++;
 	}
 
-	public override bool remove (K key) {
+	public override bool remove (K key, out V? value = null) {
 		Node<K,V>** node = lookup_node (key);
 		if (*node != null) {
 			Node<K,V> next = (owned) (*node)->next;
 
+			if (&value != null) {
+				value = (owned) (*node)->value;
+			}
+
 			(*node)->key = null;
 			(*node)->value = null;
 			delete *node;
diff --git a/gee/map.vala b/gee/map.vala
index 9d6996e..f4a1983 100644
--- a/gee/map.vala
+++ b/gee/map.vala
@@ -78,11 +78,12 @@ public interface Gee.Map<K,V> : GLib.Object {
 	/**
 	 * Removes the specified key from this map.
 	 *
-	 * @param key the key to remove from the map
+	 * @param key   the key to remove from the map
+	 * @param value the receiver variable for the removed value
 	 *
 	 * @return    true if the map has been changed, false otherwise
 	 */
-	public abstract bool remove (K key);
+	public abstract bool remove (K key, out V? value = null);
 
 	/**
 	 * Removes all items from this collection. Must not be called on
diff --git a/gee/readonlymap.vala b/gee/readonlymap.vala
index 37d7730..e38fb01 100644
--- a/gee/readonlymap.vala
+++ b/gee/readonlymap.vala
@@ -80,7 +80,7 @@ public class Gee.ReadOnlyMap<K,V> : Object, Map<K,V> {
 		assert_not_reached ();
 	}
 
-	public bool remove (K key) {
+	public bool remove (K key, out V? value = null) {
 		assert_not_reached ();
 	}
 
diff --git a/gee/treemap.vala b/gee/treemap.vala
index a9c1806..d816854 100644
--- a/gee/treemap.vala
+++ b/gee/treemap.vala
@@ -169,7 +169,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> {
 		fix_up (ref node);
 	}
 
-	private bool remove_from_node (ref Node<K, V>? node, K key) {
+	private bool remove_from_node (ref Node<K, V>? node, K key, out V value) {
 		if (node == null) {
 			return false;
 		} else if (key_compare_func (key, node.key) < 0) {
@@ -180,7 +180,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> {
 			if (is_black (left) && is_black (left.left)) {
 				move_red_left (ref node);
 			}
-			bool r = remove_from_node (ref node.left, key);
+			bool r = remove_from_node (ref node.left, key, out value);
 			fix_up (ref node);
 			return r;
 		} else {
@@ -190,6 +190,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> {
 	
 			weak Node<K,V> r = node.right;
 			if (key_compare_func (key, node.key) == 0 && r == null) {
+				value = (owned) node.value;
 				node = null;
 				_size--;
 				return true;
@@ -198,12 +199,13 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> {
 				move_red_right (ref node);
 			}
 			if (key_compare_func (key, node.key) == 0) {
+				value = (owned) node.value;
 				remove_minimal (ref node.right, out node.key, out node.value);
 				fix_up (ref node);
 				_size--;
 				return true;
 			} else {
-				bool re = remove_from_node (ref node.right, key);
+				bool re = remove_from_node (ref node.right, key, out value);
 				fix_up (ref node);
 				return re;
 			}
@@ -219,8 +221,14 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> {
 		}
 	}
 
-	public override bool remove (K key) {
-		bool b = remove_from_node (ref root, key);
+	public override bool remove (K key, out V? value = null) {
+		V node_value;
+		bool b = remove_from_node (ref root, key, out node_value);
+
+		if (&value != null) {
+			value = (owned) node_value;
+		}
+
 		if (root != null) {
 			root.color = Node.Color.BLACK;
 		}
diff --git a/tests/testhashmap.vala b/tests/testhashmap.vala
index 731d931..14871f9 100644
--- a/tests/testhashmap.vala
+++ b/tests/testhashmap.vala
@@ -76,6 +76,7 @@ void test_hashmap_set () {
 
 void test_hashmap_remove () {
 	var hashmap = new HashMap<string,string> (str_hash, str_equal, str_equal);
+	string? value;
 	
 	// check removing when map is empty
 	hashmap.remove ("foo");
@@ -93,15 +94,17 @@ void test_hashmap_remove () {
 	assert (hashmap.size == 3);
 	
 	// check remove in between 
-	hashmap.remove ("ccc");
+	hashmap.remove ("ccc", out value);
 	assert (hashmap.size == 2);
+	assert (value == "333");
 	
 	// check remove in last place
 	hashmap.remove ("ddd");
 	assert (hashmap.size == 1);
 	
 	// check remove invalid key
-	hashmap.remove ("bar");
+	hashmap.remove ("bar", out value);
+	assert (value == null);
 	
 	// check remove last in map
 	hashmap.remove ("bbb");
diff --git a/tests/testtreemap.vala b/tests/testtreemap.vala
index b92f3ef..df32f72 100644
--- a/tests/testtreemap.vala
+++ b/tests/testtreemap.vala
@@ -75,6 +75,7 @@ void test_treemap_set () {
 
 void test_treemap_remove () {
 	var treemap = new TreeMap<string,string> ((CompareFunc) strcmp, str_equal);
+	string? value;
 
 	// check removing when map is empty
 	treemap.remove ("foo");
@@ -92,15 +93,17 @@ void test_treemap_remove () {
 	assert (treemap.size == 3);
 
 	// check remove in between 
-	treemap.remove ("ccc");
+	treemap.remove ("ccc", out value);
 	assert (treemap.size == 2);
+	assert (value == "333");
 
 	// check remove in last place
 	treemap.remove ("ddd");
 	assert (treemap.size == 1);
 
 	// check remove invalid key
-	treemap.remove ("bar");
+	treemap.remove ("bar", out value);
+	assert (value == null);
 
 	// check remove last in map
 	treemap.remove ("bbb");



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