Author: chromatic
Date: Fri Nov 28 22:14:40 2008
New Revision: 33323

Modified:
   trunk/include/parrot/hash.h
   trunk/src/hash.c

Log:
[src] Added parrot_chash_destroy_values() function, which takes a callback
which knows how to destroy C-level values in a hash.  This is important to IMCC
at least (see r33324).

Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h (original)
+++ trunk/include/parrot/hash.h Fri Nov 28 22:14:40 2008
@@ -71,6 +71,8 @@
     hash_hash_key_fn hash_val;  /* generate a hash value for key */
 };
 
+typedef void (*value_free)(void *);
+
 /* HEADERIZER BEGIN: src/hash.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will 
be lost. */
 
@@ -214,6 +216,13 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*hash);
 
+void parrot_chash_destroy_values(PARROT_INTERP, ARGMOD(Hash *hash),
+    ARGIN(value_free func))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*hash);
+
 void parrot_new_hash_x(
     ARGOUT(Hash **hptr),
     PARROT_DATA_TYPE val_type,

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c    (original)
+++ trunk/src/hash.c    Fri Nov 28 22:14:40 2008
@@ -898,6 +898,39 @@
     parrot_hash_destroy(interp, hash);
 }
 
+
+/*
+
+=item C<void parrot_chash_destroy_values>
+
+Delete the specified hash by freeing the memory allocated to all the key-value
+pairs, calling the provided callback to free the values, and finally the hash
+itself.
+
+The callback returns C<void> and takes a C<void *>.
+
+=cut
+
+*/
+
+void
+parrot_chash_destroy_values(PARROT_INTERP, ARGMOD(Hash *hash),
+    ARGIN(value_free func))
+{
+    UINTVAL i;
+
+    for (i = 0; i <= hash->mask; i++) {
+        HashBucket *bucket = hash->bi[i];
+        while (bucket) {
+            mem_sys_free(bucket->key);
+            func(bucket->value);
+            bucket = bucket->next;
+        }
+    }
+
+    parrot_hash_destroy(interp, hash);
+}
+
 /*
 
 =item C<void parrot_new_hash_x>

Reply via email to