This is Josh, commiting as Manish. This is completely new, and
authorManish Singh <yosh@src.gnome.org>
Sun, 20 Sep 1998 09:43:11 +0000 (09:43 +0000)
committerManish Singh <yosh@src.gnome.org>
Sun, 20 Sep 1998 09:43:11 +0000 (09:43 +0000)
nothing will break.

* glib.h: New function g_hash_table_foreach_remove is similar to
  g_hash_table_foreach, but the callback's return value indicates
  whether to remove the element (if TRUE) or not (if FALSE).

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
ghash.c
glib.h
glib/ghash.c
glib/glib.h
testglib.c
tests/testglib.c

index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
index 1b52cf1e2b013508547ea1ace72401c76fa16ed0..c39be1ef10978027c652ca6d1a03d57c0469737c 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 20 02:09:44 1998  Josh MacDonald  <jmacd@axis.hip.berkeley.edu>
+
+       * glib.h: New function g_hash_table_foreach_remove is similar to
+       g_hash_table_foreach, but the callback's return value indicates
+       whether to remove the element (if TRUE) or not (if FALSE).  
+       Returns the number of elements deleted.
+
 Fri Sep 18 11:31:50 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * glib.h
diff --git a/ghash.c b/ghash.c
index b2c3838dd10404af7505285ac1640ef1919e6fcc..065f889562da79e7fb9f21bd6ec213fe7387e959 100644 (file)
--- a/ghash.c
+++ b/ghash.c
@@ -194,6 +194,52 @@ g_hash_table_thaw (GHashTable *hash_table)
   g_hash_table_resize (hash_table);
 }
 
