diff options
author | Miguel de Icaza <miguel@gnome.org> | 2006-10-08 23:55:57 +0400 |
---|---|---|
committer | Miguel de Icaza <miguel@gnome.org> | 2006-10-08 23:55:57 +0400 |
commit | 14e86051328309eef455802b4791a6cf7c59b076 (patch) | |
tree | 492f3c41221b944655c88e98dcd4b8fad9c5757f /eglib | |
parent | dbb47ba9a4ee2f290aa17493244dc57b2ac91fb1 (diff) |
2006-10-08 Miguel de Icaza <miguel@novell.com>
* src/ghashtable.c (g_hash_table_new_alloc,
g_hash_table_new_full_alloc): Add new entry points that will be
used for GC-aware hashtables.
svn path=/trunk/mono/; revision=66421
Diffstat (limited to 'eglib')
-rw-r--r-- | eglib/ChangeLog | 7 | ||||
-rw-r--r-- | eglib/src/ghashtable.c | 105 | ||||
-rw-r--r-- | eglib/src/glib.h | 17 |
3 files changed, 103 insertions, 26 deletions
diff --git a/eglib/ChangeLog b/eglib/ChangeLog index 62e08c1e9e5..9ed5105a981 100644 --- a/eglib/ChangeLog +++ b/eglib/ChangeLog @@ -1,3 +1,9 @@ +2006-10-08 Miguel de Icaza <miguel@novell.com> + + * src/ghashtable.c (g_hash_table_new_alloc, + g_hash_table_new_full_alloc): Add new entry points that will be + used for GC-aware hashtables. + 2006-10-08 Gonzalo Paniagua Javier <gonzalo@ximian.com> * test/string-util.c: @@ -38,6 +44,7 @@ * str/glib.c (g_log_set_handler): empty. (g_printerr): empty. (GMemVTable): define, empty, ignored. + (G_USEC_PER_SEC) :-) * src/gunicode.c (g_convert): Add bytes_read, bytes_written support; Small fixes to avoid valgrind errors. diff --git a/eglib/src/ghashtable.c b/eglib/src/ghashtable.c index e675ba4708f..ce3374d3dd4 100644 --- a/eglib/src/ghashtable.c +++ b/eglib/src/ghashtable.c @@ -24,6 +24,19 @@ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * NOTES: + * + * In addition to supporting the standard g_hash_table behavior, + * this version adds support for providing a malloc/free set of + * routines, these by default are malloc and free, but with a GC, + * they could be GC_malloc and the free routine could be NULL. If + * the value for free is NULL, we set all the fields that we would + * have otherwise released to NULL, to assist the garbage collector. + * + * This is designed to support the GC-aware hashtable that Mono uses, + * and replaces mono-hash.c. To do this, a new constructor is introduced + * that contains the extra parameters. */ #include <stdio.h> #include <math.h> @@ -49,6 +62,8 @@ struct _GHashTable { int threshold; int last_rehash; GDestroyNotify value_destroy_func, key_destroy_func; + GMFree freefn; + GMAlloc allocfn; }; static int prime_tbl[] = { @@ -98,37 +113,56 @@ to_prime (int x) return calc_prime (x); } +#undef g_new0 +static void * +g_new0 (size_t t) +{ + return calloc (1, t); +} + GHashTable * g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func) { + return g_hash_table_new_full_alloc (hash_func, key_equal_func, NULL, NULL, g_new0, free); +} + +GHashTable * +g_hash_table_new_alloc (GHashFunc hash_func, GEqualFunc key_equal_func, GMAlloc allocfn, GMFree freefn) +{ + return g_hash_table_new_full_alloc (hash_func, key_equal_func, NULL, NULL, allocfn, freefn); +} + + +GHashTable * +g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, + GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func) +{ + return g_hash_table_new_full_alloc (hash_func, key_equal_func, key_destroy_func, value_destroy_func, g_new0, free); +} + +GHashTable * +g_hash_table_new_full_alloc (GHashFunc hash_func, GEqualFunc key_equal_func, + GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func, + GMAlloc allocfn, GMFree freefn) +{ GHashTable *hash; if (hash_func == NULL) hash_func = g_direct_hash; if (key_equal_func == NULL) key_equal_func = g_direct_equal; - hash = g_new0 (GHashTable, 1); + + hash = (*allocfn) (sizeof (GHashTable)); hash->hash_func = hash_func; hash->key_equal_func = key_equal_func; - - hash->table_size = to_prime (1); - hash->table = g_new0 (Slot *, hash->table_size); - hash->last_rehash = hash->table_size; - - return hash; -} - -GHashTable * -g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, - GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func) -{ - GHashTable *hash = g_hash_table_new (hash_func, key_equal_func); - if (hash == NULL) - return NULL; - hash->key_destroy_func = key_destroy_func; hash->value_destroy_func = value_destroy_func; + hash->table_size = to_prime (1); + hash->table = (*allocfn) (sizeof (Slot *) * hash->table_size); + hash->last_rehash = hash->table_size; + hash->freefn = freefn; + hash->allocfn = allocfn; return hash; } @@ -145,7 +179,7 @@ do_rehash (GHashTable *hash) hash->table_size = to_prime (hash->in_use); /* printf ("New size: %d\n", hash->table_size); */ table = hash->table; - hash->table = g_new0 (Slot *, hash->table_size); + hash->table = (*hash->allocfn)(sizeof (Slot *) * hash->table_size); for (i = 0; i < current_size; i++){ Slot *s, *next; @@ -158,7 +192,7 @@ do_rehash (GHashTable *hash) hash->table [hashcode] = s; } } - g_free (table); + (*hash->freefn)(table); } void @@ -201,7 +235,7 @@ g_hash_table_insert_replace (GHashTable *hash, gpointer key, gpointer value, gbo return; } } - s = g_new (Slot, 1); + s = (*hash->allocfn) (sizeof (Slot)); s->key = key; s->value = value; s->next = hash->table [hashcode]; @@ -306,7 +340,12 @@ g_hash_table_remove (GHashTable *hash, gconstpointer key) hash->table [hashcode] = s->next; else last->next = s->next; - g_free (s); + if (hash->freefn) + (*hash->freefn) (s); + else { + s->key = NULL; + s->value = NULL; + } hash->in_use--; return TRUE; } @@ -343,7 +382,13 @@ g_hash_table_foreach_remove (GHashTable *hash, GHRFunc func, gpointer user_data) last->next = s->next; n = last->next; } - g_free (s); + if (hash->freefn) + (*hash->freefn)(s); + else { + s->key = NULL; + s->value = NULL; + } + hash->in_use--; count++; s = n; @@ -375,12 +420,20 @@ g_hash_table_destroy (GHashTable *hash) (*hash->key_destroy_func)(s->key); if (hash->value_destroy_func != NULL) (*hash->value_destroy_func)(s->value); - g_free (s); + if (hash->freefn) + (*hash->freefn)(s); + else { + s->key = NULL; + s->value = NULL; + } } } - g_free (hash->table); - - g_free (hash); + if (hash->freefn){ + (*hash->freefn) (hash->table); + (*hash->freefn) (hash); + } else { + hash->table = NULL; + } } gboolean diff --git a/eglib/src/glib.h b/eglib/src/glib.h index 54879979102..b64f945ff11 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -1,6 +1,9 @@ #ifndef __GLIB_H #define __GLIB_H +/* Define to detect that we are being built with eglib */ +#define __EGLIB_X11 1 + #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -117,6 +120,9 @@ typedef void (*GDestroyNotify) (gpointer data); typedef guint (*GHashFunc) (gconstpointer key); typedef gboolean (*GEqualFunc) (gconstpointer a, gconstpointer b); +typedef void (*GMFree) (void *ptr); +typedef void *(*GMAlloc) (size_t size); + GHashTable *g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func); GHashTable *g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func); @@ -688,5 +694,16 @@ gchar *g_convert (const gchar *str, gssize len, gsize *bytes_read, gsize *bytes_written, GError **error); gboolean g_utf8_validate (const gchar *str, gssize max_len, const gchar **end); +/* + * Eglib-only routines: + * + * These are extensions, not found on regular glib. + */ +GHashTable *g_hash_table_new_alloc (GHashFunc hash_func, GEqualFunc key_equal_func, + GMAlloc allocfn, GMFree freefn); +GHashTable *g_hash_table_new_full_alloc (GHashFunc hash_func, GEqualFunc key_equal_func, + GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func, + GMAlloc allocfn, GMFree freefn); + #endif |