Make g_tree_remove() and g_tree_steal() return FALSE if the node is found but cannot...
authorDana Jansens <danakj@orodu.net>
Fri, 30 Oct 2009 22:24:32 +0000 (18:24 -0400)
committerDana Jansens <danakj@orodu.net>
Thu, 12 Nov 2009 21:54:05 +0000 (16:54 -0500)
This should help people from freeing things accidentally based on the return result.  Also, change comments for these functions to reflect their behaviour in a tree with multiple versions.

glib/gtree.c

index 77ee5fc62535afb45e5a7dfb83939c86da35ec4e..6dde6ccbae8e8a8f79baae07a47d96b981225e18 100644 (file)
@@ -804,10 +804,13 @@ g_tree_insert_internal (GTree    *tree,
  * If the #GTree was created using g_tree_new_full(), the key and value 
  * are freed using the supplied destroy functions, otherwise you have to 
  * make sure that any dynamically allocated values are freed yourself.
+ * Note that if the key existed in
+ * earlier versions of the tree (g_tree_next_version() has been called since
+ * it was inserted), then it cannot be removed from the tree. *
  * If the key does not exist in the #GTree, the function does nothing.
  *
- * Returns: %TRUE if the key was found (prior to 2.8, this function returned 
- *   nothing)
+ * Returns: %TRUE if the key was found and able to be removed
+ *   (prior to 2.8, this function returned nothing)
  **/
 gboolean
 g_tree_remove (GTree         *tree,
@@ -832,12 +835,13 @@ g_tree_remove (GTree         *tree,
  * @key: the key to remove.
  * 
  * Removes a key and its associated value from a #GTree without calling 
- * the key and value destroy functions.
- *
+ * the key and value destroy functions.  Note that if the key existed in
+ * earlier versions of the tree (g_tree_next_version() has been called since
+ * it was inserted), then it cannot be removed from the tree. *
  * If the key does not exist in the #GTree, the function does nothing.
  *
- * Returns: %TRUE if the key was found (prior to 2.8, this function returned 
- *    nothing)
+ * Returns: %TRUE if the key was found and able to be removed
+ *   (prior to 2.8, this function returned nothing)
  **/
 gboolean
 g_tree_steal (GTree         *tree,
@@ -976,6 +980,8 @@ g_tree_remove_internal (GTree         *tree,
         }
     }
 
+  tree->nnodes--;
+
   /* only really delete the node if it's in the current version, otherwise
      it needs to be remembered */
   if (node->nv == 1 && node->version(NOW) == tree->version)
@@ -993,11 +999,11 @@ g_tree_remove_internal (GTree         *tree,
                      (node->version(NOW) == 0 ? 1 : MAX_IN_DEGREE + 1),
                      node->v);
       g_slice_free (GTreeNode, node);
-    }
 
-  tree->nnodes--;
+      return TRUE;
+    }
 
-  return TRUE;
+  return FALSE;
 }
 
 /**