diff options
author | Tim Janik <timj@gtk.org> | 1999-07-24 18:50:58 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1999-07-24 18:50:58 +0000 |
commit | 87c7aeb93bd654776f59805a342ad913031034f3 (patch) | |
tree | 4f43e0cefcbe83a51ffe9aeb24f3386f519a071d /gqueue.c | |
parent | c8a28b935ca605ece11c65564ad1d3918786dd07 (diff) |
18:36. incorporated proposed cleanups from gtk-devel-list.
Sat Jul 24 20:11:35 1999 Tim Janik <timj@gtk.org>
* merged GLib 1.3.0 with glib-1.2.3 from Fri Jul 16 22:18:36.
* incorporated proposed cleanups from gtk-devel-list.
* bumped version number to GLib-1.3.1
* glib.h:
* gqueue.c:
* gstring.c:
* glist.c:
removed string tokenisation (we got g_strsplit() and g_strjoin()
already) and readline functions.
s/g_list_delete/g_list_delete_link.
implemented g_slist_delete_link.
removed notion of g_ATEXIT() macro in glib.h, this is an *internal*
macro, g_atexit() is provided for public consumption.
added GTrashStack inline utility functions.
reimplement double eneded queues.
removed GStack implementation, people can use a queue or a (singly)
linked list for this task.
deprecated g_strescape(), we need the SunOS variants here.
* gdate.c: added DEBUG_MSG() macro to wrap old messages.
* *.*: CVS merges.
* upgrade to libtool 1.3.3.
Diffstat (limited to 'gqueue.c')
-rw-r--r-- | gqueue.c | 262 |
1 files changed, 181 insertions, 81 deletions
@@ -1,5 +1,8 @@ /* GLIB - Library of useful routines for C programming - * Copyright (C) 1999 Free Software Foundation, Inc. + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GQueue: Double ended queue implementation, piggy backed on GList. + * Copyright (C) 1998 Tim Janik * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,138 +20,235 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe + */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif +#include "glib.h" -#include <glib.h> +G_LOCK_DEFINE_STATIC (queue_memchunk); +static GMemChunk *queue_memchunk = NULL; +static GTrashStack *free_queue_nodes = NULL; +GQueue* +g_queue_create (void) +{ + GQueue *queue; + G_LOCK (queue_memchunk); + queue = g_trash_stack_pop (&free_queue_nodes); -GQueue * -g_queue_new (void) -{ - GQueue *q = g_new (GQueue, 1); + if (!queue) + { + if (!queue_memchunk) + queue_memchunk = g_mem_chunk_new ("GLib GQueue chunk", + sizeof (GNode), + sizeof (GNode) * 128, + G_ALLOC_ONLY); + queue = g_chunk_new (GQueue, queue_memchunk); + } + G_UNLOCK (queue_memchunk); - q->list = q->list_end = NULL; - q->list_size = 0; + queue->head = NULL; + queue->tail = NULL; + queue->length = 0; - return q; + return queue; } - void -g_queue_free (GQueue *q) +g_queue_free (GQueue *queue) { - if (q) - { - if (q->list) - g_list_free (q->list); - g_free (q); - } -} + g_return_if_fail (queue != NULL); + g_list_free (queue->head); -guint -g_queue_get_size (GQueue *q) -{ - return (q == NULL) ? 0 : q->list_size; + G_LOCK (queue_memchunk); + g_trash_stack_push (&free_queue_nodes, queue); + G_UNLOCK (queue_memchunk); } - void -g_queue_push_front (GQueue *q, gpointer data) +g_queue_push_head (GQueue *queue, + gpointer data) { - if (q) - { - q->list = g_list_prepend (q->list, data); + g_return_if_fail (queue != NULL); - if (q->list_end == NULL) - q->list_end = q->list; + queue->head = g_list_prepend (queue->head, data); + if (!queue->tail) + queue->tail = queue->head; + queue->length++; +} - q->list_size++; - } +void +g_queue_push_head_link (GQueue *queue, + GList *link) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (link != NULL); + g_return_if_fail (link->prev != NULL); + g_return_if_fail (link->next != NULL); + + link->next = queue->head; + if (queue->head) + queue->head->prev = link; + else + queue->tail = link; + queue->head = link; + queue->length++; } +void +g_queue_push_tail (GQueue *queue, + gpointer data) +{ + g_return_if_fail (queue != NULL); + + queue->tail = g_list_append (queue->tail, data); + if (queue->tail->next) + queue->tail = queue->tail->next; + else + queue->head = queue->tail; + queue->length++; +} void -g_queue_push_back (GQueue *q, gpointer data) +g_queue_push_tail_link (GQueue *queue, + GList *link) { - if (q) + g_return_if_fail (queue != NULL); + g_return_if_fail (link != NULL); + g_return_if_fail (link->prev != NULL); + g_return_if_fail (link->next != NULL); + + link->prev = queue->tail; + if (queue->tail) + queue->tail->next = link; + else + queue->head = link; + queue->tail = link; + queue->length++; +} + +gpointer +g_queue_pop_head (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + if (queue->head) { - q->list_end = g_list_append (q->list_end, data); + GList *node = queue->head; + gpointer data = node->data; - if (! q->list) - q->list = q->list_end; + queue->head = node->next; + if (queue->head) + queue->head->prev = NULL; else - q->list_end = q->list_end->next; + queue->tail = NULL; + g_list_free_1 (node); + queue->length--; - q->list_size++; + return data; } -} + return NULL; +} -gpointer -g_queue_pop_front (GQueue *q) +GList* +g_queue_pop_head_link (GQueue *queue) { - gpointer data = NULL; + g_return_val_if_fail (queue != NULL, NULL); - if ((q) && (q->list)) + if (queue->head) { - GList *node; + GList *node = queue->head; - node = q->list; - data = node->data; - - if (! node->next) - { - q->list = q->list_end = NULL; - q->list_size = 0; - } + queue->head = node->next; + if (queue->head) + { + queue->head->prev = NULL; + node->next = NULL; + } else - { - q->list = node->next; - q->list->prev = NULL; - q->list_size--; - } + queue->tail = NULL; + queue->length--; - g_list_free_1 (node); + return node; } - return data; + return NULL; } - gpointer -g_queue_pop_back (GQueue *q) +g_queue_pop_tail (GQueue *queue) { - gpointer data = NULL; + g_return_val_if_fail (queue != NULL, NULL); - if ((q) && (q->list)) + if (queue->tail) { - GList *node; + GList *node = queue->tail; + gpointer data = node->data; + + queue->tail = node->prev; + if (queue->tail) + queue->tail->next = NULL; + else + queue->head = NULL; + queue->length--; + g_list_free_1 (node); - node = q->list_end; - data = node->data; + return data; + } + + return NULL; +} - if (! node->prev) +GList* +g_queue_pop_tail_link (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + if (queue->tail) + { + GList *node = queue->tail; + + queue->tail = node->prev; + if (queue->tail) { - q->list = q->list_end = NULL; - q->list_size = 0; - } + queue->tail->next = NULL; + node->prev = NULL; + } else - { - q->list_end = node->prev; - q->list_end->next = NULL; - q->list_size--; - } - - g_list_free_1 (node); + queue->head = NULL; + queue->length--; + + return node; } + + return NULL; +} - return data; +gboolean +g_queue_is_empty (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, TRUE); + + return queue->head == NULL; } +gpointer +g_queue_peek_head (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + return queue->head ? queue->head->data : NULL; +} + +gpointer +g_queue_peek_tail (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return queue->tail ? queue->tail->data : NULL; +} |