+gint
+g_hash_table_foreach_remove    (GHashTable     *hash_table,
+                                GHRFunc         func,
+                                gpointer        user_data)
+{
+  gint deleted = 0, i;
+  GHashNode *node, *prev;
+
+  g_return_val_if_fail (hash_table && func, -1);
+
+  for (i = 0; i < hash_table->size; i++)
+    {
+    restart:
+
+      prev = NULL;
+
+      for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
+       {
+         if ((* func) (node->key, node->value, user_data))
+           {
+             deleted += 1;
+
+             hash_table->nnodes -= 1;
+
+             if (prev)
+               {
+                 prev->next = node->next;
+                 g_hash_node_destroy (node);
+                 node = prev;
+               }
+             else
+               {
+                 hash_table->nodes[i] = node->next;
+                 g_hash_node_destroy (node);
+                 goto restart;
+               }
+           }
+       }
+    }
+
+  if (! hash_table->frozen)
+    g_hash_table_resize (hash_table);
+
+  return deleted;
+}
+
 void
 g_hash_table_foreach (GHashTable *hash_table,
                      GHFunc      func,
diff --git a/glib.h b/glib.h
index c52179ed4fa3fa3ff503aeaae541b4b82a365b7d..6b199cbbcff1e96e2844aec034bfbd8a41a32ba1 100644 (file)
--- a/glib.h
+++ b/glib.h
@@ -659,6 +659,9 @@ typedef guint               (*GHashFunc)            (gconstpointer  key);
 typedef void           (*GHFunc)               (gpointer       key,
                                                 gpointer       value,
                                                 gpointer       user_data);
+typedef gboolean       (*GHRFunc)              (gpointer       key,
+                                                gpointer       value,
+                                                gpointer       user_data);
 typedef void           (*GLogFunc)             (const gchar   *log_domain,
                                                 GLogLevelFlags log_level,
                                                 const gchar   *message,
@@ -851,6 +854,9 @@ void            g_hash_table_thaw           (GHashTable     *hash_table);
 void       g_hash_table_foreach        (GHashTable     *hash_table,
                                         GHFunc          func,
                                         gpointer        user_data);
+gint       g_hash_table_foreach_remove (GHashTable     *hash_table,
+                                        GHRFunc         func,
+                                        gpointer        user_data);
 gint       g_hash_table_size           (GHashTable     *hash_table);
 
 
index b2c3838dd10404af7505285ac1640ef1919e6fcc..065f889562da79e7fb9f21bd6ec213fe7387e959 100644 (file)
@@ -194,6 +194,52 @@ g_hash_table_thaw (GHashTable *hash_table)
   g_hash_table_resize (hash_table);
 }
 
+gint
+g_hash_table_foreach_remove    (GHashTable     *hash_table,
+                                GHRFunc         func,
+                                gpointer        user_data)
+{
+  gint deleted = 0, i;
+  GHashNode *node, *prev;
+
+  g_return_val_if_fail (hash_table && func, -1);
+
+  for (i = 0; i < hash_table->size; i++)
+    {
+    restart:
+
+      prev = NULL;
+
+      for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
+       {
+         if ((* func) (node->key, node->value, user_data))
+           {
+             deleted += 1;
+
+             hash_table->nnodes -= 1;
+
+             if (prev)
+               {
+                 prev->next = node->next;
+                 g_hash_node_destroy (node);
+                 node = prev;
+               }
+             else
+               {
+                 hash_table->nodes[i] = node->next;
+                 g_hash_node_destroy (node);
+                 goto restart;
+               }
+           }
+       }
+    }
+
+  if (! hash_table->frozen)
+    g_hash_table_resize (hash_table);
+
+  return deleted;
+}
+
 void
 g_hash_table_foreach (GHashTable *hash_table,
                      GHFunc      func,
index c52179ed4fa3fa3ff503aeaae541b4b82a365b7d..6b199cbbcff1e96e2844aec034bfbd8a41a32ba1 100644 (file)
@@ -659,6 +659,9 @@ typedef guint               (*GHashFunc)            (gconstpointer  key);
 typedef void           (*GHFunc)               (gpointer       key,
                                                 gpointer       value,
                                                 gpointer       user_data);
+typedef gboolean       (*GHRFunc)              (gpointer       key,
+                                                gpointer       value,
+                                                gpointer       user_data);
 typedef void           (*GLogFunc)             (const gchar   *log_domain,
                                                 GLogLevelFlags log_level,
                                                 const gchar   *message,
@@ -851,6 +854,9 @@ void            g_hash_table_thaw           (GHashTable     *hash_table);
 void       g_hash_table_foreach        (GHashTable     *hash_table,
                                         GHFunc          func,
                                         gpointer        user_data);
+gint       g_hash_table_foreach_remove (GHashTable     *hash_table,
+                                        GHRFunc         func,
+                                        gpointer        user_data);
 gint       g_hash_table_size           (GHashTable     *hash_table);
 
 
index d0440224d581a354b17665cf795bdd85edf7c844..1dd6efa80b303df7f881971254e37b94891a45b3 100644 (file)
@@ -177,6 +177,30 @@ g_node_test (void)
     g_print ("ok\n");
 }
 
+gboolean
+my_hash_callback_remove (gpointer key,
+                        gpointer value,
+                        gpointer user_data)
+{
+  int *d = value;
+
+  if ((*d) % 2)
+    return TRUE;
+
+  return FALSE;
+}
+
+void
+my_hash_callback_remove_test (gpointer key,
+                             gpointer value,
+                             gpointer user_data)
+{
+  int *d = value;
+
+  if ((*d) % 2)
+    g_print ("bad!\n");
+}
+
 void
 my_hash_callback (gpointer key,
                  gpointer value,
@@ -522,6 +546,19 @@ main (int   argc,
   for (i = 0; i < 10000; i++)
     g_hash_table_remove (hash_table, &array[i]);
 
+  for (i = 0; i < 10000; i++)
+    {
+      array[i] = i;
+      g_hash_table_insert (hash_table, &array[i], &array[i]);
+    }
+
+  if (g_hash_table_foreach_remove (hash_table, my_hash_callback_remove, NULL) != 5000 ||
+      g_hash_table_size (hash_table) != 5000)
+    g_print ("bad!\n");
+
+  g_hash_table_foreach (hash_table, my_hash_callback_remove_test, NULL);
+
+
   g_hash_table_destroy (hash_table);
 
   g_print ("ok\n");
index d0440224d581a354b17665cf795bdd85edf7c844..1dd6efa80b303df7f881971254e37b94891a45b3 100644 (file)
@@ -177,6 +177,30 @@ g_node_test (void)
     g_print ("ok\n");
 }
 
+gboolean
+my_hash_callback_remove (gpointer key,
+                        gpointer value,
+                        gpointer user_data)
+{
+  int *d = value;
+
+  if ((*d) % 2)
+    return TRUE;
+
+  return FALSE;
+}
+
+void
+my_hash_callback_remove_test (gpointer key,
+                             gpointer value,
+                             gpointer user_data)
+{
+  int *d = value;
+
+  if ((*d) % 2)
+    g_print ("bad!\n");
+}
+
 void
 my_hash_callback (gpointer key,
                  gpointer value,
@@ -522,6 +546,19 @@ main (int   argc,
   for (i = 0; i < 10000; i++)
     g_hash_table_remove (hash_table, &array[i]);
 
+  for (i = 0; i < 10000; i++)
+    {
+      array[i] = i;
+      g_hash_table_insert (hash_table, &array[i], &array[i]);
+    }
+
+  if (g_hash_table_foreach_remove (hash_table, my_hash_callback_remove, NULL) != 5000 ||
+      g_hash_table_size (hash_table) != 5000)
+    g_print ("bad!\n");
+
+  g_hash_table_foreach (hash_table, my_hash_callback_remove_test, NULL);
+
+
   g_hash_table_destroy (hash_table);
 
   g_print ("ok\n");