This commit is contained in:
2008-08-13 07:58:57 +00:00
parent 4793f1efdf
commit 002a9d1913
8 changed files with 484 additions and 19 deletions

221
ase/lib/cmn/dll.c Normal file
View File

@ -0,0 +1,221 @@
/*
* $Id$
*
* {License}
*/
#include <ase/cmn/dll.h>
#include "mem.h"
void* ase_dll_copyinline (ase_dll_t* dll, void* dptr, ase_size_t dlen)
{
/* this is a dummy copier */
return ASE_NULL;
}
ase_dll_t* ase_dll_open (ase_mmgr_t* mmgr)
{
return ase_dll_openx (mmgr, 0, ASE_NULL);
}
ase_dll_t* ase_dll_openx (ase_mmgr_t* mmgr, ase_size_t extension, ase_fuser_t fuser)
{
ase_dll_t* dll;
dll = ASE_MALLOC (mmgr, ASE_SIZEOF(ase_dll_t) + extension);
if (dll == ASE_NULL) return ASE_NULL;
ASE_MEMSET (dll, 0, ASE_SIZEOF(ase_dll_t) + extension);
if (fuser != ASE_NULL) mmgr = fuser (mmgr, dll + 1);
dll->mmgr = mmgr;
return dll;
}
void ase_dll_close (ase_dll_t* dll)
{
ase_dll_clear (dll);
ASE_FREE (dll->mmgr, dll);
}
void ase_dll_clear (ase_dll_t* dll)
{
while (dll->head != ASE_NULL) ase_dll_delete (dll, dll->head);
ASE_ASSERT (dll->tail == ASE_NULL);
}
void* ase_dll_getextension (ase_dll_t* dll)
{
return dll + 1;
}
ase_size_t ase_dll_getsize (ase_dll_t* dll)
{
return dll->size;
}
ase_dll_node_t* ase_dll_gethead (ase_dll_t* dll)
{
return dll->head;
}
ase_dll_node_t* ase_dll_gettail (ase_dll_t* dll)
{
return dll->tail;
}
ase_dll_copier_t ase_dll_getcopier (ase_dll_t* dll)
{
return dll->copier;
}
void ase_dll_setcopier (ase_dll_t* dll, ase_dll_copier_t copier)
{
dll->copier = copier;
}
ase_dll_freeer_t ase_dll_getfreeer (ase_dll_t* dll)
{
return dll->freeer;
}
void ase_dll_setfreeer (ase_dll_t* dll, ase_dll_freeer_t freeer)
{
dll->freeer = freeer;
}
static ase_dll_node_t* alloc_node (ase_dll_t* dll, void* dptr, ase_size_t dlen)
{
ase_dll_node_t* n;
if (dll->copier == ASE_NULL)
{
n = ASE_MALLOC (dll->mmgr, ASE_SIZEOF(ase_dll_node_t));
if (n == ASE_NULL) return ASE_NULL;
n->dptr = dptr;
}
else if (dll->copier == ASE_DLL_COPIER_INLINE)
{
n = ASE_MALLOC (dll->mmgr, ASE_SIZEOF(ase_dll_node_t) + dlen);
if (n == ASE_NULL) return ASE_NULL;
ASE_MEMCPY (n + 1, dptr, dlen);
n->dptr = n + 1;
}
else
{
n = ASE_MALLOC (dll->mmgr, ASE_SIZEOF(ase_dll_node_t));
if (n == ASE_NULL) return ASE_NULL;
n->dptr = dll->copier (dll, dptr, dlen);
}
n->dlen = dlen;
n->next = ASE_NULL;
n->prev = ASE_NULL;
return n;
}
ase_dll_node_t* ase_dll_insert (
ase_dll_t* dll, ase_dll_node_t* pos, void* dptr, ase_size_t dlen)
{
ase_dll_node_t* n = alloc_node (dll, dptr, dlen);
if (n == ASE_NULL) return ASE_NULL;
if (pos == ASE_NULL)
{
/* insert at the end */
if (dll->head == ASE_NULL)
{
ASE_ASSERT (dll->tail == ASE_NULL);
dll->head = n;
}
else dll->tail->next = n;
dll->tail = n;
}
else
{
/* insert in front of the positional node */
n->next = pos;
if (pos == dll->head) dll->head = n;
else
{
/* take note of performance penalty */
ase_dll_node_t* n2 = dll->head;
while (n2->next != pos) n2 = n2->next;
n2->next = n;
}
}
dll->size++;
return n;
}
ase_dll_node_t* ase_dll_pushhead (ase_dll_t* dll, void* data, ase_size_t size)
{
return ase_dll_insert (dll, dll->head, data, size);
}
ase_dll_node_t* ase_dll_pushtail (ase_dll_t* dll, void* data, ase_size_t size)
{
return ase_dll_insert (dll, ASE_NULL, data, size);
}
void ase_dll_delete (ase_dll_t* dll, ase_dll_node_t* pos)
{
if (pos == ASE_NULL) return; /* not a valid node */
if (pos == dll->head)
{
/* it is simple to delete the head node */
dll->head = pos->next;
if (dll->head == ASE_NULL) dll->tail = ASE_NULL;
}
else
{
/* but deletion of other nodes has significant performance
* penalty as it has look for the predecessor of the
* target node */
ase_dll_node_t* n2 = dll->head;
while (n2->next != pos) n2 = n2->next;
n2->next = pos->next;
/* update the tail node if necessary */
if (pos == dll->tail) dll->tail = n2;
}
if (dll->freeer != ASE_NULL)
{
/* free the actual data */
dll->freeer (dll, pos->dptr, pos->dlen);
}
/* free the node */
ASE_FREE (dll->mmgr, pos);
/* decrement the number of elements */
dll->size--;
}
void ase_dll_pophead (ase_dll_t* dll)
{
ase_dll_delete (dll, dll->head);
}
void ase_dll_poptail (ase_dll_t* dll)
{
ase_dll_delete (dll, dll->tail);
}
void ase_dll_walk (ase_dll_t* dll, ase_dll_walker_t walker, void* arg)
{
ase_dll_node_t* n = dll->head;
while (n != ASE_NULL)
{
if (walker(dll,n,arg) == ASE_DLL_WALK_STOP) return;
n = n->next;
}
}

