removed the GListAllocator type and its g_*_allocator_*() function

Tue Nov 24 09:40:00 1998  Tim Janik  <timj@gtk.org>

        * glib.h: removed the GListAllocator type and its g_*_allocator_*()
        function variants (which weren't working anyways) in favour of a
        generic GAllocator type. new functions:
        g_allocator_new, g_allocator_free, g_slist_push_allocator,
        g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
        g_node_push_allocator and g_node_pop_allocator.

        * gstring.c: removed bogus slist allocator code.
        * gtree.c: maintain own list of free tree nodes and don't waste
        GSLists for that, removed bogus slist allocator code.
        * glist.c: use GAllocators for node allocation.
        * gslist.c: use GAllocators for node allocation.
        * gnode.c: use GAllocators for node allocation.

        * gdataset.c: cleanups wrt automatic initialization.
This commit is contained in:
Tim Janik 1998-11-24 12:18:22 +00:00 committed by Tim Janik
parent eabb208b30
commit 9c1692c260
24 changed files with 924 additions and 516 deletions

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -1,3 +1,21 @@
Tue Nov 24 09:40:00 1998 Tim Janik <timj@gtk.org>
* glib.h: removed the GListAllocator type and its g_*_allocator_*()
function variants (which weren't working anyways) in favour of a
generic GAllocator type. new functions:
g_allocator_new, g_allocator_free, g_slist_push_allocator,
g_slist_pop_allocator, g_list_push_allocator, g_list_pop_allocator,
g_node_push_allocator and g_node_pop_allocator.
* gstring.c: removed bogus slist allocator code.
* gtree.c: maintain own list of free tree nodes and don't waste
GSLists for that, removed bogus slist allocator code.
* glist.c: use GAllocators for node allocation.
* gslist.c: use GAllocators for node allocation.
* gnode.c: use GAllocators for node allocation.
* gdataset.c: cleanups wrt automatic initialization.
Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org> Mon Nov 23 10:03:58 1998 Owen Taylor <otaylor@gtk.org>
* glib.h garray.[ch]: added g_array_insert_vals() to * glib.h garray.[ch]: added g_array_insert_vals() to

View File

@ -57,19 +57,19 @@ static inline void g_data_set_internal (GData **datalist,
GDestroyNotify destroy_func, GDestroyNotify destroy_func,
GDataset *dataset); GDataset *dataset);
static void g_data_initialize (void); static void g_data_initialize (void);
static inline GQuark g_quark_new (const gchar *string); static inline GQuark g_quark_new (gchar *string);
/* --- variables --- */ /* --- variables --- */
static GHashTable *g_quark_ht = NULL;
static gchar **g_quarks = NULL;
static GQuark g_quark_seq_id = 0;
static GHashTable *g_dataset_location_ht = NULL; static GHashTable *g_dataset_location_ht = NULL;
static GDataset *g_dataset_cached = NULL; static GDataset *g_dataset_cached = NULL;
static GMemChunk *g_dataset_mem_chunk = NULL; static GMemChunk *g_dataset_mem_chunk = NULL;
static GMemChunk *g_data_mem_chunk = NULL; static GMemChunk *g_data_mem_chunk = NULL;
static GData *g_data_cache = NULL; static GData *g_data_cache = NULL;
static guint g_data_cache_length = 0; static guint g_data_cache_length = 0;
static GHashTable *g_quark_ht = NULL;
static gchar **g_quarks = NULL;
static GQuark g_quark_seq_id = 0;
/* --- functions --- */ /* --- functions --- */
@ -109,6 +109,9 @@ g_datalist_clear (GData **datalist)
{ {
g_return_if_fail (datalist != NULL); g_return_if_fail (datalist != NULL);
if (!g_dataset_location_ht)
g_data_initialize ();
while (*datalist) while (*datalist)
g_datalist_clear_i (datalist); g_datalist_clear_i (datalist);
} }
@ -174,9 +177,6 @@ g_data_set_internal (GData **datalist,
{ {
register GData *list; register GData *list;
if (!g_dataset_location_ht)
g_data_initialize ();
list = *datalist; list = *datalist;
if (!data) if (!data)
{ {
@ -201,7 +201,7 @@ g_data_set_internal (GData **datalist,
} }
/* the GData struct *must* already be unlinked /* the GData struct *must* already be unlinked
* when invoking the destroy function * when invoking the destroy function.
* we use (data==NULL && destroy_func!=NULL) as * we use (data==NULL && destroy_func!=NULL) as
* a special hint combination to "steal" * a special hint combination to "steal"
* data without destroy notification * data without destroy notification
@ -326,6 +326,9 @@ g_datalist_id_set_data_full (GData **datalist,
else else
return; return;
} }
if (!g_dataset_location_ht)
g_data_initialize ();
g_data_set_internal (datalist, key_id, data, destroy_func, NULL); g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
} }
@ -352,7 +355,7 @@ g_datalist_id_remove_no_notify (GData **datalist,
{ {
g_return_if_fail (datalist != NULL); g_return_if_fail (datalist != NULL);
if (key_id) if (key_id && g_dataset_location_ht)
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL); g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
} }
@ -407,14 +410,17 @@ g_dataset_foreach (gconstpointer dataset_location,
g_return_if_fail (dataset_location != NULL); g_return_if_fail (dataset_location != NULL);
g_return_if_fail (func != NULL); g_return_if_fail (func != NULL);
dataset = g_dataset_lookup (dataset_location); if (g_dataset_location_ht)
if (dataset)
{ {
register GData *list; dataset = g_dataset_lookup (dataset_location);
if (dataset)
for (list = dataset->datalist; list; list = list->next) {
func (list->id, list->data, user_data); register GData *list;
for (list = dataset->datalist; list; list = list->next)
func (list->id, list->data, user_data);
}
} }
} }
@ -443,22 +449,20 @@ g_datalist_init (GData **datalist)
static void static void
g_data_initialize (void) g_data_initialize (void)
{ {
if (!g_dataset_location_ht) g_return_if_fail (g_dataset_location_ht == NULL);
{
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal); g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL); g_dataset_cached = NULL;
g_dataset_cached = NULL; g_dataset_mem_chunk =
g_dataset_mem_chunk = g_mem_chunk_new ("GDataset MemChunk",
g_mem_chunk_new ("GDataset MemChunk", sizeof (GDataset),
sizeof (GDataset), sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC, G_ALLOC_AND_FREE);
G_ALLOC_AND_FREE); g_data_mem_chunk =
g_data_mem_chunk = g_mem_chunk_new ("GData MemChunk",
g_mem_chunk_new ("GData MemChunk", sizeof (GData),
sizeof (GData), sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC, G_ALLOC_AND_FREE);
G_ALLOC_AND_FREE);
}
} }
GQuark GQuark
@ -479,10 +483,14 @@ g_quark_from_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0); g_return_val_if_fail (string != NULL, 0);
if (!g_quark_ht) if (g_quark_ht)
g_data_initialize (); quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
else
{
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
quark = 0;
}
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
if (!quark) if (!quark)
quark = g_quark_new (g_strdup (string)); quark = g_quark_new (g_strdup (string));
@ -496,12 +504,16 @@ g_quark_from_static_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0); g_return_val_if_fail (string != NULL, 0);
if (!g_quark_ht) if (g_quark_ht)
g_data_initialize (); quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
else
quark = (gulong) g_hash_table_lookup (g_quark_ht, string); {
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
quark = 0;
}
if (!quark) if (!quark)
quark = g_quark_new (string); quark = g_quark_new ((gchar*) string);
return quark; return quark;
} }
@ -516,19 +528,17 @@ g_quark_to_string (GQuark quark)
} }
static inline GQuark static inline GQuark
g_quark_new (const gchar *string) g_quark_new (gchar *string)
{ {
GQuark quark; GQuark quark;
if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0) if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
g_quarks = g_realloc (g_quarks, g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
(g_quark_seq_id + G_QUARK_BLOCK_SIZE) * sizeof (gchar*));
g_quarks[g_quark_seq_id] = string;
g_quarks[g_quark_seq_id] = (gchar*) string;
g_quark_seq_id++; g_quark_seq_id++;
quark = g_quark_seq_id; quark = g_quark_seq_id;
g_hash_table_insert (g_quark_ht, (gchar*) string, GUINT_TO_POINTER (quark)); g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
return quark; return quark;
} }

26
glib.h
View File

@ -695,6 +695,7 @@ GUTILS_C_VAR const guint glib_binary_age;
/* Forward declarations of glib types. /* Forward declarations of glib types.
*/ */
typedef struct _GAllocator GAllocator;
typedef struct _GArray GArray; typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray; typedef struct _GByteArray GByteArray;
typedef struct _GCache GCache; typedef struct _GCache GCache;
@ -705,7 +706,6 @@ typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook; typedef struct _GHook GHook;
typedef struct _GHookList GHookList; typedef struct _GHookList GHookList;
typedef struct _GList GList; typedef struct _GList GList;
typedef struct _GListAllocator GListAllocator;
typedef struct _GMemChunk GMemChunk; typedef struct _GMemChunk GMemChunk;
typedef struct _GNode GNode; typedef struct _GNode GNode;
typedef struct _GPtrArray GPtrArray; typedef struct _GPtrArray GPtrArray;
@ -865,6 +865,8 @@ struct _GDebugKey
/* Doubly linked lists /* Doubly linked lists
*/ */
void g_list_push_allocator (GAllocator *allocator);
void g_list_pop_allocator (void);
GList* g_list_alloc (void); GList* g_list_alloc (void);
void g_list_free (GList *list); void g_list_free (GList *list);
void g_list_free_1 (GList *list); void g_list_free_1 (GList *list);
@ -913,6 +915,8 @@ gpointer g_list_nth_data (GList *list,
/* Singly linked lists /* Singly linked lists
*/ */
void g_slist_push_allocator (GAllocator *allocator);
void g_slist_pop_allocator (void);
GSList* g_slist_alloc (void); GSList* g_slist_alloc (void);
void g_slist_free (GSList *list); void g_slist_free (GSList *list);
void g_slist_free_1 (GSList *list); void g_slist_free_1 (GSList *list);
@ -957,14 +961,6 @@ gpointer g_slist_nth_data (GSList *list,
#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL) #define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
/* List Allocators
*/
GListAllocator* g_list_allocator_new (void);
void g_list_allocator_free (GListAllocator* allocator);
GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
GListAllocator* g_list_set_allocator (GListAllocator* allocator);
/* Hash tables /* Hash tables
*/ */
GHashTable* g_hash_table_new (GHashFunc hash_func, GHashTable* g_hash_table_new (GHashFunc hash_func,
@ -1053,6 +1049,8 @@ struct _GNode
((GNode*) (node))->next == NULL) ((GNode*) (node))->next == NULL)
#define G_NODE_IS_LEAF(node) (((GNode*) (node))->children == NULL) #define G_NODE_IS_LEAF(node) (((GNode*) (node))->children == NULL)
void g_node_push_allocator (GAllocator *allocator);
void g_node_pop_allocator (void);
GNode* g_node_new (gpointer data); GNode* g_node_new (gpointer data);
void g_node_destroy (GNode *root); void g_node_destroy (GNode *root);
void g_node_unlink (GNode *node); void g_node_unlink (GNode *node);
@ -1363,6 +1361,16 @@ void g_free (gpointer mem);
void g_mem_profile (void); void g_mem_profile (void);
void g_mem_check (gpointer mem); void g_mem_check (gpointer mem);
/* Generic allocators
*/
GAllocator* g_allocator_new (const gchar *name,
guint n_preallocs);
void g_allocator_free (GAllocator *allocator);
#define G_ALLOCATOR_LIST (1)
#define G_ALLOCATOR_SLIST (2)
#define G_ALLOCATOR_NODE (3)
/* "g_mem_chunk_new" creates a new memory chunk. /* "g_mem_chunk_new" creates a new memory chunk.
* Memory chunks are used to allocate pieces of memory which are * Memory chunks are used to allocate pieces of memory which are

View File

@ -57,19 +57,19 @@ static inline void g_data_set_internal (GData **datalist,
GDestroyNotify destroy_func, GDestroyNotify destroy_func,
GDataset *dataset); GDataset *dataset);
static void g_data_initialize (void); static void g_data_initialize (void);
static inline GQuark g_quark_new (const gchar *string); static inline GQuark g_quark_new (gchar *string);
/* --- variables --- */ /* --- variables --- */
static GHashTable *g_quark_ht = NULL;
static gchar **g_quarks = NULL;
static GQuark g_quark_seq_id = 0;
static GHashTable *g_dataset_location_ht = NULL; static GHashTable *g_dataset_location_ht = NULL;
static GDataset *g_dataset_cached = NULL; static GDataset *g_dataset_cached = NULL;
static GMemChunk *g_dataset_mem_chunk = NULL; static GMemChunk *g_dataset_mem_chunk = NULL;
static GMemChunk *g_data_mem_chunk = NULL; static GMemChunk *g_data_mem_chunk = NULL;
static GData *g_data_cache = NULL; static GData *g_data_cache = NULL;
static guint g_data_cache_length = 0; static guint g_data_cache_length = 0;
static GHashTable *g_quark_ht = NULL;
static gchar **g_quarks = NULL;
static GQuark g_quark_seq_id = 0;
/* --- functions --- */ /* --- functions --- */
@ -109,6 +109,9 @@ g_datalist_clear (GData **datalist)
{ {
g_return_if_fail (datalist != NULL); g_return_if_fail (datalist != NULL);
if (!g_dataset_location_ht)
g_data_initialize ();
while (*datalist) while (*datalist)
g_datalist_clear_i (datalist); g_datalist_clear_i (datalist);
} }
@ -174,9 +177,6 @@ g_data_set_internal (GData **datalist,
{ {
register GData *list; register GData *list;
if (!g_dataset_location_ht)
g_data_initialize ();
list = *datalist; list = *datalist;
if (!data) if (!data)
{ {
@ -201,7 +201,7 @@ g_data_set_internal (GData **datalist,
} }
/* the GData struct *must* already be unlinked /* the GData struct *must* already be unlinked
* when invoking the destroy function * when invoking the destroy function.
* we use (data==NULL && destroy_func!=NULL) as * we use (data==NULL && destroy_func!=NULL) as
* a special hint combination to "steal" * a special hint combination to "steal"
* data without destroy notification * data without destroy notification
@ -326,6 +326,9 @@ g_datalist_id_set_data_full (GData **datalist,
else else
return; return;
} }
if (!g_dataset_location_ht)
g_data_initialize ();
g_data_set_internal (datalist, key_id, data, destroy_func, NULL); g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
} }
@ -352,7 +355,7 @@ g_datalist_id_remove_no_notify (GData **datalist,
{ {
g_return_if_fail (datalist != NULL); g_return_if_fail (datalist != NULL);
if (key_id) if (key_id && g_dataset_location_ht)
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL); g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
} }
@ -407,14 +410,17 @@ g_dataset_foreach (gconstpointer dataset_location,
g_return_if_fail (dataset_location != NULL); g_return_if_fail (dataset_location != NULL);
g_return_if_fail (func != NULL); g_return_if_fail (func != NULL);
dataset = g_dataset_lookup (dataset_location); if (g_dataset_location_ht)
if (dataset)
{ {
register GData *list; dataset = g_dataset_lookup (dataset_location);
if (dataset)
for (list = dataset->datalist; list; list = list->next) {
func (list->id, list->data, user_data); register GData *list;
for (list = dataset->datalist; list; list = list->next)
func (list->id, list->data, user_data);
}
} }
} }
@ -443,22 +449,20 @@ g_datalist_init (GData **datalist)
static void static void
g_data_initialize (void) g_data_initialize (void)
{ {
if (!g_dataset_location_ht) g_return_if_fail (g_dataset_location_ht == NULL);
{
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal); g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL); g_dataset_cached = NULL;
g_dataset_cached = NULL; g_dataset_mem_chunk =
g_dataset_mem_chunk = g_mem_chunk_new ("GDataset MemChunk",
g_mem_chunk_new ("GDataset MemChunk", sizeof (GDataset),
sizeof (GDataset), sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC, G_ALLOC_AND_FREE);
G_ALLOC_AND_FREE); g_data_mem_chunk =
g_data_mem_chunk = g_mem_chunk_new ("GData MemChunk",
g_mem_chunk_new ("GData MemChunk", sizeof (GData),
sizeof (GData), sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC, G_ALLOC_AND_FREE);
G_ALLOC_AND_FREE);
}
} }
GQuark GQuark
@ -479,10 +483,14 @@ g_quark_from_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0); g_return_val_if_fail (string != NULL, 0);
if (!g_quark_ht) if (g_quark_ht)
g_data_initialize (); quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
else
{
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
quark = 0;
}
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
if (!quark) if (!quark)
quark = g_quark_new (g_strdup (string)); quark = g_quark_new (g_strdup (string));
@ -496,12 +504,16 @@ g_quark_from_static_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0); g_return_val_if_fail (string != NULL, 0);
if (!g_quark_ht) if (g_quark_ht)
g_data_initialize (); quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
else
quark = (gulong) g_hash_table_lookup (g_quark_ht, string); {
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
quark = 0;
}
if (!quark) if (!quark)
quark = g_quark_new (string); quark = g_quark_new ((gchar*) string);
return quark; return quark;
} }
@ -516,19 +528,17 @@ g_quark_to_string (GQuark quark)
} }
static inline GQuark static inline GQuark
g_quark_new (const gchar *string) g_quark_new (gchar *string)
{ {
GQuark quark; GQuark quark;
if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0) if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
g_quarks = g_realloc (g_quarks, g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
(g_quark_seq_id + G_QUARK_BLOCK_SIZE) * sizeof (gchar*));
g_quarks[g_quark_seq_id] = string;
g_quarks[g_quark_seq_id] = (gchar*) string;
g_quark_seq_id++; g_quark_seq_id++;
quark = g_quark_seq_id; quark = g_quark_seq_id;
g_hash_table_insert (g_quark_ht, (gchar*) string, GUINT_TO_POINTER (quark)); g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
return quark; return quark;
} }

View File

@ -695,6 +695,7 @@ GUTILS_C_VAR const guint glib_binary_age;
/* Forward declarations of glib types. /* Forward declarations of glib types.
*/ */
typedef struct _GAllocator GAllocator;
typedef struct _GArray GArray; typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray; typedef struct _GByteArray GByteArray;
typedef struct _GCache GCache; typedef struct _GCache GCache;
@ -705,7 +706,6 @@ typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook; typedef struct _GHook GHook;
typedef struct _GHookList GHookList; typedef struct _GHookList GHookList;
typedef struct _GList GList; typedef struct _GList GList;
typedef struct _GListAllocator GListAllocator;
typedef struct _GMemChunk GMemChunk; typedef struct _GMemChunk GMemChunk;
typedef struct _GNode GNode; typedef struct _GNode GNode;
typedef struct _GPtrArray GPtrArray; typedef struct _GPtrArray GPtrArray;
@ -865,6 +865,8 @@ struct _GDebugKey
/* Doubly linked lists /* Doubly linked lists
*/ */
void g_list_push_allocator (GAllocator *allocator);
void g_list_pop_allocator (void);
GList* g_list_alloc (void); GList* g_list_alloc (void);
void g_list_free (GList *list); void g_list_free (GList *list);
void g_list_free_1 (GList *list); void g_list_free_1 (GList *list);
@ -913,6 +915,8 @@ gpointer g_list_nth_data (GList *list,
/* Singly linked lists /* Singly linked lists
*/ */
void g_slist_push_allocator (GAllocator *allocator);
void g_slist_pop_allocator (void);
GSList* g_slist_alloc (void); GSList* g_slist_alloc (void);
void g_slist_free (GSList *list); void g_slist_free (GSList *list);
void g_slist_free_1 (GSList *list); void g_slist_free_1 (GSList *list);
@ -957,14 +961,6 @@ gpointer g_slist_nth_data (GSList *list,
#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL) #define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
/* List Allocators
*/
GListAllocator* g_list_allocator_new (void);
void g_list_allocator_free (GListAllocator* allocator);
GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
GListAllocator* g_list_set_allocator (GListAllocator* allocator);
/* Hash tables /* Hash tables
*/ */
GHashTable* g_hash_table_new (GHashFunc hash_func, GHashTable* g_hash_table_new (GHashFunc hash_func,
@ -1053,6 +1049,8 @@ struct _GNode
((GNode*) (node))->next == NULL) ((GNode*) (node))->next == NULL)
#define G_NODE_IS_LEAF(node) (((GNode*) (node))->children == NULL) #define G_NODE_IS_LEAF(node) (((GNode*) (node))->children == NULL)
void g_node_push_allocator (GAllocator *allocator);
void g_node_pop_allocator (void);
GNode* g_node_new (gpointer data); GNode* g_node_new (gpointer data);
void g_node_destroy (GNode *root); void g_node_destroy (GNode *root);
void g_node_unlink (GNode *node); void g_node_unlink (GNode *node);
@ -1363,6 +1361,16 @@ void g_free (gpointer mem);
void g_mem_profile (void); void g_mem_profile (void);
void g_mem_check (gpointer mem); void g_mem_check (gpointer mem);
/* Generic allocators
*/
GAllocator* g_allocator_new (const gchar *name,
guint n_preallocs);
void g_allocator_free (GAllocator *allocator);
#define G_ALLOCATOR_LIST (1)
#define G_ALLOCATOR_SLIST (2)
#define G_ALLOCATOR_NODE (3)
/* "g_mem_chunk_new" creates a new memory chunk. /* "g_mem_chunk_new" creates a new memory chunk.
* Memory chunks are used to allocate pieces of memory which are * Memory chunks are used to allocate pieces of memory which are

View File

@ -19,99 +19,104 @@
#include "glib.h" #include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator; struct _GAllocator /* from gmem.c */
struct _GRealListAllocator
{ {
GMemChunk *list_mem_chunk; gchar *name;
GList *free_list; guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GList *free_lists; /* implementation specific */
}; };
static GAllocator *current_allocator = NULL;
static GRealListAllocator *default_allocator = NULL; void
static GRealListAllocator *current_allocator = NULL; g_list_push_allocator (GAllocator *allocator)
GListAllocator*
g_list_allocator_new (void)
{ {
GRealListAllocator* allocator = g_new (GRealListAllocator, 1); g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
allocator->list_mem_chunk = NULL;
allocator->free_list = NULL; if (allocator->type != G_ALLOCATOR_LIST)
{
return (GListAllocator*) allocator; allocator->type = G_ALLOCATOR_LIST;
if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GList),
sizeof (GList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
allocator->is_unused = FALSE;
allocator->last = current_allocator;
current_allocator = allocator;
} }
void void
g_list_allocator_free (GListAllocator* fallocator) g_list_pop_allocator (void)
{ {
GRealListAllocator* allocator = (GRealListAllocator *) fallocator; if (current_allocator)
if (allocator && allocator->list_mem_chunk)
g_mem_chunk_destroy (allocator->list_mem_chunk);
if (allocator)
g_free (allocator);
}
GListAllocator*
g_list_set_allocator (GListAllocator* fallocator)
{
GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
GRealListAllocator* old_allocator = current_allocator;
if (allocator)
current_allocator = allocator;
else
{ {
if (!default_allocator) GAllocator *allocator;
default_allocator = (GRealListAllocator*) g_list_allocator_new ();
current_allocator = default_allocator;
}
if (!current_allocator->list_mem_chunk)
current_allocator->list_mem_chunk = g_mem_chunk_new ("list mem chunk",
sizeof (GList),
1024,
G_ALLOC_ONLY);
return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
}
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
GList* GList*
g_list_alloc (void) g_list_alloc (void)
{ {
GList *new_list; GList *list;
g_list_set_allocator (NULL); if (!current_allocator)
if (current_allocator->free_list) g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
if (!current_allocator->free_lists)
{ {
new_list = current_allocator->free_list; list = g_chunk_new (GList, current_allocator->mem_chunk);
current_allocator->free_list = current_allocator->free_list->next; list->data = NULL;
} }
else else
{ {
new_list = g_chunk_new (GList, current_allocator->list_mem_chunk); if (current_allocator->free_lists->data)
{
list = current_allocator->free_lists->data;
current_allocator->free_lists->data = list->next;
list->data = NULL;
}
else
{
list = current_allocator->free_lists;
current_allocator->free_lists = list->next;
}
} }
list->next = NULL;
list->prev = NULL;
new_list->data = NULL; return list;
new_list->next = NULL;
new_list->prev = NULL;
return new_list;
} }
void void
g_list_free (GList *list) g_list_free (GList *list)
{ {
GList *last;
if (list) if (list)
{ {
last = g_list_last (list); list->data = list->next;
last->next = current_allocator->free_list; list->next = current_allocator->free_lists;
current_allocator->free_list = list; current_allocator->free_lists = list;
} }
} }
@ -120,8 +125,9 @@ g_list_free_1 (GList *list)
{ {
if (list) if (list)
{ {
list->next = current_allocator->free_list; list->data = NULL;
current_allocator->free_list = list; list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
} }
} }

View File

@ -894,3 +894,49 @@ g_mem_chunk_area_search (GMemArea *a,
} }
return -1; return -1;
} }
/* generic allocators
*/
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
gpointer dummy; /* implementation specific */
};
GAllocator*
g_allocator_new (const gchar *name,
guint n_preallocs)
{
GAllocator *allocator;
g_return_val_if_fail (name != NULL, NULL);
allocator = g_new0 (GAllocator, 1);
allocator->name = g_strdup (name);
allocator->n_preallocs = CLAMP (n_preallocs, 1, 65535);
allocator->is_unused = TRUE;
allocator->type = 0;
allocator->last = NULL;
allocator->mem_chunk = NULL;
allocator->dummy = NULL;
return allocator;
}
void
g_allocator_free (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
g_free (allocator->name);
if (allocator->mem_chunk)
g_mem_chunk_destroy (allocator->mem_chunk);
g_free (allocator);
}

View File

@ -21,33 +21,82 @@
*/ */
#include "glib.h" #include "glib.h"
/* node allocation
*/
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GNode *free_nodes; /* implementation specific */
};
#define KEEP_NODES (1024) static GAllocator *current_allocator = NULL;
void
g_node_push_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
/* --- variables --- */ if (allocator->type != G_ALLOCATOR_NODE)
static GMemChunk *g_tree_node_chunk = NULL; {
static GNode *free_nodes = NULL; allocator->type = G_ALLOCATOR_NODE;
static guint n_free_nodes = 0; if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GNode),
sizeof (GNode) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_nodes = NULL;
}
allocator->is_unused = FALSE;
allocator->last = current_allocator;
current_allocator = allocator;
}
void
g_node_pop_allocator (void)
{
if (current_allocator)
{
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
/* --- functions --- */ /* --- functions --- */
GNode* GNode*
g_node_new (gpointer data) g_node_new (gpointer data)
{ {
register GNode *node; GNode *node;
if (!g_tree_node_chunk) if (!current_allocator)
g_tree_node_chunk = g_mem_chunk_create (GNode, 1024, G_ALLOC_AND_FREE); g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
if (n_free_nodes) if (!current_allocator->free_nodes)
{ node = g_chunk_new (GNode, current_allocator->mem_chunk);
node = free_nodes;
free_nodes = free_nodes->next;
n_free_nodes--;
}
else else
node = g_chunk_new (GNode, g_tree_node_chunk); {
node = current_allocator->free_nodes;
current_allocator->free_nodes = node->next;
}
node->data = data; node->data = data;
node->next = NULL; node->next = NULL;
@ -59,29 +108,23 @@ g_node_new (gpointer data)
} }
static void static void
g_node_free (GNode *parent) g_nodes_free (GNode *node)
{ {
GNode *node; GNode *parent;
node = parent->children; parent = node;
while (1)
while (node)
{ {
register GNode *free_node; if (parent->children)
g_nodes_free (parent->children);
free_node = node; if (parent->next)
node = free_node->next; parent = parent->next;
g_node_free (free_node); else
break;
} }
if (n_free_nodes < KEEP_NODES) parent->next = current_allocator->free_nodes;
{ current_allocator->free_nodes = node;
parent->next = free_nodes;
free_nodes = parent;
n_free_nodes++;
}
else
g_chunk_free (parent, g_tree_node_chunk);
} }
void void
@ -92,7 +135,7 @@ g_node_destroy (GNode *root)
if (!G_NODE_IS_ROOT (root)) if (!G_NODE_IS_ROOT (root))
g_node_unlink (root); g_node_unlink (root);
g_node_free (root); g_nodes_free (root);
} }
void void

View File

@ -19,75 +19,103 @@
#include "glib.h" #include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator; struct _GAllocator /* from gmem.c */
struct _GRealListAllocator
{ {
GMemChunk *list_mem_chunk; gchar *name;
GSList *free_list; guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GSList *free_lists; /* implementation specific */
}; };
static GAllocator *current_allocator = NULL;
static GRealListAllocator *default_allocator = NULL; void
static GRealListAllocator *current_allocator = NULL; g_slist_push_allocator (GAllocator *allocator)
GListAllocator*
g_slist_set_allocator (GListAllocator* fallocator)
{ {
GRealListAllocator* allocator = (GRealListAllocator *) fallocator; g_return_if_fail (allocator != NULL);
GRealListAllocator* old_allocator = current_allocator; g_return_if_fail (allocator->is_unused == TRUE);
if (allocator) if (allocator->type != G_ALLOCATOR_SLIST)
current_allocator = allocator;
else
{ {
if (!default_allocator) allocator->type = G_ALLOCATOR_SLIST;
default_allocator = (GRealListAllocator*) g_list_allocator_new (); if (allocator->mem_chunk)
current_allocator = default_allocator; {
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
} }
if (!current_allocator->list_mem_chunk) if (!allocator->mem_chunk)
current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk", {
sizeof (GSList), allocator->mem_chunk = g_mem_chunk_new (allocator->name,
1024, sizeof (GSList),
G_ALLOC_ONLY); sizeof (GSList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator); allocator->is_unused = FALSE;
allocator->last = current_allocator;
current_allocator = allocator;
} }
void
g_slist_pop_allocator (void)
{
if (current_allocator)
{
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
GSList* GSList*
g_slist_alloc (void) g_slist_alloc (void)
{ {
GSList *new_list; GSList *list;
g_slist_set_allocator (NULL); if (!current_allocator)
if (current_allocator->free_list) g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
if (!current_allocator->free_lists)
{ {
new_list = current_allocator->free_list; list = g_chunk_new (GSList, current_allocator->mem_chunk);
current_allocator->free_list = current_allocator->free_list->next; list->data = NULL;
} }
else else
{ {
new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk); if (current_allocator->free_lists->data)
{
list = current_allocator->free_lists->data;
current_allocator->free_lists->data = list->next;
list->data = NULL;
}
else
{
list = current_allocator->free_lists;
current_allocator->free_lists = list->next;
}
} }
list->next = NULL;
new_list->data = NULL; return list;
new_list->next = NULL;
return new_list;
} }
void void
g_slist_free (GSList *list) g_slist_free (GSList *list)
{ {
GSList *last;
if (list) if (list)
{ {
last = g_slist_last (list); list->data = list->next;
last->next = current_allocator->free_list; list->next = current_allocator->free_lists;
current_allocator->free_list = list; current_allocator->free_lists = list;
} }
} }
@ -96,8 +124,9 @@ g_slist_free_1 (GSList *list)
{ {
if (list) if (list)
{ {
list->next = current_allocator->free_list; list->data = NULL;
current_allocator->free_list = list; list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
} }
} }

View File

@ -106,14 +106,10 @@ g_string_chunk_free (GStringChunk *fchunk)
if (chunk->storage_list) if (chunk->storage_list)
{ {
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next) for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
g_free (tmp_list->data); g_free (tmp_list->data);
g_slist_free (chunk->storage_list); g_slist_free (chunk->storage_list);
g_slist_set_allocator (tmp_allocator);
} }
if (chunk->const_table) if (chunk->const_table)
@ -134,7 +130,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
if ((chunk->storage_next + len + 1) > chunk->this_size) if ((chunk->storage_next + len + 1) > chunk->this_size)
{ {
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
gint new_size = chunk->default_size; gint new_size = chunk->default_size;
while (new_size < len+1) while (new_size < len+1)
@ -145,8 +140,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
chunk->this_size = new_size; chunk->this_size = new_size;
chunk->storage_next = 0; chunk->storage_next = 0;
g_slist_set_allocator (tmp_allocator);
} }
pos = ((char*)chunk->storage_list->data) + chunk->storage_next; pos = ((char*)chunk->storage_list->data) + chunk->storage_next;

View File

@ -79,7 +79,51 @@ static void g_tree_node_check (GTreeNode *node);
static GMemChunk *node_mem_chunk = NULL; static GMemChunk *node_mem_chunk = NULL;
static GSList *node_free_list = NULL; static GTreeNode *node_free_list = NULL;
static GTreeNode*
g_tree_node_new (gpointer key,
gpointer value)
{
GTreeNode *node;
if (node_free_list)
{
node = node_free_list;
node_free_list = node->right;
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("GLib GTreeNode mem chunk",
sizeof (GTreeNode),
1024,
G_ALLOC_ONLY);
node = g_chunk_new (GTreeNode, node_mem_chunk);
}
node->balance = 0;
node->left = NULL;
node->right = NULL;
node->key = key;
node->value = value;
return node;
}
static void
g_tree_node_destroy (GTreeNode *node)
{
if (node)
{
g_tree_node_destroy (node->right);
g_tree_node_destroy (node->left);
node->right = node_free_list;
node_free_list = node;
}
}
GTree* GTree*
@ -230,55 +274,6 @@ g_tree_nnodes (GTree *tree)
return 0; return 0;
} }
static GTreeNode*
g_tree_node_new (gpointer key,
gpointer value)
{
GTreeNode *node;
GSList *tmp_list;
if (node_free_list)
{
tmp_list = node_free_list;
node_free_list = node_free_list->next;
node = tmp_list->data;
{
GListAllocator *tmp_allocator = g_list_set_allocator (NULL);
g_slist_free_1 (tmp_list);
g_list_set_allocator (tmp_allocator);
}
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("tree node mem chunk", sizeof (GTreeNode), 1024, G_ALLOC_ONLY);
node = g_chunk_new (GTreeNode, node_mem_chunk);
}
node->balance = 0;
node->left = NULL;
node->right = NULL;
node->key = key;
node->value = value;
return node;
}
static void
g_tree_node_destroy (GTreeNode *node)
{
if (node)
{
node_free_list = g_slist_prepend (node_free_list, node);
g_tree_node_destroy (node->right);
g_tree_node_destroy (node->left);
}
}
static GTreeNode* static GTreeNode*
g_tree_node_insert (GTreeNode *node, g_tree_node_insert (GTreeNode *node,
GCompareFunc compare, GCompareFunc compare,
@ -352,7 +347,6 @@ g_tree_node_remove (GTreeNode *node,
GCompareFunc compare, GCompareFunc compare,
gpointer key) gpointer key)
{ {
GTreeNode *garbage;
GTreeNode *new_root; GTreeNode *new_root;
gint old_balance; gint old_balance;
gint cmp; gint cmp;
@ -363,6 +357,8 @@ g_tree_node_remove (GTreeNode *node,
cmp = (* compare) (key, node->key); cmp = (* compare) (key, node->key);
if (cmp == 0) if (cmp == 0)
{ {
GTreeNode *garbage;
garbage = node; garbage = node;
if (!node->right) if (!node->right)
@ -379,7 +375,8 @@ g_tree_node_remove (GTreeNode *node,
node = g_tree_node_restore_right_balance (new_root, old_balance); node = g_tree_node_restore_right_balance (new_root, old_balance);
} }
node_free_list = g_slist_prepend (node_free_list, garbage); garbage->right = node_free_list;
node_free_list = garbage;
} }
else if (cmp < 0) else if (cmp < 0)
{ {

140
glist.c
View File

@ -19,99 +19,104 @@
#include "glib.h" #include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator; struct _GAllocator /* from gmem.c */
struct _GRealListAllocator
{ {
GMemChunk *list_mem_chunk; gchar *name;
GList *free_list; guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GList *free_lists; /* implementation specific */
}; };
static GAllocator *current_allocator = NULL;
static GRealListAllocator *default_allocator = NULL; void
static GRealListAllocator *current_allocator = NULL; g_list_push_allocator (GAllocator *allocator)
GListAllocator*
g_list_allocator_new (void)
{ {
GRealListAllocator* allocator = g_new (GRealListAllocator, 1); g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
allocator->list_mem_chunk = NULL;
allocator->free_list = NULL; if (allocator->type != G_ALLOCATOR_LIST)
{
return (GListAllocator*) allocator; allocator->type = G_ALLOCATOR_LIST;
if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GList),
sizeof (GList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
allocator->is_unused = FALSE;
allocator->last = current_allocator;
current_allocator = allocator;
} }
void void
g_list_allocator_free (GListAllocator* fallocator) g_list_pop_allocator (void)
{ {
GRealListAllocator* allocator = (GRealListAllocator *) fallocator; if (current_allocator)
if (allocator && allocator->list_mem_chunk)
g_mem_chunk_destroy (allocator->list_mem_chunk);
if (allocator)
g_free (allocator);
}
GListAllocator*
g_list_set_allocator (GListAllocator* fallocator)
{
GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
GRealListAllocator* old_allocator = current_allocator;
if (allocator)
current_allocator = allocator;
else
{ {
if (!default_allocator) GAllocator *allocator;
default_allocator = (GRealListAllocator*) g_list_allocator_new ();
current_allocator = default_allocator;
}
if (!current_allocator->list_mem_chunk)
current_allocator->list_mem_chunk = g_mem_chunk_new ("list mem chunk",
sizeof (GList),
1024,
G_ALLOC_ONLY);
return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
}
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
GList* GList*
g_list_alloc (void) g_list_alloc (void)
{ {
GList *new_list; GList *list;
g_list_set_allocator (NULL); if (!current_allocator)
if (current_allocator->free_list) g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
if (!current_allocator->free_lists)
{ {
new_list = current_allocator->free_list; list = g_chunk_new (GList, current_allocator->mem_chunk);
current_allocator->free_list = current_allocator->free_list->next; list->data = NULL;
} }
else else
{ {
new_list = g_chunk_new (GList, current_allocator->list_mem_chunk); if (current_allocator->free_lists->data)
{
list = current_allocator->free_lists->data;
current_allocator->free_lists->data = list->next;
list->data = NULL;
}
else
{
list = current_allocator->free_lists;
current_allocator->free_lists = list->next;
}
} }
list->next = NULL;
list->prev = NULL;
new_list->data = NULL; return list;
new_list->next = NULL;
new_list->prev = NULL;
return new_list;
} }
void void
g_list_free (GList *list) g_list_free (GList *list)
{ {
GList *last;
if (list) if (list)
{ {
last = g_list_last (list); list->data = list->next;
last->next = current_allocator->free_list; list->next = current_allocator->free_lists;
current_allocator->free_list = list; current_allocator->free_lists = list;
} }
} }
@ -120,8 +125,9 @@ g_list_free_1 (GList *list)
{ {
if (list) if (list)
{ {
list->next = current_allocator->free_list; list->data = NULL;
current_allocator->free_list = list; list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
} }
} }

46
gmem.c
View File

@ -894,3 +894,49 @@ g_mem_chunk_area_search (GMemArea *a,
} }
return -1; return -1;
} }
/* generic allocators
*/
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
gpointer dummy; /* implementation specific */
};
GAllocator*
g_allocator_new (const gchar *name,
guint n_preallocs)
{
GAllocator *allocator;
g_return_val_if_fail (name != NULL, NULL);
allocator = g_new0 (GAllocator, 1);
allocator->name = g_strdup (name);
allocator->n_preallocs = CLAMP (n_preallocs, 1, 65535);
allocator->is_unused = TRUE;
allocator->type = 0;
allocator->last = NULL;
allocator->mem_chunk = NULL;
allocator->dummy = NULL;
return allocator;
}
void
g_allocator_free (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
g_free (allocator->name);
if (allocator->mem_chunk)
g_mem_chunk_destroy (allocator->mem_chunk);
g_free (allocator);
}

115
gnode.c
View File

@ -21,33 +21,82 @@
*/ */
#include "glib.h" #include "glib.h"
/* node allocation
*/
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GNode *free_nodes; /* implementation specific */
};
#define KEEP_NODES (1024) static GAllocator *current_allocator = NULL;
void
g_node_push_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
/* --- variables --- */ if (allocator->type != G_ALLOCATOR_NODE)
static GMemChunk *g_tree_node_chunk = NULL; {
static GNode *free_nodes = NULL; allocator->type = G_ALLOCATOR_NODE;
static guint n_free_nodes = 0; if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GNode),
sizeof (GNode) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_nodes = NULL;
}
allocator->is_unused = FALSE;
allocator->last = current_allocator;
current_allocator = allocator;
}
void
g_node_pop_allocator (void)
{
if (current_allocator)
{
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
/* --- functions --- */ /* --- functions --- */
GNode* GNode*
g_node_new (gpointer data) g_node_new (gpointer data)
{ {
register GNode *node; GNode *node;
if (!g_tree_node_chunk) if (!current_allocator)
g_tree_node_chunk = g_mem_chunk_create (GNode, 1024, G_ALLOC_AND_FREE); g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
if (n_free_nodes) if (!current_allocator->free_nodes)
{ node = g_chunk_new (GNode, current_allocator->mem_chunk);
node = free_nodes;
free_nodes = free_nodes->next;
n_free_nodes--;
}
else else
node = g_chunk_new (GNode, g_tree_node_chunk); {
node = current_allocator->free_nodes;
current_allocator->free_nodes = node->next;
}
node->data = data; node->data = data;
node->next = NULL; node->next = NULL;
@ -59,29 +108,23 @@ g_node_new (gpointer data)
} }
static void static void
g_node_free (GNode *parent) g_nodes_free (GNode *node)
{ {
GNode *node; GNode *parent;
node = parent->children; parent = node;
while (1)
while (node)
{ {
register GNode *free_node; if (parent->children)
g_nodes_free (parent->children);
free_node = node; if (parent->next)
node = free_node->next; parent = parent->next;
g_node_free (free_node); else
break;
} }
if (n_free_nodes < KEEP_NODES) parent->next = current_allocator->free_nodes;
{ current_allocator->free_nodes = node;
parent->next = free_nodes;
free_nodes = parent;
n_free_nodes++;
}
else
g_chunk_free (parent, g_tree_node_chunk);
} }
void void
@ -92,7 +135,7 @@ g_node_destroy (GNode *root)
if (!G_NODE_IS_ROOT (root)) if (!G_NODE_IS_ROOT (root))
g_node_unlink (root); g_node_unlink (root);
g_node_free (root); g_nodes_free (root);
} }
void void

111
gslist.c
View File

@ -19,75 +19,103 @@
#include "glib.h" #include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator; struct _GAllocator /* from gmem.c */
struct _GRealListAllocator
{ {
GMemChunk *list_mem_chunk; gchar *name;
GSList *free_list; guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GSList *free_lists; /* implementation specific */
}; };
static GAllocator *current_allocator = NULL;
static GRealListAllocator *default_allocator = NULL; void
static GRealListAllocator *current_allocator = NULL; g_slist_push_allocator (GAllocator *allocator)
GListAllocator*
g_slist_set_allocator (GListAllocator* fallocator)
{ {
GRealListAllocator* allocator = (GRealListAllocator *) fallocator; g_return_if_fail (allocator != NULL);
GRealListAllocator* old_allocator = current_allocator; g_return_if_fail (allocator->is_unused == TRUE);
if (allocator) if (allocator->type != G_ALLOCATOR_SLIST)
current_allocator = allocator;
else
{ {
if (!default_allocator) allocator->type = G_ALLOCATOR_SLIST;
default_allocator = (GRealListAllocator*) g_list_allocator_new (); if (allocator->mem_chunk)
current_allocator = default_allocator; {
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
} }
if (!current_allocator->list_mem_chunk) if (!allocator->mem_chunk)
current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk", {
sizeof (GSList), allocator->mem_chunk = g_mem_chunk_new (allocator->name,
1024, sizeof (GSList),
G_ALLOC_ONLY); sizeof (GSList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator); allocator->is_unused = FALSE;
allocator->last = current_allocator;
current_allocator = allocator;
} }
void
g_slist_pop_allocator (void)
{
if (current_allocator)
{
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
GSList* GSList*
g_slist_alloc (void) g_slist_alloc (void)
{ {
GSList *new_list; GSList *list;
g_slist_set_allocator (NULL); if (!current_allocator)
if (current_allocator->free_list) g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
if (!current_allocator->free_lists)
{ {
new_list = current_allocator->free_list; list = g_chunk_new (GSList, current_allocator->mem_chunk);
current_allocator->free_list = current_allocator->free_list->next; list->data = NULL;
} }
else else
{ {
new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk); if (current_allocator->free_lists->data)
{
list = current_allocator->free_lists->data;
current_allocator->free_lists->data = list->next;
list->data = NULL;
}
else
{
list = current_allocator->free_lists;
current_allocator->free_lists = list->next;
}
} }
list->next = NULL;
new_list->data = NULL; return list;
new_list->next = NULL;
return new_list;
} }
void void
g_slist_free (GSList *list) g_slist_free (GSList *list)
{ {
GSList *last;
if (list) if (list)
{ {
last = g_slist_last (list); list->data = list->next;
last->next = current_allocator->free_list; list->next = current_allocator->free_lists;
current_allocator->free_list = list; current_allocator->free_lists = list;
} }
} }
@ -96,8 +124,9 @@ g_slist_free_1 (GSList *list)
{ {
if (list) if (list)
{ {
list->next = current_allocator->free_list; list->data = NULL;
current_allocator->free_list = list; list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
} }
} }

View File

@ -106,14 +106,10 @@ g_string_chunk_free (GStringChunk *fchunk)
if (chunk->storage_list) if (chunk->storage_list)
{ {
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next) for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
g_free (tmp_list->data); g_free (tmp_list->data);
g_slist_free (chunk->storage_list); g_slist_free (chunk->storage_list);
g_slist_set_allocator (tmp_allocator);
} }
if (chunk->const_table) if (chunk->const_table)
@ -134,7 +130,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
if ((chunk->storage_next + len + 1) > chunk->this_size) if ((chunk->storage_next + len + 1) > chunk->this_size)
{ {
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
gint new_size = chunk->default_size; gint new_size = chunk->default_size;
while (new_size < len+1) while (new_size < len+1)
@ -145,8 +140,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
chunk->this_size = new_size; chunk->this_size = new_size;
chunk->storage_next = 0; chunk->storage_next = 0;
g_slist_set_allocator (tmp_allocator);
} }
pos = ((char*)chunk->storage_list->data) + chunk->storage_next; pos = ((char*)chunk->storage_list->data) + chunk->storage_next;

101
gtree.c
View File

@ -79,7 +79,51 @@ static void g_tree_node_check (GTreeNode *node);
static GMemChunk *node_mem_chunk = NULL; static GMemChunk *node_mem_chunk = NULL;
static GSList *node_free_list = NULL; static GTreeNode *node_free_list = NULL;
static GTreeNode*
g_tree_node_new (gpointer key,
gpointer value)
{
GTreeNode *node;
if (node_free_list)
{
node = node_free_list;
node_free_list = node->right;
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("GLib GTreeNode mem chunk",
sizeof (GTreeNode),
1024,
G_ALLOC_ONLY);
node = g_chunk_new (GTreeNode, node_mem_chunk);
}
node->balance = 0;
node->left = NULL;
node->right = NULL;
node->key = key;
node->value = value;
return node;
}
static void
g_tree_node_destroy (GTreeNode *node)
{
if (node)
{
g_tree_node_destroy (node->right);
g_tree_node_destroy (node->left);
node->right = node_free_list;
node_free_list = node;
}
}
GTree* GTree*
@ -230,55 +274,6 @@ g_tree_nnodes (GTree *tree)
return 0; return 0;
} }
static GTreeNode*
g_tree_node_new (gpointer key,
gpointer value)
{
GTreeNode *node;
GSList *tmp_list;
if (node_free_list)
{
tmp_list = node_free_list;
node_free_list = node_free_list->next;
node = tmp_list->data;
{
GListAllocator *tmp_allocator = g_list_set_allocator (NULL);
g_slist_free_1 (tmp_list);
g_list_set_allocator (tmp_allocator);
}
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("tree node mem chunk", sizeof (GTreeNode), 1024, G_ALLOC_ONLY);
node = g_chunk_new (GTreeNode, node_mem_chunk);
}
node->balance = 0;
node->left = NULL;
node->right = NULL;
node->key = key;
node->value = value;
return node;
}
static void
g_tree_node_destroy (GTreeNode *node)
{
if (node)
{
node_free_list = g_slist_prepend (node_free_list, node);
g_tree_node_destroy (node->right);
g_tree_node_destroy (node->left);
}
}
static GTreeNode* static GTreeNode*
g_tree_node_insert (GTreeNode *node, g_tree_node_insert (GTreeNode *node,
GCompareFunc compare, GCompareFunc compare,
@ -352,7 +347,6 @@ g_tree_node_remove (GTreeNode *node,
GCompareFunc compare, GCompareFunc compare,
gpointer key) gpointer key)
{ {
GTreeNode *garbage;
GTreeNode *new_root; GTreeNode *new_root;
gint old_balance; gint old_balance;
gint cmp; gint cmp;
@ -363,6 +357,8 @@ g_tree_node_remove (GTreeNode *node,
cmp = (* compare) (key, node->key); cmp = (* compare) (key, node->key);
if (cmp == 0) if (cmp == 0)
{ {
GTreeNode *garbage;
garbage = node; garbage = node;
if (!node->right) if (!node->right)
@ -379,7 +375,8 @@ g_tree_node_remove (GTreeNode *node,
node = g_tree_node_restore_right_balance (new_root, old_balance); node = g_tree_node_restore_right_balance (new_root, old_balance);
} }
node_free_list = g_slist_prepend (node_free_list, garbage); garbage->right = node_free_list;
node_free_list = garbage;
} }
else if (cmp < 0) else if (cmp < 0)
{ {