mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 10:16:17 +01:00
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:
parent
eabb208b30
commit
9c1692c260
18
ChangeLog
18
ChangeLog
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
102
gdataset.c
102
gdataset.c
@ -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
26
glib.h
@ -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
|
||||
|
102
glib/gdataset.c
102
glib/gdataset.c
@ -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/glib.h
26
glib/glib.h
@ -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
|
||||
|
140
glib/glist.c
140
glib/glist.c
@ -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
glib/gmem.c
46
glib/gmem.c
@ -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
glib/gnode.c
115
glib/gnode.c
@ -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
glib/gslist.c
111
glib/gslist.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
glib/gtree.c
101
glib/gtree.c
@ -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
140
glist.c
@ -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
46
gmem.c
@ -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
115
gnode.c
@ -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
111
gslist.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
101
gtree.c
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user