View File

@ -4,6 +4,6 @@ AM_CFLAGS = -I$(top_builddir)/include
lib_LTLIBRARIES = libasecmn.la
libasecmn_la_SOURCES = mem.h \
map.c mem.c misc.c rex.c str_bas.c str_cnv.c str_dyn.c sll.c
map.c mem.c misc.c rex.c str_bas.c str_cnv.c str_dyn.c sll.c dll.c
libasecmn_la_LDFLAGS = -version-info 1:0:0

View File

@ -56,7 +56,7 @@ libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libasecmn_la_LIBADD =
am_libasecmn_la_OBJECTS = map.lo mem.lo misc.lo rex.lo str_bas.lo \
str_cnv.lo str_dyn.lo sll.lo
str_cnv.lo str_dyn.lo sll.lo dll.lo
libasecmn_la_OBJECTS = $(am_libasecmn_la_OBJECTS)
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp
@ -196,7 +196,7 @@ AUTOMAKE_OPTIONS = nostdinc
AM_CFLAGS = -I$(top_builddir)/include
lib_LTLIBRARIES = libasecmn.la
libasecmn_la_SOURCES = mem.h \
map.c mem.c misc.c rex.c str_bas.c str_cnv.c str_dyn.c sll.c
map.c mem.c misc.c rex.c str_bas.c str_cnv.c str_dyn.c sll.c dll.c
libasecmn_la_LDFLAGS = -version-info 1:0:0
all: all-am
@ -268,6 +268,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@

View File

@ -92,7 +92,7 @@ static ase_sll_node_t* alloc_node (ase_sll_t* sll, void* dptr, ase_size_t dlen)
{
n = ASE_MALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
if (n == ASE_NULL) return ASE_NULL;
n->data.ptr = dptr;
n->dptr = dptr;
}
else if (sll->copier == ASE_SLL_COPIER_INLINE)
{
@ -100,16 +100,16 @@ static ase_sll_node_t* alloc_node (ase_sll_t* sll, void* dptr, ase_size_t dlen)
if (n == ASE_NULL) return ASE_NULL;
ASE_MEMCPY (n + 1, dptr, dlen);
n->data.ptr = n + 1;
n->dptr = n + 1;
}
else
{
n = ASE_MALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
if (n == ASE_NULL) return ASE_NULL;
n->data.ptr = sll->copier (sll, dptr, dlen);
n->dptr = sll->copier (sll, dptr, dlen);
}
n->data.len = dlen;
n->dlen = dlen;
n->next = ASE_NULL;
return n;
@ -188,7 +188,7 @@ void ase_sll_delete (ase_sll_t* sll, ase_sll_node_t* pos)
if (sll->freeer != ASE_NULL)
{
/* free the actual data */
sll->freeer (sll, pos->data.ptr, pos->data.len);
sll->freeer (sll, pos->dptr, pos->dlen);
}
/* free the node */