fixed various bugs in a map and enhanced it.
- added ase_strbytes returning the number of bytes of a '\0'-terminated string - changed the prototype of ase_map_walker_t to return ase_map_walk_t - added ASE_MAP_KCLEN and ASE_MAP_VCLEN - fixed the bug of not initializing the bucket in ase_map_init - fixed the bug of returning 0 when a match is found in ase_map_search - fixed the bug of wrongly calculating the value pointer in alloc_pair
This commit is contained in:
parent
21c331febf
commit
a88cc05eae
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: map.h 375 2008-09-23 14:47:23Z baconevi $
|
* $Id: map.h 376 2008-09-24 07:18:50Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
typedef struct ase_map_t ase_map_t;
|
typedef struct ase_map_t ase_map_t;
|
||||||
typedef struct ase_map_pair_t ase_map_pair_t;
|
typedef struct ase_map_pair_t ase_map_pair_t;
|
||||||
|
typedef enum ase_map_walk_t ase_map_walk_t;
|
||||||
|
|
||||||
/* data copier */
|
/* data copier */
|
||||||
typedef void* (*ase_map_copier_t) (
|
typedef void* (*ase_map_copier_t) (
|
||||||
@ -59,7 +60,7 @@ typedef void (*ase_map_keeper_t) (
|
|||||||
typedef ase_size_t (*ase_map_sizer_t) (ase_map_t* data, ase_size_t hint);
|
typedef ase_size_t (*ase_map_sizer_t) (ase_map_t* data, ase_size_t hint);
|
||||||
|
|
||||||
/* pair visitor - should return ASE_MAP_WALK_STOP or ASE_MAP_WALK_FORWARD */
|
/* pair visitor - should return ASE_MAP_WALK_STOP or ASE_MAP_WALK_FORWARD */
|
||||||
typedef int (*ase_map_walker_t) (
|
typedef ase_map_walk_t (*ase_map_walker_t) (
|
||||||
ase_map_t* map /* a map */,
|
ase_map_t* map /* a map */,
|
||||||
ase_map_pair_t* pair /* the pointer to a key/value pair */,
|
ase_map_pair_t* pair /* the pointer to a key/value pair */,
|
||||||
void* arg /* the pointer to user-defined data */
|
void* arg /* the pointer to user-defined data */
|
||||||
@ -120,6 +121,11 @@ enum ase_map_walk_t
|
|||||||
#define ASE_MAP_VLEN(p) ((p)->vlen)
|
#define ASE_MAP_VLEN(p) ((p)->vlen)
|
||||||
#define ASE_MAP_NEXT(p) ((p)->next)
|
#define ASE_MAP_NEXT(p) ((p)->next)
|
||||||
|
|
||||||
|
/* special macros that you can use to get the number of characters
|
||||||
|
* in a key and/or a value if it is a chracter string */
|
||||||
|
#define ASE_MAP_KCLEN(p) (((p)->klen)/ASE_SIZEOF(ase_char_t))
|
||||||
|
#define ASE_MAP_VCLEN(p) (((p)->vlen)/ASE_SIZEOF(ase_char_t))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: str.h 375 2008-09-23 14:47:23Z baconevi $
|
* $Id: str.h 376 2008-09-24 07:18:50Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -86,6 +86,7 @@ extern "C" {
|
|||||||
* basic string functions
|
* basic string functions
|
||||||
*/
|
*/
|
||||||
ase_size_t ase_strlen (const ase_char_t* str);
|
ase_size_t ase_strlen (const ase_char_t* str);
|
||||||
|
ase_size_t ase_strbytes (const ase_char_t* str);
|
||||||
|
|
||||||
ase_size_t ase_strcpy (
|
ase_size_t ase_strcpy (
|
||||||
ase_char_t* buf, const ase_char_t* str);
|
ase_char_t* buf, const ase_char_t* str);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: map.c 375 2008-09-23 14:47:23Z baconevi $
|
* $Id: map.c 376 2008-09-24 07:18:50Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -63,11 +63,10 @@ static pair_t* alloc_pair (map_t* map,
|
|||||||
copier_t vcop = map->copier[ASE_MAP_VAL];
|
copier_t vcop = map->copier[ASE_MAP_VAL];
|
||||||
|
|
||||||
size_t as = SIZEOF(pair_t);
|
size_t as = SIZEOF(pair_t);
|
||||||
|
|
||||||
if (kcop == ASE_MAP_COPIER_INLINE) as += klen;
|
if (kcop == ASE_MAP_COPIER_INLINE) as += klen;
|
||||||
if (vcop == ASE_MAP_COPIER_INLINE) as += vlen;
|
if (vcop == ASE_MAP_COPIER_INLINE) as += vlen;
|
||||||
|
|
||||||
n = ASE_MMGR_ALLOC (map->mmgr, as);
|
n = (pair_t*) ASE_MMGR_ALLOC (map->mmgr, as);
|
||||||
if (n == ASE_NULL) return ASE_NULL;
|
if (n == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
NEXT(n) = ASE_NULL;
|
NEXT(n) = ASE_NULL;
|
||||||
@ -84,8 +83,8 @@ static pair_t* alloc_pair (map_t* map,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n->kptr = kcop (map, kptr, klen);
|
KPTR(n) = kcop (map, kptr, klen);
|
||||||
if (n->kptr == ASE_NULL)
|
if (KPTR(n) == ASE_NULL)
|
||||||
{
|
{
|
||||||
ASE_MMGR_FREE (map->mmgr, n);
|
ASE_MMGR_FREE (map->mmgr, n);
|
||||||
return ASE_NULL;
|
return ASE_NULL;
|
||||||
@ -100,6 +99,8 @@ static pair_t* alloc_pair (map_t* map,
|
|||||||
else if (vcop == ASE_MAP_COPIER_INLINE)
|
else if (vcop == ASE_MAP_COPIER_INLINE)
|
||||||
{
|
{
|
||||||
VPTR(n) = n + 1;
|
VPTR(n) = n + 1;
|
||||||
|
if (kcop == ASE_MAP_COPIER_INLINE)
|
||||||
|
VPTR(n) = (byte_t*)VPTR(n) + klen;
|
||||||
ASE_MEMCPY (VPTR(n), vptr, vlen);
|
ASE_MEMCPY (VPTR(n), vptr, vlen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -201,6 +202,9 @@ map_t* ase_map_open (mmgr_t* mmgr, size_t ext, size_t capa, uint_t factor)
|
|||||||
if (mmgr == ASE_NULL) return ASE_NULL;
|
if (mmgr == ASE_NULL) return ASE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map = (ase_map_t*) ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_map_t) + ext);
|
||||||
|
if (map == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
if (ase_map_init (map, mmgr, capa, factor) == ASE_NULL)
|
if (ase_map_init (map, mmgr, capa, factor) == ASE_NULL)
|
||||||
{
|
{
|
||||||
ASE_MMGR_FREE (mmgr, map);
|
ASE_MMGR_FREE (mmgr, map);
|
||||||
@ -234,13 +238,26 @@ map_t* ase_map_init (map_t* map, mmgr_t* mmgr, size_t capa, uint_t factor)
|
|||||||
map->bucket = ASE_MMGR_ALLOC (mmgr, capa*SIZEOF(pair_t*));
|
map->bucket = ASE_MMGR_ALLOC (mmgr, capa*SIZEOF(pair_t*));
|
||||||
if (map->bucket == ASE_NULL) return ASE_NULL;
|
if (map->bucket == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
|
/*for (i = 0; i < capa; i++) map->bucket[i] = ASE_NULL;*/
|
||||||
|
ASE_MEMSET (map->bucket, 0, capa*SIZEOF(pair_t*));
|
||||||
|
|
||||||
map->size = 0;
|
map->size = 0;
|
||||||
map->capa = capa;
|
map->capa = capa;
|
||||||
map->factor = factor;
|
map->factor = factor;
|
||||||
|
map->threshold = map->capa * map->factor / 100;
|
||||||
|
|
||||||
map->hasher = hash_key;
|
map->hasher = hash_key;
|
||||||
map->comper = comp_key;
|
map->comper = comp_key;
|
||||||
|
|
||||||
|
/*
|
||||||
|
map->copier[ASE_MAP_KEY] = ASE_NULL;
|
||||||
|
map->copier[ASE_MAP_VAL] = ASE_NULL;
|
||||||
|
map->freeer[ASE_MAP_KEY] = ASE_NULL;
|
||||||
|
map->freeer[ASE_MAP_VAL] = ASE_NULL;
|
||||||
|
map->keeper = ASE_NULL;
|
||||||
|
map->sizer = ASE_NULL;
|
||||||
|
*/
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,7 +538,7 @@ pair_t* ase_map_update (
|
|||||||
NEXT(p) = next;
|
NEXT(p) = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* value changed for the existing key */
|
return p; /* value changed for the existing key */
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = pair;
|
prev = pair;
|
||||||
@ -646,7 +663,7 @@ static int reorganize (map_t* map)
|
|||||||
}
|
}
|
||||||
|
|
||||||
new_buck = (pair_t**) ASE_MMGR_ALLOC (
|
new_buck = (pair_t**) ASE_MMGR_ALLOC (
|
||||||
map->mmgr, SIZEOF(pair_t*) * new_capa);
|
map->mmgr, new_capa*SIZEOF(pair_t*));
|
||||||
if (new_buck == ASE_NULL)
|
if (new_buck == ASE_NULL)
|
||||||
{
|
{
|
||||||
/* reorganization is disabled once it fails */
|
/* reorganization is disabled once it fails */
|
||||||
@ -654,7 +671,8 @@ static int reorganize (map_t* map)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < new_capa; i++) new_buck[i] = ASE_NULL;
|
/*for (i = 0; i < new_capa; i++) new_buck[i] = ASE_NULL;*/
|
||||||
|
ASE_MEMSET (new_buck, 0, new_capa*SIZEOF(pair_t*));
|
||||||
|
|
||||||
for (i = 0; i < map->capa; i++)
|
for (i = 0; i < map->capa; i++)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: str_bas.c 337 2008-08-20 09:17:25Z baconevi $
|
* $Id: str_bas.c 376 2008-09-24 07:18:50Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -15,6 +15,13 @@ ase_size_t ase_strlen (const ase_char_t* str)
|
|||||||
return p - str;
|
return p - str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ase_size_t ase_strbytes (const ase_char_t* str)
|
||||||
|
{
|
||||||
|
const ase_char_t* p = str;
|
||||||
|
while (*p != ASE_T('\0')) p++;
|
||||||
|
return (p - str) * ASE_SIZEOF(ase_char_t);
|
||||||
|
}
|
||||||
|
|
||||||
ase_size_t ase_strcpy (ase_char_t* buf, const ase_char_t* str)
|
ase_size_t ase_strcpy (ase_char_t* buf, const ase_char_t* str)
|
||||||
{
|
{
|
||||||
ase_char_t* org = buf;
|
ase_char_t* org = buf;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: str_dyn.c 375 2008-09-23 14:47:23Z baconevi $
|
* $Id: str_dyn.c 376 2008-09-24 07:18:50Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -11,6 +11,16 @@ ase_str_t* ase_str_open (ase_mmgr_t* mmgr, ase_size_t ext, ase_size_t capa)
|
|||||||
{
|
{
|
||||||
ase_str_t* str;
|
ase_str_t* str;
|
||||||
|
|
||||||
|
if (mmgr == ASE_NULL)
|
||||||
|
{
|
||||||
|
mmgr = ASE_MMGR_GETDFL();
|
||||||
|
|
||||||
|
ASE_ASSERTX (mmgr != ASE_NULL,
|
||||||
|
"Set the memory manager with ASE_MMGR_SETDFL()");
|
||||||
|
|
||||||
|
if (mmgr == ASE_NULL) return ASE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
str = (ase_str_t*) ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_str_t) + ext);
|
str = (ase_str_t*) ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_str_t) + ext);
|
||||||
if (str == ASE_NULL) return ASE_NULL;
|
if (str == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user