Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/eglib
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnome.org>2006-10-08 23:55:57 +0400
committerMiguel de Icaza <miguel@gnome.org>2006-10-08 23:55:57 +0400
commit14e86051328309eef455802b4791a6cf7c59b076 (patch)
tree492f3c41221b944655c88e98dcd4b8fad9c5757f /eglib
parentdbb47ba9a4ee2f290aa17493244dc57b2ac91fb1 (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/ChangeLog7
-rw-r--r--eglib/src/ghashtable.c105
-rw-r--r--eglib/src/glib.h17
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