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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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>
* 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,
GDataset *dataset);
static void g_data_initialize (void);
static inline GQuark g_quark_new (const gchar *string);
static inline GQuark g_quark_new (gchar *string);
/* --- 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 GDataset *g_dataset_cached = NULL;
static GMemChunk *g_dataset_mem_chunk = NULL;
static GMemChunk *g_data_mem_chunk = NULL;
static GData *g_data_cache = NULL;
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 --- */
@ -109,6 +109,9 @@ g_datalist_clear (GData **datalist)
{
g_return_if_fail (datalist != NULL);
if (!g_dataset_location_ht)
g_data_initialize ();
while (*datalist)
g_datalist_clear_i (datalist);
}
@ -174,9 +177,6 @@ g_data_set_internal (GData **datalist,
{
register GData *list;
if (!g_dataset_location_ht)
g_data_initialize ();
list = *datalist;
if (!data)
{
@ -201,7 +201,7 @@ g_data_set_internal (GData **datalist,
}
/* 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
* a special hint combination to "steal"
* data without destroy notification
@ -326,6 +326,9 @@ g_datalist_id_set_data_full (GData **datalist,
else
return;
}
if (!g_dataset_location_ht)
g_data_initialize ();
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);
if (key_id)
if (key_id && g_dataset_location_ht)
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 (func != NULL);
dataset = g_dataset_lookup (dataset_location);
if (dataset)
if (g_dataset_location_ht)
{
register GData *list;
for (list = dataset->datalist; list; list = list->next)
func (list->id, list->data, user_data);
dataset = g_dataset_lookup (dataset_location);
if (dataset)
{
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
g_data_initialize (void)
{
if (!g_dataset_location_ht)
{
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_cached = NULL;
g_dataset_mem_chunk =
g_mem_chunk_new ("GDataset MemChunk",
sizeof (GDataset),
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
g_data_mem_chunk =
g_mem_chunk_new ("GData MemChunk",
sizeof (GData),
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
}
g_return_if_fail (g_dataset_location_ht == NULL);
g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
g_dataset_cached = NULL;
g_dataset_mem_chunk =
g_mem_chunk_new ("GDataset MemChunk",
sizeof (GDataset),
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
g_data_mem_chunk =
g_mem_chunk_new ("GData MemChunk",
sizeof (GData),
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
}
GQuark
@ -479,10 +483,14 @@ g_quark_from_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0);
if (!g_quark_ht)
g_data_initialize ();
if (g_quark_ht)
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)
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);
if (!g_quark_ht)
g_data_initialize ();
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
if (g_quark_ht)
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;
}
if (!quark)
quark = g_quark_new (string);
quark = g_quark_new ((gchar*) string);
return quark;
}
@ -516,19 +528,17 @@ g_quark_to_string (GQuark quark)
}
static inline GQuark
g_quark_new (const gchar *string)
g_quark_new (gchar *string)
{
GQuark quark;
if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
g_quarks = g_realloc (g_quarks,
(g_quark_seq_id + G_QUARK_BLOCK_SIZE) * sizeof (gchar*));
g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
g_quarks[g_quark_seq_id] = (gchar*) string;
g_quarks[g_quark_seq_id] = string;
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;
}

26
glib.h
View File

@ -695,6 +695,7 @@ GUTILS_C_VAR const guint glib_binary_age;
/* Forward declarations of glib types.
*/
typedef struct _GAllocator GAllocator;
typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray;
typedef struct _GCache GCache;
@ -705,7 +706,6 @@ typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook;
typedef struct _GHookList GHookList;
typedef struct _GList GList;
typedef struct _GListAllocator GListAllocator;
typedef struct _GMemChunk GMemChunk;
typedef struct _GNode GNode;
typedef struct _GPtrArray GPtrArray;
@ -865,6 +865,8 @@ struct _GDebugKey
/* Doubly linked lists
*/
void g_list_push_allocator (GAllocator *allocator);
void g_list_pop_allocator (void);
GList* g_list_alloc (void);
void g_list_free (GList *list);
void g_list_free_1 (GList *list);
@ -913,6 +915,8 @@ gpointer g_list_nth_data (GList *list,
/* Singly linked lists
*/
void g_slist_push_allocator (GAllocator *allocator);
void g_slist_pop_allocator (void);
GSList* g_slist_alloc (void);
void g_slist_free (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)
/* 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
*/
GHashTable* g_hash_table_new (GHashFunc hash_func,
@ -1053,6 +1049,8 @@ struct _GNode
((GNode*) (node))->next == 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);
void g_node_destroy (GNode *root);
void g_node_unlink (GNode *node);
@ -1363,6 +1361,16 @@ void g_free (gpointer mem);
void g_mem_profile (void);
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.
* 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,
GDataset *dataset);
static void g_data_initialize (void);
static inline GQuark g_quark_new (const gchar *string);
static inline GQuark g_quark_new (gchar *string);
/* --- 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 GDataset *g_dataset_cached = NULL;
static GMemChunk *g_dataset_mem_chunk = NULL;
static GMemChunk *g_data_mem_chunk = NULL;
static GData *g_data_cache = NULL;
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 --- */
@ -109,6 +109,9 @@ g_datalist_clear (GData **datalist)
{
g_return_if_fail (datalist != NULL);
if (!g_dataset_location_ht)
g_data_initialize ();
while (*datalist)
g_datalist_clear_i (datalist);
}
@ -174,9 +177,6 @@ g_data_set_internal (GData **datalist,
{
register GData *list;
if (!g_dataset_location_ht)
g_data_initialize ();
list = *datalist;
if (!data)
{
@ -201,7 +201,7 @@ g_data_set_internal (GData **datalist,
}
/* 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
* a special hint combination to "steal"
* data without destroy notification
@ -326,6 +326,9 @@ g_datalist_id_set_data_full (GData **datalist,
else
return;
}
if (!g_dataset_location_ht)
g_data_initialize ();
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);
if (key_id)
if (key_id && g_dataset_location_ht)
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 (func != NULL);
dataset = g_dataset_lookup (dataset_location);
if (dataset)
if (g_dataset_location_ht)
{
register GData *list;
for (list = dataset->datalist; list; list = list->next)
func (list->id, list->data, user_data);
dataset = g_dataset_lookup (dataset_location);
if (dataset)
{
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
g_data_initialize (void)
{
if (!g_dataset_location_ht)
{
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_cached = NULL;
g_dataset_mem_chunk =
g_mem_chunk_new ("GDataset MemChunk",
sizeof (GDataset),
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
g_data_mem_chunk =
g_mem_chunk_new ("GData MemChunk",
sizeof (GData),
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
}
g_return_if_fail (g_dataset_location_ht == NULL);
g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
g_dataset_cached = NULL;
g_dataset_mem_chunk =
g_mem_chunk_new ("GDataset MemChunk",
sizeof (GDataset),
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
g_data_mem_chunk =
g_mem_chunk_new ("GData MemChunk",
sizeof (GData),
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
}
GQuark
@ -479,10 +483,14 @@ g_quark_from_string (const gchar *string)
g_return_val_if_fail (string != NULL, 0);
if (!g_quark_ht)
g_data_initialize ();
if (g_quark_ht)
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)
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);
if (!g_quark_ht)
g_data_initialize ();
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
if (g_quark_ht)
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;
}
if (!quark)
quark = g_quark_new (string);
quark = g_quark_new ((gchar*) string);
return quark;
}
@ -516,19 +528,17 @@ g_quark_to_string (GQuark quark)
}
static inline GQuark
g_quark_new (const gchar *string)
g_quark_new (gchar *string)
{
GQuark quark;
if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
g_quarks = g_realloc (g_quarks,
(g_quark_seq_id + G_QUARK_BLOCK_SIZE) * sizeof (gchar*));
g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
g_quarks[g_quark_seq_id] = (gchar*) string;
g_quarks[g_quark_seq_id] = string;
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;
}

View File

@ -695,6 +695,7 @@ GUTILS_C_VAR const guint glib_binary_age;
/* Forward declarations of glib types.
*/
typedef struct _GAllocator GAllocator;
typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray;
typedef struct _GCache GCache;
@ -705,7 +706,6 @@ typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook;
typedef struct _GHookList GHookList;
typedef struct _GList GList;
typedef struct _GListAllocator GListAllocator;
typedef struct _GMemChunk GMemChunk;
typedef struct _GNode GNode;
typedef struct _GPtrArray GPtrArray;
@ -865,6 +865,8 @@ struct _GDebugKey
/* Doubly linked lists
*/
void g_list_push_allocator (GAllocator *allocator);
void g_list_pop_allocator (void);
GList* g_list_alloc (void);
void g_list_free (GList *list);
void g_list_free_1 (GList *list);
@ -913,6 +915,8 @@ gpointer g_list_nth_data (GList *list,
/* Singly linked lists
*/
void g_slist_push_allocator (GAllocator *allocator);
void g_slist_pop_allocator (void);
GSList* g_slist_alloc (void);
void g_slist_free (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)
/* 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
*/
GHashTable* g_hash_table_new (GHashFunc hash_func,
@ -1053,6 +1049,8 @@ struct _GNode
((GNode*) (node))->next == 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);
void g_node_destroy (GNode *root);
void g_node_unlink (GNode *node);
@ -1363,6 +1361,16 @@ void g_free (gpointer mem);
void g_mem_profile (void);
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.
* Memory chunks are used to allocate pieces of memory which are

View File

@ -19,99 +19,104 @@
#include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator;
struct _GRealListAllocator
struct _GAllocator /* from gmem.c */
{
GMemChunk *list_mem_chunk;
GList *free_list;
gchar *name;
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;
static GRealListAllocator *current_allocator = NULL;
GListAllocator*
g_list_allocator_new (void)
void
g_list_push_allocator (GAllocator *allocator)
{
GRealListAllocator* allocator = g_new (GRealListAllocator, 1);
allocator->list_mem_chunk = NULL;
allocator->free_list = NULL;
return (GListAllocator*) allocator;
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_LIST)
{
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
g_list_allocator_free (GListAllocator* fallocator)
g_list_pop_allocator (void)
{
GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
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 (current_allocator)
{
if (!default_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);
}
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
GList*
g_list_alloc (void)
{
GList *new_list;
g_list_set_allocator (NULL);
if (current_allocator->free_list)
GList *list;
if (!current_allocator)
g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
if (!current_allocator->free_lists)
{
new_list = current_allocator->free_list;
current_allocator->free_list = current_allocator->free_list->next;
list = g_chunk_new (GList, current_allocator->mem_chunk);
list->data = NULL;
}
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;
new_list->next = NULL;
new_list->prev = NULL;
return new_list;
return list;
}
void
g_list_free (GList *list)
{
GList *last;
if (list)
{
last = g_list_last (list);
last->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = list->next;
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
}
}
@ -120,8 +125,9 @@ g_list_free_1 (GList *list)
{
if (list)
{
list->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = NULL;
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;
}
/* 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"
/* 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 --- */
static GMemChunk *g_tree_node_chunk = NULL;
static GNode *free_nodes = NULL;
static guint n_free_nodes = 0;
if (allocator->type != G_ALLOCATOR_NODE)
{
allocator->type = G_ALLOCATOR_NODE;
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 --- */
GNode*
g_node_new (gpointer data)
{
register GNode *node;
if (!g_tree_node_chunk)
g_tree_node_chunk = g_mem_chunk_create (GNode, 1024, G_ALLOC_AND_FREE);
if (n_free_nodes)
{
node = free_nodes;
free_nodes = free_nodes->next;
n_free_nodes--;
}
GNode *node;
if (!current_allocator)
g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
if (!current_allocator->free_nodes)
node = g_chunk_new (GNode, current_allocator->mem_chunk);
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->next = NULL;
@ -59,29 +108,23 @@ g_node_new (gpointer data)
}
static void
g_node_free (GNode *parent)
g_nodes_free (GNode *node)
{
GNode *node;
GNode *parent;
node = parent->children;
while (node)
parent = node;
while (1)
{
register GNode *free_node;
free_node = node;
node = free_node->next;
g_node_free (free_node);
if (parent->children)
g_nodes_free (parent->children);
if (parent->next)
parent = parent->next;
else
break;
}
if (n_free_nodes < KEEP_NODES)
{
parent->next = free_nodes;
free_nodes = parent;
n_free_nodes++;
}
else
g_chunk_free (parent, g_tree_node_chunk);
parent->next = current_allocator->free_nodes;
current_allocator->free_nodes = node;
}
void
@ -92,7 +135,7 @@ g_node_destroy (GNode *root)
if (!G_NODE_IS_ROOT (root))
g_node_unlink (root);
g_node_free (root);
g_nodes_free (root);
}
void

View File

@ -19,75 +19,103 @@
#include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator;
struct _GRealListAllocator
struct _GAllocator /* from gmem.c */
{
GMemChunk *list_mem_chunk;
GSList *free_list;
gchar *name;
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;
static GRealListAllocator *current_allocator = NULL;
GListAllocator*
g_slist_set_allocator (GListAllocator* fallocator)
void
g_slist_push_allocator (GAllocator *allocator)
{
GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
GRealListAllocator* old_allocator = current_allocator;
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator)
current_allocator = allocator;
else
if (allocator->type != G_ALLOCATOR_SLIST)
{
if (!default_allocator)
default_allocator = (GRealListAllocator*) g_list_allocator_new ();
current_allocator = default_allocator;
allocator->type = G_ALLOCATOR_SLIST;
if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!current_allocator->list_mem_chunk)
current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
sizeof (GSList),
1024,
G_ALLOC_ONLY);
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GSList),
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*
g_slist_alloc (void)
{
GSList *new_list;
GSList *list;
g_slist_set_allocator (NULL);
if (current_allocator->free_list)
if (!current_allocator)
g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
if (!current_allocator->free_lists)
{
new_list = current_allocator->free_list;
current_allocator->free_list = current_allocator->free_list->next;
list = g_chunk_new (GSList, current_allocator->mem_chunk);
list->data = NULL;
}
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;
new_list->next = NULL;
return new_list;
return list;
}
void
g_slist_free (GSList *list)
{
GSList *last;
if (list)
{
last = g_slist_last (list);
last->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = list->next;
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
}
}
@ -96,8 +124,9 @@ g_slist_free_1 (GSList *list)
{
if (list)
{
list->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = NULL;
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)
{
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
g_free (tmp_list->data);
g_slist_free (chunk->storage_list);
g_slist_set_allocator (tmp_allocator);
}
if (chunk->const_table)
@ -134,7 +130,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
if ((chunk->storage_next + len + 1) > chunk->this_size)
{
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
gint new_size = chunk->default_size;
while (new_size < len+1)
@ -145,8 +140,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
chunk->this_size = new_size;
chunk->storage_next = 0;
g_slist_set_allocator (tmp_allocator);
}
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 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*
@ -230,55 +274,6 @@ g_tree_nnodes (GTree *tree)
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*
g_tree_node_insert (GTreeNode *node,
GCompareFunc compare,
@ -352,7 +347,6 @@ g_tree_node_remove (GTreeNode *node,
GCompareFunc compare,
gpointer key)
{
GTreeNode *garbage;
GTreeNode *new_root;
gint old_balance;
gint cmp;
@ -363,6 +357,8 @@ g_tree_node_remove (GTreeNode *node,
cmp = (* compare) (key, node->key);
if (cmp == 0)
{
GTreeNode *garbage;
garbage = node;
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_free_list = g_slist_prepend (node_free_list, garbage);
garbage->right = node_free_list;
node_free_list = garbage;
}
else if (cmp < 0)
{

140
glist.c
View File

@ -19,99 +19,104 @@
#include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator;
struct _GRealListAllocator
struct _GAllocator /* from gmem.c */
{
GMemChunk *list_mem_chunk;
GList *free_list;
gchar *name;
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;
static GRealListAllocator *current_allocator = NULL;
GListAllocator*
g_list_allocator_new (void)
void
g_list_push_allocator (GAllocator *allocator)
{
GRealListAllocator* allocator = g_new (GRealListAllocator, 1);
allocator->list_mem_chunk = NULL;
allocator->free_list = NULL;
return (GListAllocator*) allocator;
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_LIST)
{
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
g_list_allocator_free (GListAllocator* fallocator)
g_list_pop_allocator (void)
{
GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
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 (current_allocator)
{
if (!default_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);
}
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
}
GList*
g_list_alloc (void)
{
GList *new_list;
g_list_set_allocator (NULL);
if (current_allocator->free_list)
GList *list;
if (!current_allocator)
g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
if (!current_allocator->free_lists)
{
new_list = current_allocator->free_list;
current_allocator->free_list = current_allocator->free_list->next;
list = g_chunk_new (GList, current_allocator->mem_chunk);
list->data = NULL;
}
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;
new_list->next = NULL;
new_list->prev = NULL;
return new_list;
return list;
}
void
g_list_free (GList *list)
{
GList *last;
if (list)
{
last = g_list_last (list);
last->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = list->next;
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
}
}
@ -120,8 +125,9 @@ g_list_free_1 (GList *list)
{
if (list)
{
list->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = NULL;
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;
}
/* 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"
/* 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 --- */
static GMemChunk *g_tree_node_chunk = NULL;
static GNode *free_nodes = NULL;
static guint n_free_nodes = 0;
if (allocator->type != G_ALLOCATOR_NODE)
{
allocator->type = G_ALLOCATOR_NODE;
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 --- */
GNode*
g_node_new (gpointer data)
{
register GNode *node;
if (!g_tree_node_chunk)
g_tree_node_chunk = g_mem_chunk_create (GNode, 1024, G_ALLOC_AND_FREE);
if (n_free_nodes)
{
node = free_nodes;
free_nodes = free_nodes->next;
n_free_nodes--;
}
GNode *node;
if (!current_allocator)
g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
if (!current_allocator->free_nodes)
node = g_chunk_new (GNode, current_allocator->mem_chunk);
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->next = NULL;
@ -59,29 +108,23 @@ g_node_new (gpointer data)
}
static void
g_node_free (GNode *parent)
g_nodes_free (GNode *node)
{
GNode *node;
GNode *parent;
node = parent->children;
while (node)
parent = node;
while (1)
{
register GNode *free_node;
free_node = node;
node = free_node->next;
g_node_free (free_node);
if (parent->children)
g_nodes_free (parent->children);
if (parent->next)
parent = parent->next;
else
break;
}
if (n_free_nodes < KEEP_NODES)
{
parent->next = free_nodes;
free_nodes = parent;
n_free_nodes++;
}
else
g_chunk_free (parent, g_tree_node_chunk);
parent->next = current_allocator->free_nodes;
current_allocator->free_nodes = node;
}
void
@ -92,7 +135,7 @@ g_node_destroy (GNode *root)
if (!G_NODE_IS_ROOT (root))
g_node_unlink (root);
g_node_free (root);
g_nodes_free (root);
}
void

111
gslist.c
View File

@ -19,75 +19,103 @@
#include "glib.h"
typedef struct _GRealListAllocator GRealListAllocator;
struct _GRealListAllocator
struct _GAllocator /* from gmem.c */
{
GMemChunk *list_mem_chunk;
GSList *free_list;
gchar *name;
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;
static GRealListAllocator *current_allocator = NULL;
GListAllocator*
g_slist_set_allocator (GListAllocator* fallocator)
void
g_slist_push_allocator (GAllocator *allocator)
{
GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
GRealListAllocator* old_allocator = current_allocator;
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator)
current_allocator = allocator;
else
if (allocator->type != G_ALLOCATOR_SLIST)
{
if (!default_allocator)
default_allocator = (GRealListAllocator*) g_list_allocator_new ();
current_allocator = default_allocator;
allocator->type = G_ALLOCATOR_SLIST;
if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!current_allocator->list_mem_chunk)
current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
sizeof (GSList),
1024,
G_ALLOC_ONLY);
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GSList),
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*
g_slist_alloc (void)
{
GSList *new_list;
GSList *list;
g_slist_set_allocator (NULL);
if (current_allocator->free_list)
if (!current_allocator)
g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
if (!current_allocator->free_lists)
{
new_list = current_allocator->free_list;
current_allocator->free_list = current_allocator->free_list->next;
list = g_chunk_new (GSList, current_allocator->mem_chunk);
list->data = NULL;
}
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;
new_list->next = NULL;
return new_list;
return list;
}
void
g_slist_free (GSList *list)
{
GSList *last;
if (list)
{
last = g_slist_last (list);
last->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = list->next;
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
}
}
@ -96,8 +124,9 @@ g_slist_free_1 (GSList *list)
{
if (list)
{
list->next = current_allocator->free_list;
current_allocator->free_list = list;
list->data = NULL;
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)
{
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
g_free (tmp_list->data);
g_slist_free (chunk->storage_list);
g_slist_set_allocator (tmp_allocator);
}
if (chunk->const_table)
@ -134,7 +130,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
if ((chunk->storage_next + len + 1) > chunk->this_size)
{
GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
gint new_size = chunk->default_size;
while (new_size < len+1)
@ -145,8 +140,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
chunk->this_size = new_size;
chunk->storage_next = 0;
g_slist_set_allocator (tmp_allocator);
}
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 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*
@ -230,55 +274,6 @@ g_tree_nnodes (GTree *tree)
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*
g_tree_node_insert (GTreeNode *node,
GCompareFunc compare,
@ -352,7 +347,6 @@ g_tree_node_remove (GTreeNode *node,
GCompareFunc compare,
gpointer key)
{
GTreeNode *garbage;
GTreeNode *new_root;
gint old_balance;
gint cmp;
@ -363,6 +357,8 @@ g_tree_node_remove (GTreeNode *node,
cmp = (* compare) (key, node->key);
if (cmp == 0)
{
GTreeNode *garbage;
garbage = node;
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_free_list = g_slist_prepend (node_free_list, garbage);
garbage->right = node_free_list;
node_free_list = garbage;
}
else if (cmp < 0)
{