This commit is contained in:
parent
b6d38c892a
commit
0590924941
@ -92,8 +92,8 @@ extern "C" {
|
|||||||
|
|
||||||
ase_dll_t* ase_dll_open (
|
ase_dll_t* ase_dll_open (
|
||||||
ase_mmgr_t* mmgr /* memory manager */ ,
|
ase_mmgr_t* mmgr /* memory manager */ ,
|
||||||
ase_size_t extension /* size of extension area in bytes */,
|
ase_size_t ext /* size of extension area in bytes */,
|
||||||
void (*initializer) (ase_dll_t*) /* extension initializer */
|
void (*init) (ase_dll_t*) /* extension initializer */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: map.h 344 2008-08-22 15:23:09Z baconevi $
|
* $Id: map.h 345 2008-08-26 08:50:12Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -43,11 +43,11 @@ typedef int (*ase_map_comper_t) (
|
|||||||
ase_size_t klen2 /* the length of a key in bytes */
|
ase_size_t klen2 /* the length of a key in bytes */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* pair visitor */
|
/* pair visitor - should return ASE_MAP_WALK_STOP or ASE_MAP_WALK_FORWARD */
|
||||||
typedef int (*ase_map_walker_t) (
|
typedef int (*ase_map_walker_t) (
|
||||||
ase_map_t* map,
|
ase_map_t* map /* a map */,
|
||||||
ase_map_pair_t* pair,
|
ase_map_pair_t* pair /* the pointer to a key/value pair */,
|
||||||
void* arg
|
void* arg /* the pointer to user-defined data */
|
||||||
);
|
);
|
||||||
|
|
||||||
struct ase_map_pair_t
|
struct ase_map_pair_t
|
||||||
@ -62,7 +62,7 @@ struct ase_map_pair_t
|
|||||||
ase_map_pair_t* next;
|
ase_map_pair_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ase_map_id_t
|
enum ase_map_id_t
|
||||||
{
|
{
|
||||||
ASE_MAP_KEY = 0,
|
ASE_MAP_KEY = 0,
|
||||||
ASE_MAP_VAL = 1
|
ASE_MAP_VAL = 1
|
||||||
@ -85,12 +85,16 @@ struct ase_map_t
|
|||||||
|
|
||||||
ase_map_pair_t** buck;
|
ase_map_pair_t** buck;
|
||||||
|
|
||||||
/*
|
|
||||||
void (*freeval) (void* owner,void* val);
|
|
||||||
*/
|
|
||||||
void (*sameval) (void* owner, void* vptr, ase_size_t vlen);
|
void (*sameval) (void* owner, void* vptr, ase_size_t vlen);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* values that can be returned by ase_map_walker_t */
|
||||||
|
enum ase_map_walk_t
|
||||||
|
{
|
||||||
|
ASE_MAP_WALK_STOP = 0,
|
||||||
|
ASE_MAP_WALK_FORWARD = 1
|
||||||
|
};
|
||||||
|
|
||||||
#define ASE_MAP_COPIER_INLINE ase_map_copyinline
|
#define ASE_MAP_COPIER_INLINE ase_map_copyinline
|
||||||
|
|
||||||
#define ASE_MAP_KPTR(p) ((p)->kptr)
|
#define ASE_MAP_KPTR(p) ((p)->kptr)
|
||||||
@ -104,14 +108,12 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates a hashed map with a dynamic array bucket and a list of values linked
|
* NAME: create a map
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
* The ase_map_open() function creates a hashed map with a dynamic array
|
||||||
|
* bucket and a list of values linked.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
ase_map_t* ase_map_open (
|
|
||||||
void* owner, ase_size_t capa, unsigned int factor,
|
|
||||||
void(*freeval)(void*,void*), void(*sameval)(void*,void*),
|
|
||||||
ase_mmgr_t* mmgr);
|
|
||||||
*/
|
|
||||||
ase_map_t* ase_map_open (
|
ase_map_t* ase_map_open (
|
||||||
ase_mmgr_t* mmgr,
|
ase_mmgr_t* mmgr,
|
||||||
ase_size_t ext,
|
ase_size_t ext,
|
||||||
@ -119,30 +121,109 @@ ase_map_t* ase_map_open (
|
|||||||
);
|
);
|
||||||
|
|
||||||
/* destroy a map */
|
/* destroy a map */
|
||||||
void ase_map_close (ase_map_t* map);
|
void ase_map_close (
|
||||||
|
ase_map_t* map /* a map */
|
||||||
|
);
|
||||||
|
|
||||||
/* clear a map */
|
/* clear a map */
|
||||||
void ase_map_clear (ase_map_t* map);
|
void ase_map_clear (
|
||||||
|
ase_map_t* map /* a map */
|
||||||
|
);
|
||||||
|
|
||||||
/* get the number of key/value pairs in a map
|
/*
|
||||||
ase_size_t ase_map_getsize (ase_map_t* map);
|
* NAME: specifies how to clone an element
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
* A special copier ASE_MAP_COPIER_INLINE is provided. This copier enables
|
||||||
|
* you to copy the data inline to the internal node. No freeer is invoked
|
||||||
|
* when the node is freeed.
|
||||||
|
*
|
||||||
|
* You may set the copier to ASE_NULL to perform no special operation
|
||||||
|
* when the data pointer is rememebered.
|
||||||
|
*/
|
||||||
|
void ase_map_setcopier (
|
||||||
|
ase_map_t* map /* a map */,
|
||||||
|
int id /* ASE_MAP_KEY or ASE_MAP_VAL */,
|
||||||
|
ase_map_copier_t copier /* a element copier */
|
||||||
|
);
|
||||||
|
|
||||||
ase_map_pair_t* ase_map_get (
|
ase_map_copier_t ase_map_getcopier (
|
||||||
|
ase_map_t* map /* a map */,
|
||||||
|
int id /* ASE_MAP_KEY or ASE_MAP_VAL */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME: specifies how to destroy an element
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The freeer is called when a node containing the element is destroyed.
|
||||||
|
*/
|
||||||
|
void ase_map_setfreeer (
|
||||||
|
ase_map_t* map /* a map */,
|
||||||
|
int id /* ASE_MAP_KEY or ASE_MAP_VAL */,
|
||||||
|
ase_map_freeer_t freeer /* a element freeer */
|
||||||
|
);
|
||||||
|
|
||||||
|
ase_map_freeer_t ase_map_getfreeer (
|
||||||
|
ase_map_t* map /* a map */,
|
||||||
|
int id /* ASE_MAP_KEY or ASE_MAP_VAL */
|
||||||
|
);
|
||||||
|
|
||||||
|
ase_map_hasher_t ase_map_gethasher (
|
||||||
|
ase_map_t* map
|
||||||
|
);
|
||||||
|
|
||||||
|
void ase_map_sethasher (
|
||||||
ase_map_t* map,
|
ase_map_t* map,
|
||||||
|
ase_map_hasher_t hasher
|
||||||
|
);
|
||||||
|
|
||||||
|
ase_map_comper_t ase_map_getcomper (
|
||||||
|
ase_map_t* map
|
||||||
|
);
|
||||||
|
|
||||||
|
void ase_map_setcomper (
|
||||||
|
ase_map_t* map,
|
||||||
|
ase_map_comper_t comper
|
||||||
|
);
|
||||||
|
|
||||||
|
void* ase_map_getextension (
|
||||||
|
ase_map_t* map
|
||||||
|
);
|
||||||
|
|
||||||
|
ase_mmgr_t* ase_map_getmmgr (
|
||||||
|
ase_map_t* map
|
||||||
|
);
|
||||||
|
|
||||||
|
void ase_map_setmmgr (
|
||||||
|
ase_map_t* map,
|
||||||
|
ase_mmgr_t* mmgr
|
||||||
|
);
|
||||||
|
|
||||||
|
/* get the number of key/value pairs in a map */
|
||||||
|
ase_size_t ase_map_getsize (
|
||||||
|
ase_map_t* map /* a map */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* get the pointer to the pair with a matching key */
|
||||||
|
ase_map_pair_t* ase_map_get (
|
||||||
|
ase_map_t* map /* a map */,
|
||||||
const void* kptr,
|
const void* kptr,
|
||||||
ase_size_t klen
|
ase_size_t klen
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* insert or update a pair with a matching key */
|
||||||
ase_map_pair_t* ase_map_put (
|
ase_map_pair_t* ase_map_put (
|
||||||
ase_map_t* map,
|
ase_map_t* map /* a map */,
|
||||||
const void* kptr,
|
void* kptr /* the pointer to the beginning of a key */,
|
||||||
ase_size_t klen,
|
ase_size_t klen /* the length of the key in bytes */,
|
||||||
void* vptr,
|
void* vptr /* the pointer to the beginning of a value */,
|
||||||
ase_size_t vlen
|
ase_size_t vlen /* the length of the value in bytes */
|
||||||
);
|
);
|
||||||
|
|
||||||
int ase_map_putx (
|
int ase_map_putx (
|
||||||
ase_map_t* map,
|
ase_map_t* map /* a map */,
|
||||||
void* kptr,
|
void* kptr,
|
||||||
ase_size_t klen,
|
ase_size_t klen,
|
||||||
void* vptr,
|
void* vptr,
|
||||||
@ -151,25 +232,39 @@ int ase_map_putx (
|
|||||||
);
|
);
|
||||||
|
|
||||||
ase_map_pair_t* ase_map_set (
|
ase_map_pair_t* ase_map_set (
|
||||||
ase_map_t* map,
|
ase_map_t* map /* a map */,
|
||||||
void* kptr,
|
void* kptr,
|
||||||
ase_size_t klen,
|
ase_size_t klen,
|
||||||
void* vptr,
|
void* vptr,
|
||||||
ase_size_t vlen
|
ase_size_t vlen
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* remove a pair with a matching key */
|
||||||
int ase_map_remove (
|
int ase_map_remove (
|
||||||
ase_map_t* map, const void* kptr, ase_size_t klen);
|
ase_map_t* map /* a map */,
|
||||||
|
const void* kptr,
|
||||||
|
ase_size_t klen
|
||||||
|
);
|
||||||
|
|
||||||
/* traverse a map */
|
/* traverse a map */
|
||||||
int ase_map_walk (ase_map_t* map, ase_map_walker_t walker, void* arg);
|
void ase_map_walk (
|
||||||
|
ase_map_t* map /* a map */,
|
||||||
|
ase_map_walker_t walker /* the pointer to the function for each pair */,
|
||||||
|
void* arg /* a pointer to user-specific data */
|
||||||
|
);
|
||||||
|
|
||||||
/* get the pointer to the first pair in the map. */
|
/* get the pointer to the first pair in the map. */
|
||||||
ase_map_pair_t* ase_map_getfirstpair (ase_map_t* map, ase_size_t* buckno);
|
ase_map_pair_t* ase_map_getfirstpair (
|
||||||
|
ase_map_t* map /* a map */,
|
||||||
|
ase_size_t* buckno
|
||||||
|
);
|
||||||
|
|
||||||
/* get the pointer to the next pair in the map. */
|
/* get the pointer to the next pair in the map. */
|
||||||
ase_map_pair_t* ase_map_getnextpair (
|
ase_map_pair_t* ase_map_getnextpair (
|
||||||
ase_map_t* map, ase_map_pair_t* pair, ase_size_t* buckno);
|
ase_map_t* map /* a map */,
|
||||||
|
ase_map_pair_t* pair,
|
||||||
|
ase_size_t* buckno
|
||||||
|
);
|
||||||
|
|
||||||
void* ase_map_copyinline (ase_map_t* map, void* dptr, ase_size_t dlen);
|
void* ase_map_copyinline (ase_map_t* map, void* dptr, ase_size_t dlen);
|
||||||
|
|
||||||
|
@ -91,8 +91,8 @@ extern "C" {
|
|||||||
|
|
||||||
ase_sll_t* ase_sll_open (
|
ase_sll_t* ase_sll_open (
|
||||||
ase_mmgr_t* mmgr /* memory manager */ ,
|
ase_mmgr_t* mmgr /* memory manager */ ,
|
||||||
ase_size_t extension /* size of extension area in bytes */,
|
ase_size_t ext /* size of extension area in bytes */,
|
||||||
void (*initializer) (ase_sll_t*) /* extension initializer */
|
void (*init) (ase_sll_t*) /* extension initializer */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -112,7 +112,7 @@ void ase_sll_clear (
|
|||||||
/*
|
/*
|
||||||
* NAME: specifies how to clone an element
|
* NAME: specifies how to clone an element
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION:
|
||||||
* A special copier ASE_SLL_COPIER_INLINE is provided. This copier enables
|
* A special copier ASE_SLL_COPIER_INLINE is provided. This copier enables
|
||||||
* you to copy the data inline to the internal node. No freeer is invoked
|
* you to copy the data inline to the internal node. No freeer is invoked
|
||||||
* when the node is freeed.
|
* when the node is freeed.
|
||||||
|
@ -10,10 +10,40 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
static ase_bool_t is_upper (ase_cint_t c) { return isupper(c); }
|
||||||
|
static ase_bool_t is_lower (ase_cint_t c) { return islower(c); }
|
||||||
|
static ase_bool_t is_alpha (ase_cint_t c) { return isalpha(c); }
|
||||||
|
static ase_bool_t is_digit (ase_cint_t c) { return isdigit(c); }
|
||||||
|
static ase_bool_t is_xdigit (ase_cint_t c) { return isxdigit(c); }
|
||||||
|
static ase_bool_t is_alnum (ase_cint_t c) { return isalnum(c); }
|
||||||
|
static ase_bool_t is_space (ase_cint_t c) { return isspace(c); }
|
||||||
|
static ase_bool_t is_print (ase_cint_t c) { return isprint(c); }
|
||||||
|
static ase_bool_t is_graph (ase_cint_t c) { return isgraph(c); }
|
||||||
|
static ase_bool_t is_cntrl (ase_cint_t c) { return iscntrl(c); }
|
||||||
|
static ase_bool_t is_punct (ase_cint_t c) { return ispunct(c); }
|
||||||
|
|
||||||
ase_bool_t ase_ccls_is (ase_cint_t c, int type)
|
ase_bool_t ase_ccls_is (ase_cint_t c, int type)
|
||||||
{
|
{
|
||||||
/* TODO: use GetStringTypeW/A for WIN32 to implement these */
|
/* TODO: use GetStringTypeW/A for WIN32 to implement these */
|
||||||
#error NOT IMPLEMENTED YET.
|
|
||||||
|
static ase_bool_t (*f[]) (ase_cint_t) =
|
||||||
|
{
|
||||||
|
is_upper,
|
||||||
|
is_lower,
|
||||||
|
is_alpha,
|
||||||
|
is_digit,
|
||||||
|
is_xdigit,
|
||||||
|
is_alnum,
|
||||||
|
is_space,
|
||||||
|
is_print,
|
||||||
|
is_graph,
|
||||||
|
is_cntrl,
|
||||||
|
is_punct
|
||||||
|
};
|
||||||
|
|
||||||
|
ASE_ASSERTX (type >= ASE_CCLS_UPPER && type <= ASE_CCLS_PUNCT,
|
||||||
|
"The character type should be one of ase_ccls_type_t values");
|
||||||
|
return f[type] (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_cint_t ase_ccls_to (ase_cint_t c, int type)
|
ase_cint_t ase_ccls_to (ase_cint_t c, int type)
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
ase_dll_t* ase_dll_open (
|
ase_dll_t* ase_dll_open (
|
||||||
ase_mmgr_t* mmgr, ase_size_t extension,
|
ase_mmgr_t* mmgr, ase_size_t ext, void (*init) (ase_dll_t*))
|
||||||
void (*initializer) (ase_dll_t*))
|
|
||||||
{
|
{
|
||||||
ase_dll_t* dll;
|
ase_dll_t* dll;
|
||||||
|
|
||||||
@ -23,13 +22,13 @@ ase_dll_t* ase_dll_open (
|
|||||||
if (mmgr == ASE_NULL) return ASE_NULL;
|
if (mmgr == ASE_NULL) return ASE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_dll_t) + extension);
|
dll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_dll_t) + ext);
|
||||||
if (dll == ASE_NULL) return ASE_NULL;
|
if (dll == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
ASE_MEMSET (dll, 0, ASE_SIZEOF(ase_dll_t) + extension);
|
ASE_MEMSET (dll, 0, ASE_SIZEOF(ase_dll_t) + ext);
|
||||||
dll->mmgr = mmgr;
|
dll->mmgr = mmgr;
|
||||||
|
|
||||||
if (initializer) initializer (dll);
|
if (init) init (dll);
|
||||||
|
|
||||||
return dll;
|
return dll;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: map.c 344 2008-08-22 15:23:09Z baconevi $
|
* $Id: map.c 345 2008-08-26 08:50:12Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -216,6 +216,34 @@ map_t* ase_map_open (mmgr_t* mmgr, size_t ext, void (*init) (map_t*))
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ase_map_close (map_t* map)
|
||||||
|
{
|
||||||
|
ase_map_clear (map);
|
||||||
|
ASE_MMGR_FREE (map->mmgr, map->buck);
|
||||||
|
ASE_MMGR_FREE (map->mmgr, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ase_map_clear (map_t* map)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
pair_t* pair, * next;
|
||||||
|
|
||||||
|
for (i = 0; i < map->capa; i++)
|
||||||
|
{
|
||||||
|
pair = map->buck[i];
|
||||||
|
|
||||||
|
while (pair != ASE_NULL)
|
||||||
|
{
|
||||||
|
next = ASE_MAP_NEXT(pair);
|
||||||
|
free_pair (map, pair);
|
||||||
|
map->size--;
|
||||||
|
pair = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
map->buck[i] = ASE_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
copier_t ase_map_getcopier (map_t* map, int id)
|
copier_t ase_map_getcopier (map_t* map, int id)
|
||||||
{
|
{
|
||||||
ASE_ASSERTX (id == ASE_MAP_KEY || id == ASE_MAP_VAL,
|
ASE_ASSERTX (id == ASE_MAP_KEY || id == ASE_MAP_VAL,
|
||||||
@ -279,34 +307,6 @@ void ase_map_setmmgr (map_t* map, mmgr_t* mmgr)
|
|||||||
map->mmgr = mmgr;
|
map->mmgr = mmgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_map_close (map_t* map)
|
|
||||||
{
|
|
||||||
ase_map_clear (map);
|
|
||||||
ASE_MMGR_FREE (map->mmgr, map->buck);
|
|
||||||
ASE_MMGR_FREE (map->mmgr, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ase_map_clear (map_t* map)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
pair_t* pair, * next;
|
|
||||||
|
|
||||||
for (i = 0; i < map->capa; i++)
|
|
||||||
{
|
|
||||||
pair = map->buck[i];
|
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
|
||||||
{
|
|
||||||
next = ASE_MAP_NEXT(pair);
|
|
||||||
free_pair (map, pair);
|
|
||||||
map->size--;
|
|
||||||
pair = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
map->buck[i] = ASE_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ase_map_getsize (map_t* map)
|
size_t ase_map_getsize (map_t* map)
|
||||||
{
|
{
|
||||||
return map->size;
|
return map->size;
|
||||||
@ -323,9 +323,10 @@ pair_t* ase_map_get (
|
|||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
if (map->comper (map,
|
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||||
KPTR(pair), KLEN(pair),
|
{
|
||||||
kptr, klen) == 0) return pair;
|
return pair;
|
||||||
|
}
|
||||||
|
|
||||||
pair = ASE_MAP_NEXT(pair);
|
pair = ASE_MAP_NEXT(pair);
|
||||||
}
|
}
|
||||||
@ -358,9 +359,7 @@ int ase_map_putx (
|
|||||||
{
|
{
|
||||||
next = ASE_MAP_NEXT(pair);
|
next = ASE_MAP_NEXT(pair);
|
||||||
|
|
||||||
if (map->comper (map,
|
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||||
KPTR(pair), KLEN(pair),
|
|
||||||
kptr, klen) == 0)
|
|
||||||
{
|
{
|
||||||
p = change_pair_val (map, pair, vptr, vlen);
|
p = change_pair_val (map, pair, vptr, vlen);
|
||||||
if (p == ASE_NULL) return -1; /* change error */
|
if (p == ASE_NULL) return -1; /* change error */
|
||||||
@ -427,9 +426,7 @@ pair_t* ase_map_set (map_t* map,
|
|||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
if (map->comper (map,
|
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||||
KPTR(pair), KLEN(pair),
|
|
||||||
kptr, klen) == 0)
|
|
||||||
{
|
{
|
||||||
/*TODO: this is wrong... change code .... same way as putx... */
|
/*TODO: this is wrong... change code .... same way as putx... */
|
||||||
return change_pair_val (map, pair, vptr, vlen);
|
return change_pair_val (map, pair, vptr, vlen);
|
||||||
@ -440,22 +437,6 @@ pair_t* ase_map_set (map_t* map,
|
|||||||
return ASE_NULL;
|
return ASE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
pair_t* ase_map_getpair (
|
|
||||||
map_t* map, const void* kptr, size_t klen,
|
|
||||||
void** val, size_t* vptr)
|
|
||||||
{
|
|
||||||
pair_t* pair;
|
|
||||||
|
|
||||||
pair = ase_map_get (map, kptr, klen);
|
|
||||||
if (pair == ASE_NULL) return ASE_NULL;
|
|
||||||
if (val) *val = VPTR(pair);
|
|
||||||
if (vptr) *vptr = VLEN(pair);
|
|
||||||
|
|
||||||
return pair;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ase_map_remove (
|
int ase_map_remove (
|
||||||
map_t* map, const void* kptr, size_t klen)
|
map_t* map, const void* kptr, size_t klen)
|
||||||
{
|
{
|
||||||
@ -468,9 +449,7 @@ int ase_map_remove (
|
|||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
if (map->comper (map,
|
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||||
KPTR(pair), KLEN(pair),
|
|
||||||
kptr, klen) == 0)
|
|
||||||
{
|
{
|
||||||
if (prev == ASE_NULL)
|
if (prev == ASE_NULL)
|
||||||
map->buck[hc] = ASE_MAP_NEXT(pair);
|
map->buck[hc] = ASE_MAP_NEXT(pair);
|
||||||
@ -489,7 +468,7 @@ int ase_map_remove (
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ase_map_walk (map_t* map, walker_t walker, void* arg)
|
void ase_map_walk (map_t* map, walker_t walker, void* arg)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
pair_t* pair, * next;
|
pair_t* pair, * next;
|
||||||
@ -501,13 +480,10 @@ int ase_map_walk (map_t* map, walker_t walker, void* arg)
|
|||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
next = ASE_MAP_NEXT(pair);
|
next = ASE_MAP_NEXT(pair);
|
||||||
/* TODO: ASE_MAP_WALK_STOP ASE_MAP_WALK_FORWARD */
|
if (walker(map, pair, arg) == ASE_MAP_WALK_STOP) return;
|
||||||
if (walker(map, pair, arg) == -1) return -1;
|
|
||||||
pair = next;
|
pair = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pair_t* ase_map_getfirstpair (map_t* map, size_t* buckno)
|
pair_t* ase_map_getfirstpair (map_t* map, size_t* buckno)
|
||||||
|
@ -7,11 +7,26 @@
|
|||||||
#include <ase/cmn/sll.h>
|
#include <ase/cmn/sll.h>
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
ase_sll_t* ase_sll_open (
|
#define sll_t ase_sll_t
|
||||||
ase_mmgr_t* mmgr, ase_size_t extension,
|
#define node_t ase_sll_node_t
|
||||||
void (*initializer) (ase_sll_t*))
|
#define copier_t ase_sll_copier_t
|
||||||
|
#define freeer_t ase_sll_freeer_t
|
||||||
|
#define walker_t ase_sll_walker_t
|
||||||
|
|
||||||
|
#define HEAD(s) ASE_SLL_HEAD(s)
|
||||||
|
#define TAIL(s) ASE_SLL_TAIL(s)
|
||||||
|
#define SIZE(s) ASE_SLL_SIZE(s)
|
||||||
|
|
||||||
|
#define DPTR(n) ASE_SLL_DPTR(n)
|
||||||
|
#define DLEN(n) ASE_SLL_DLEN(n)
|
||||||
|
#define NEXT(n) ASE_SLL_NEXT(n)
|
||||||
|
|
||||||
|
#define size_t ase_size_t
|
||||||
|
#define mmgr_t ase_mmgr_t
|
||||||
|
|
||||||
|
sll_t* ase_sll_open (mmgr_t* mmgr, size_t ext, void (*init) (sll_t*))
|
||||||
{
|
{
|
||||||
ase_sll_t* sll;
|
sll_t* sll;
|
||||||
|
|
||||||
if (mmgr == ASE_NULL)
|
if (mmgr == ASE_NULL)
|
||||||
{
|
{
|
||||||
@ -23,220 +38,220 @@ ase_sll_t* ase_sll_open (
|
|||||||
if (mmgr == ASE_NULL) return ASE_NULL;
|
if (mmgr == ASE_NULL) return ASE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_sll_t) + extension);
|
sll = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(sll_t) + ext);
|
||||||
if (sll == ASE_NULL) return ASE_NULL;
|
if (sll == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
ASE_MEMSET (sll, 0, ASE_SIZEOF(ase_sll_t) + extension);
|
ASE_MEMSET (sll, 0, ASE_SIZEOF(sll_t) + ext);
|
||||||
sll->mmgr = mmgr;
|
sll->mmgr = mmgr;
|
||||||
|
|
||||||
if (initializer) initializer (sll);
|
if (init) init (sll);
|
||||||
|
|
||||||
return sll;
|
return sll;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_close (ase_sll_t* sll)
|
void ase_sll_close (sll_t* sll)
|
||||||
{
|
{
|
||||||
ase_sll_clear (sll);
|
ase_sll_clear (sll);
|
||||||
ASE_MMGR_FREE (sll->mmgr, sll);
|
ASE_MMGR_FREE (sll->mmgr, sll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_clear (ase_sll_t* sll)
|
void ase_sll_clear (sll_t* sll)
|
||||||
{
|
{
|
||||||
while (sll->head != ASE_NULL) ase_sll_delete (sll, sll->head);
|
while (HEAD(sll) != ASE_NULL) ase_sll_delete (sll, HEAD(sll));
|
||||||
ASE_ASSERT (sll->tail == ASE_NULL);
|
ASE_ASSERT (TAIL(sll) == ASE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ase_sll_getextension (ase_sll_t* sll)
|
void* ase_sll_getextension (sll_t* sll)
|
||||||
{
|
{
|
||||||
return sll + 1;
|
return sll + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_mmgr_t* ase_sll_getmmgr (ase_sll_t* sll)
|
mmgr_t* ase_sll_getmmgr (sll_t* sll)
|
||||||
{
|
{
|
||||||
return sll->mmgr;
|
return sll->mmgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_setmmgr (ase_sll_t* sll, ase_mmgr_t* mmgr)
|
void ase_sll_setmmgr (sll_t* sll, mmgr_t* mmgr)
|
||||||
{
|
{
|
||||||
sll->mmgr = mmgr;
|
sll->mmgr = mmgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_size_t ase_sll_getsize (ase_sll_t* sll)
|
size_t ase_sll_getsize (sll_t* sll)
|
||||||
{
|
{
|
||||||
return sll->size;
|
return SIZE(sll);
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_sll_node_t* ase_sll_gethead (ase_sll_t* sll)
|
node_t* ase_sll_gethead (sll_t* sll)
|
||||||
{
|
{
|
||||||
return sll->head;
|
return HEAD(sll);
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_sll_node_t* ase_sll_gettail (ase_sll_t* sll)
|
node_t* ase_sll_gettail (sll_t* sll)
|
||||||
{
|
{
|
||||||
return sll->tail;
|
return TAIL(sll);
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_sll_copier_t ase_sll_getcopier (ase_sll_t* sll)
|
copier_t ase_sll_getcopier (sll_t* sll)
|
||||||
{
|
{
|
||||||
return sll->copier;
|
return sll->copier;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier)
|
void ase_sll_setcopier (sll_t* sll, copier_t copier)
|
||||||
{
|
{
|
||||||
sll->copier = copier;
|
sll->copier = copier;
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_sll_freeer_t ase_sll_getfreeer (ase_sll_t* sll)
|
freeer_t ase_sll_getfreeer (sll_t* sll)
|
||||||
{
|
{
|
||||||
return sll->freeer;
|
return sll->freeer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_setfreeer (ase_sll_t* sll, ase_sll_freeer_t freeer)
|
void ase_sll_setfreeer (sll_t* sll, freeer_t freeer)
|
||||||
{
|
{
|
||||||
sll->freeer = freeer;
|
sll->freeer = freeer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ase_sll_node_t* alloc_node (ase_sll_t* sll, void* dptr, ase_size_t dlen)
|
static node_t* alloc_node (sll_t* sll, void* dptr, size_t dlen)
|
||||||
{
|
{
|
||||||
ase_sll_node_t* n;
|
node_t* n;
|
||||||
|
|
||||||
if (sll->copier == ASE_NULL)
|
if (sll->copier == ASE_NULL)
|
||||||
{
|
{
|
||||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
|
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(node_t));
|
||||||
if (n == ASE_NULL) return ASE_NULL;
|
if (n == ASE_NULL) return ASE_NULL;
|
||||||
n->dptr = dptr;
|
DPTR(n) = dptr;
|
||||||
}
|
}
|
||||||
else if (sll->copier == ASE_SLL_COPIER_INLINE)
|
else if (sll->copier == ASE_SLL_COPIER_INLINE)
|
||||||
{
|
{
|
||||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t) + dlen);
|
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(node_t) + dlen);
|
||||||
if (n == ASE_NULL) return ASE_NULL;
|
if (n == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
ASE_MEMCPY (n + 1, dptr, dlen);
|
ASE_MEMCPY (n + 1, dptr, dlen);
|
||||||
n->dptr = n + 1;
|
DPTR(n) = n + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(ase_sll_node_t));
|
n = ASE_MMGR_ALLOC (sll->mmgr, ASE_SIZEOF(node_t));
|
||||||
if (n == ASE_NULL) return ASE_NULL;
|
if (n == ASE_NULL) return ASE_NULL;
|
||||||
n->dptr = sll->copier (sll, dptr, dlen);
|
DPTR(n) = sll->copier (sll, dptr, dlen);
|
||||||
if (n->dptr == ASE_NULL)
|
if (DPTR(n) == ASE_NULL)
|
||||||
{
|
{
|
||||||
ASE_MMGR_FREE (sll->mmgr, n);
|
ASE_MMGR_FREE (sll->mmgr, n);
|
||||||
return ASE_NULL;
|
return ASE_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n->dlen = dlen;
|
DLEN(n) = dlen;
|
||||||
n->next = ASE_NULL;
|
NEXT(n) = ASE_NULL;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_sll_node_t* ase_sll_insert (
|
node_t* ase_sll_insert (
|
||||||
ase_sll_t* sll, ase_sll_node_t* pos, void* dptr, ase_size_t dlen)
|
sll_t* sll, node_t* pos, void* dptr, size_t dlen)
|
||||||
{
|
{
|
||||||
ase_sll_node_t* n = alloc_node (sll, dptr, dlen);
|
node_t* n = alloc_node (sll, dptr, dlen);
|
||||||
if (n == ASE_NULL) return ASE_NULL;
|
if (n == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
if (pos == ASE_NULL)
|
if (pos == ASE_NULL)
|
||||||
{
|
{
|
||||||
/* insert at the end */
|
/* insert at the end */
|
||||||
if (sll->head == ASE_NULL)
|
if (HEAD(sll) == ASE_NULL)
|
||||||
{
|
{
|
||||||
ASE_ASSERT (sll->tail == ASE_NULL);
|
ASE_ASSERT (TAIL(sll) == ASE_NULL);
|
||||||
sll->head = n;
|
HEAD(sll) = n;
|
||||||
}
|
}
|
||||||
else sll->tail->next = n;
|
else NEXT(TAIL(sll)) = n;
|
||||||
|
|
||||||
sll->tail = n;
|
TAIL(sll) = n;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* insert in front of the positional node */
|
/* insert in front of the positional node */
|
||||||
n->next = pos;
|
NEXT(n) = pos;
|
||||||
if (pos == sll->head) sll->head = n;
|
if (pos == HEAD(sll)) HEAD(sll) = n;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* take note of performance penalty */
|
/* take note of performance penalty */
|
||||||
ase_sll_node_t* n2 = sll->head;
|
node_t* n2 = HEAD(sll);
|
||||||
while (n2->next != pos) n2 = n2->next;
|
while (NEXT(n2) != pos) n2 = NEXT(n2);
|
||||||
n2->next = n;
|
NEXT(n2) = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sll->size++;
|
SIZE(sll)++;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_sll_node_t* ase_sll_pushhead (ase_sll_t* sll, void* data, ase_size_t size)
|
node_t* ase_sll_pushhead (sll_t* sll, void* data, size_t size)
|
||||||
{
|
{
|
||||||
return ase_sll_insert (sll, sll->head, data, size);
|
return ase_sll_insert (sll, HEAD(sll), data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_sll_node_t* ase_sll_pushtail (ase_sll_t* sll, void* data, ase_size_t size)
|
node_t* ase_sll_pushtail (sll_t* sll, void* data, size_t size)
|
||||||
{
|
{
|
||||||
return ase_sll_insert (sll, ASE_NULL, data, size);
|
return ase_sll_insert (sll, ASE_NULL, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_delete (ase_sll_t* sll, ase_sll_node_t* pos)
|
void ase_sll_delete (sll_t* sll, node_t* pos)
|
||||||
{
|
{
|
||||||
if (pos == ASE_NULL) return; /* not a valid node */
|
if (pos == ASE_NULL) return; /* not a valid node */
|
||||||
|
|
||||||
if (pos == sll->head)
|
if (pos == HEAD(sll))
|
||||||
{
|
{
|
||||||
/* it is simple to delete the head node */
|
/* it is simple to delete the head node */
|
||||||
sll->head = pos->next;
|
HEAD(sll) = NEXT(pos);
|
||||||
if (sll->head == ASE_NULL) sll->tail = ASE_NULL;
|
if (HEAD(sll) == ASE_NULL) TAIL(sll) = ASE_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* but deletion of other nodes has significant performance
|
/* but deletion of other nodes has significant performance
|
||||||
* penalty as it has look for the predecessor of the
|
* penalty as it has look for the predecessor of the
|
||||||
* target node */
|
* target node */
|
||||||
ase_sll_node_t* n2 = sll->head;
|
node_t* n2 = HEAD(sll);
|
||||||
while (n2->next != pos) n2 = n2->next;
|
while (NEXT(n2) != pos) n2 = NEXT(n2);
|
||||||
|
|
||||||
n2->next = pos->next;
|
NEXT(n2) = NEXT(pos);
|
||||||
|
|
||||||
/* update the tail node if necessary */
|
/* update the tail node if necessary */
|
||||||
if (pos == sll->tail) sll->tail = n2;
|
if (pos == TAIL(sll)) TAIL(sll) = n2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sll->freeer != ASE_NULL)
|
if (sll->freeer != ASE_NULL)
|
||||||
{
|
{
|
||||||
/* free the actual data */
|
/* free the actual data */
|
||||||
sll->freeer (sll, pos->dptr, pos->dlen);
|
sll->freeer (sll, DPTR(pos), DLEN(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the node */
|
/* free the node */
|
||||||
ASE_MMGR_FREE (sll->mmgr, pos);
|
ASE_MMGR_FREE (sll->mmgr, pos);
|
||||||
|
|
||||||
/* decrement the number of elements */
|
/* decrement the number of elements */
|
||||||
sll->size--;
|
SIZE(sll)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_pophead (ase_sll_t* sll)
|
void ase_sll_pophead (sll_t* sll)
|
||||||
{
|
{
|
||||||
ase_sll_delete (sll, sll->head);
|
ase_sll_delete (sll, HEAD(sll));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_poptail (ase_sll_t* sll)
|
void ase_sll_poptail (sll_t* sll)
|
||||||
{
|
{
|
||||||
ase_sll_delete (sll, sll->tail);
|
ase_sll_delete (sll, TAIL(sll));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker, void* arg)
|
void ase_sll_walk (sll_t* sll, walker_t walker, void* arg)
|
||||||
{
|
{
|
||||||
ase_sll_node_t* n = sll->head;
|
node_t* n = HEAD(sll);
|
||||||
|
|
||||||
while (n != ASE_NULL)
|
while (n != ASE_NULL)
|
||||||
{
|
{
|
||||||
if (walker(sll,n,arg) == ASE_SLL_WALK_STOP) return;
|
if (walker(sll,n,arg) == ASE_SLL_WALK_STOP) return;
|
||||||
n = n->next;
|
n = NEXT(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ase_sll_copyinline (ase_sll_t* sll, void* dptr, ase_size_t dlen)
|
void* ase_sll_copyinline (sll_t* sll, void* dptr, size_t dlen)
|
||||||
{
|
{
|
||||||
/* this is a dummy copier */
|
/* this is a dummy copier */
|
||||||
return ASE_NULL;
|
return ASE_NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user