From a88cc05eaeddf286d3d1b80b9a0aa33454e7304b Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 25 Sep 2008 01:18:50 +0000 Subject: [PATCH] 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 --- ase/include/ase/cmn/map.h | 10 ++++++++-- ase/include/ase/cmn/str.h | 3 ++- ase/lib/cmn/map.c | 34 ++++++++++++++++++++++++++-------- ase/lib/cmn/str_bas.c | 9 ++++++++- ase/lib/cmn/str_dyn.c | 12 +++++++++++- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/ase/include/ase/cmn/map.h b/ase/include/ase/cmn/map.h index b1fae78e..91cf787f 100644 --- a/ase/include/ase/cmn/map.h +++ b/ase/include/ase/cmn/map.h @@ -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} */ @@ -12,6 +12,7 @@ typedef struct ase_map_t ase_map_t; typedef struct ase_map_pair_t ase_map_pair_t; +typedef enum ase_map_walk_t ase_map_walk_t; /* data copier */ 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); /* 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_pair_t* pair /* the pointer to a key/value pair */, 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_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 extern "C" { #endif diff --git a/ase/include/ase/cmn/str.h b/ase/include/ase/cmn/str.h index e5521deb..5d21b95b 100644 --- a/ase/include/ase/cmn/str.h +++ b/ase/include/ase/cmn/str.h @@ -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} */ @@ -86,6 +86,7 @@ extern "C" { * basic string functions */ 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_char_t* buf, const ase_char_t* str); diff --git a/ase/lib/cmn/map.c b/ase/lib/cmn/map.c index 0198cf46..96542bd1 100644 --- a/ase/lib/cmn/map.c +++ b/ase/lib/cmn/map.c @@ -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} */ @@ -63,11 +63,10 @@ static pair_t* alloc_pair (map_t* map, copier_t vcop = map->copier[ASE_MAP_VAL]; size_t as = SIZEOF(pair_t); - if (kcop == ASE_MAP_COPIER_INLINE) as += klen; 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; NEXT(n) = ASE_NULL; @@ -84,8 +83,8 @@ static pair_t* alloc_pair (map_t* map, } else { - n->kptr = kcop (map, kptr, klen); - if (n->kptr == ASE_NULL) + KPTR(n) = kcop (map, kptr, klen); + if (KPTR(n) == ASE_NULL) { ASE_MMGR_FREE (map->mmgr, n); return ASE_NULL; @@ -100,6 +99,8 @@ static pair_t* alloc_pair (map_t* map, else if (vcop == ASE_MAP_COPIER_INLINE) { VPTR(n) = n + 1; + if (kcop == ASE_MAP_COPIER_INLINE) + VPTR(n) = (byte_t*)VPTR(n) + klen; ASE_MEMCPY (VPTR(n), vptr, vlen); } 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; } + 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) { 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*)); 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->capa = capa; map->factor = factor; + map->threshold = map->capa * map->factor / 100; map->hasher = hash_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; } @@ -521,7 +538,7 @@ pair_t* ase_map_update ( NEXT(p) = next; } - return 0; /* value changed for the existing key */ + return p; /* value changed for the existing key */ } prev = pair; @@ -646,7 +663,7 @@ static int reorganize (map_t* map) } 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) { /* reorganization is disabled once it fails */ @@ -654,7 +671,8 @@ static int reorganize (map_t* map) 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++) { diff --git a/ase/lib/cmn/str_bas.c b/ase/lib/cmn/str_bas.c index 1e3b9b8b..28c75fa0 100644 --- a/ase/lib/cmn/str_bas.c +++ b/ase/lib/cmn/str_bas.c @@ -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} */ @@ -15,6 +15,13 @@ ase_size_t ase_strlen (const ase_char_t* 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_char_t* org = buf; diff --git a/ase/lib/cmn/str_dyn.c b/ase/lib/cmn/str_dyn.c index 0a12df45..3c55664d 100644 --- a/ase/lib/cmn/str_dyn.c +++ b/ase/lib/cmn/str_dyn.c @@ -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} */ @@ -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; + 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); if (str == ASE_NULL) return ASE_NULL;