This commit is contained in:
parent
dd00a6f49d
commit
91159085ed
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: map.c 350 2008-08-29 14:51:04Z baconevi $
|
* $Id: map.c 351 2008-08-29 15:02:26Z baconevi $
|
||||||
*
|
*
|
||||||
* {License}
|
* {License}
|
||||||
*/
|
*/
|
||||||
@ -24,20 +24,9 @@
|
|||||||
#define SIZEOF(x) ASE_SIZEOF(x)
|
#define SIZEOF(x) ASE_SIZEOF(x)
|
||||||
#define size_t ase_size_t
|
#define size_t ase_size_t
|
||||||
#define byte_t ase_byte_t
|
#define byte_t ase_byte_t
|
||||||
|
#define uint_t ase_uint_t
|
||||||
#define mmgr_t ase_mmgr_t
|
#define mmgr_t ase_mmgr_t
|
||||||
|
|
||||||
#define PUB(m) (m)
|
|
||||||
#define PRIV(m) ((priv_t*)(m+1))
|
|
||||||
|
|
||||||
typedef struct priv_t priv_t;
|
|
||||||
|
|
||||||
struct priv_t
|
|
||||||
{
|
|
||||||
unsigned int load_factor;
|
|
||||||
size_t threshold;
|
|
||||||
pair_t** bucket;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int reorganize (map_t* map);
|
static int reorganize (map_t* map);
|
||||||
|
|
||||||
static size_t hash_key (map_t* map, const void* kptr, size_t klen)
|
static size_t hash_key (map_t* map, const void* kptr, size_t klen)
|
||||||
@ -196,9 +185,7 @@ static pair_t* change_pair_val (
|
|||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_t* ase_map_open (
|
map_t* ase_map_open (mmgr_t* mmgr, size_t ext, size_t capa, uint_t factor)
|
||||||
mmgr_t* mmgr, size_t ext,
|
|
||||||
size_t capa, unsigned int load_factor)
|
|
||||||
{
|
{
|
||||||
map_t* map;
|
map_t* map;
|
||||||
|
|
||||||
@ -212,29 +199,43 @@ map_t* ase_map_open (
|
|||||||
if (mmgr == ASE_NULL) return ASE_NULL;
|
if (mmgr == ASE_NULL) return ASE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASE_ASSERTX (capa >= 0,
|
if (ase_map_init (map, mmgr, capa, factor) == ASE_NULL)
|
||||||
"The initial capacity should be greater than 0");
|
|
||||||
|
|
||||||
ASE_ASSERTX (load_factor >= 0 && load_factor <= 100,
|
|
||||||
"The load factor should be between 0 and 100 inclusive");
|
|
||||||
|
|
||||||
map = ASE_MMGR_ALLOC (mmgr, SIZEOF(map_t)+SIZEOF(priv_t)+ext);
|
|
||||||
if (map == ASE_NULL) return ASE_NULL;
|
|
||||||
|
|
||||||
PRIV(map)->bucket = ASE_MMGR_ALLOC (mmgr, capa*SIZEOF(pair_t*));
|
|
||||||
if (PRIV(map)->bucket == ASE_NULL)
|
|
||||||
{
|
{
|
||||||
ASE_MMGR_FREE (mmgr, map);
|
ASE_MMGR_FREE (mmgr, map);
|
||||||
return ASE_NULL;
|
return ASE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mmgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ase_map_close (map_t* map)
|
||||||
|
{
|
||||||
|
ase_map_fini (map);
|
||||||
|
ASE_MMGR_FREE (map->mmgr, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
map_t* ase_map_init (map_t* map, mmgr_t* mmgr, size_t capa, uint_t factor)
|
||||||
|
{
|
||||||
|
ASE_ASSERTX (capa >= 0,
|
||||||
|
"The initial capacity should be greater than 0");
|
||||||
|
|
||||||
|
ASE_ASSERTX (factor >= 0 && factor <= 100,
|
||||||
|
"The load factor should be between 0 and 100 inclusive");
|
||||||
|
|
||||||
/* do not zero out the extension */
|
/* do not zero out the extension */
|
||||||
ASE_MEMSET (map, 0, SIZEOF(map_t)+SIZEOF(priv_t));
|
ASE_MEMSET (map, 0, SIZEOF(map_t));
|
||||||
map->mmgr = mmgr;
|
map->mmgr = mmgr;
|
||||||
|
|
||||||
|
map->bucket = ASE_MMGR_ALLOC (mmgr, capa*SIZEOF(pair_t*));
|
||||||
|
if (map->bucket == ASE_NULL)
|
||||||
|
{
|
||||||
|
ASE_MMGR_FREE (mmgr, map);
|
||||||
|
return ASE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
map->size = 0;
|
map->size = 0;
|
||||||
map->capa = capa;
|
map->capa = capa;
|
||||||
PRIV(map)->load_factor = load_factor;
|
map->factor = factor;
|
||||||
|
|
||||||
map->hasher = hash_key;
|
map->hasher = hash_key;
|
||||||
map->comper = comp_key;
|
map->comper = comp_key;
|
||||||
@ -242,11 +243,10 @@ map_t* ase_map_open (
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_map_close (map_t* map)
|
void ase_map_fini (map_t* map)
|
||||||
{
|
{
|
||||||
ase_map_clear (map);
|
ase_map_clear (map);
|
||||||
ASE_MMGR_FREE (map->mmgr, PRIV(map)->bucket);
|
ASE_MMGR_FREE (map->mmgr, map->bucket);
|
||||||
ASE_MMGR_FREE (map->mmgr, map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ase_map_clear (map_t* map)
|
void ase_map_clear (map_t* map)
|
||||||
@ -256,7 +256,7 @@ void ase_map_clear (map_t* map)
|
|||||||
|
|
||||||
for (i = 0; i < map->capa; i++)
|
for (i = 0; i < map->capa; i++)
|
||||||
{
|
{
|
||||||
pair = PRIV(map)->bucket[i];
|
pair = map->bucket[i];
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
@ -266,7 +266,7 @@ void ase_map_clear (map_t* map)
|
|||||||
pair = next;
|
pair = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIV(map)->bucket[i] = ASE_NULL;
|
map->bucket[i] = ASE_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ void ase_map_setcomper (map_t* map, comper_t comper)
|
|||||||
|
|
||||||
void* ase_map_getextension (map_t* map)
|
void* ase_map_getextension (map_t* map)
|
||||||
{
|
{
|
||||||
return PRIV(map) + 1;
|
return map + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mmgr_t* ase_map_getmmgr (map_t* map)
|
mmgr_t* ase_map_getmmgr (map_t* map)
|
||||||
@ -351,7 +351,7 @@ pair_t* ase_map_search (map_t* map, const void* kptr, size_t klen)
|
|||||||
size_t hc;
|
size_t hc;
|
||||||
|
|
||||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||||
pair = PRIV(map)->bucket[hc];
|
pair = map->bucket[hc];
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
@ -374,7 +374,7 @@ int ase_map_put (
|
|||||||
size_t hc;
|
size_t hc;
|
||||||
|
|
||||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||||
pair = PRIV(map)->bucket[hc];
|
pair = map->bucket[hc];
|
||||||
prev = ASE_NULL;
|
prev = ASE_NULL;
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
@ -388,7 +388,7 @@ int ase_map_put (
|
|||||||
if (p != pair)
|
if (p != pair)
|
||||||
{
|
{
|
||||||
/* the pair has been reallocated. relink it */
|
/* the pair has been reallocated. relink it */
|
||||||
if (prev == ASE_NULL) PRIV(map)->bucket[hc] = p;
|
if (prev == ASE_NULL) map->bucket[hc] = p;
|
||||||
else NEXT(prev) = p;
|
else NEXT(prev) = p;
|
||||||
NEXT(p) = next;
|
NEXT(p) = next;
|
||||||
}
|
}
|
||||||
@ -401,7 +401,7 @@ int ase_map_put (
|
|||||||
pair = next;
|
pair = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PRIV(map)->threshold > 0 && map->size >= PRIV(map)->threshold)
|
if (map->threshold > 0 && map->size >= map->threshold)
|
||||||
{
|
{
|
||||||
if (reorganize(map) == 0) /* ignore the error */
|
if (reorganize(map) == 0) /* ignore the error */
|
||||||
{
|
{
|
||||||
@ -414,8 +414,8 @@ int ase_map_put (
|
|||||||
pair = alloc_pair (map, kptr, klen, vptr, vlen);
|
pair = alloc_pair (map, kptr, klen, vptr, vlen);
|
||||||
if (pair == ASE_NULL) return -1; /* error */
|
if (pair == ASE_NULL) return -1; /* error */
|
||||||
|
|
||||||
NEXT(pair) = PRIV(map)->bucket[hc];
|
NEXT(pair) = map->bucket[hc];
|
||||||
PRIV(map)->bucket[hc] = pair;
|
map->bucket[hc] = pair;
|
||||||
map->size++;
|
map->size++;
|
||||||
|
|
||||||
if (px != ASE_NULL) *px = pair;
|
if (px != ASE_NULL) *px = pair;
|
||||||
@ -441,7 +441,7 @@ pair_t* ase_map_insert (
|
|||||||
size_t hc;
|
size_t hc;
|
||||||
|
|
||||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||||
pair = PRIV(map)->bucket[hc];
|
pair = map->bucket[hc];
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
@ -453,7 +453,7 @@ pair_t* ase_map_insert (
|
|||||||
pair = NEXT(pair);
|
pair = NEXT(pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PRIV(map)->threshold > 0 && map->size >= PRIV(map)->threshold)
|
if (map->threshold > 0 && map->size >= map->threshold)
|
||||||
{
|
{
|
||||||
if (reorganize(map) == 0) /* ignore the error */
|
if (reorganize(map) == 0) /* ignore the error */
|
||||||
{
|
{
|
||||||
@ -466,8 +466,8 @@ pair_t* ase_map_insert (
|
|||||||
pair = alloc_pair (map, kptr, klen, vptr, vlen);
|
pair = alloc_pair (map, kptr, klen, vptr, vlen);
|
||||||
if (pair == ASE_NULL) return ASE_NULL;
|
if (pair == ASE_NULL) return ASE_NULL;
|
||||||
|
|
||||||
NEXT(pair) = PRIV(map)->bucket[hc];
|
NEXT(pair) = map->bucket[hc];
|
||||||
PRIV(map)->bucket[hc] = pair;
|
map->bucket[hc] = pair;
|
||||||
map->size++;
|
map->size++;
|
||||||
|
|
||||||
return pair;
|
return pair;
|
||||||
@ -480,7 +480,7 @@ pair_t* ase_map_update (
|
|||||||
size_t hc;
|
size_t hc;
|
||||||
|
|
||||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||||
pair = PRIV(map)->bucket[hc];
|
pair = map->bucket[hc];
|
||||||
prev = ASE_NULL;
|
prev = ASE_NULL;
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
@ -495,7 +495,7 @@ pair_t* ase_map_update (
|
|||||||
if (p != pair)
|
if (p != pair)
|
||||||
{
|
{
|
||||||
/* the pair has been reallocated. relink it */
|
/* the pair has been reallocated. relink it */
|
||||||
if (prev == ASE_NULL) PRIV(map)->bucket[hc] = p;
|
if (prev == ASE_NULL) map->bucket[hc] = p;
|
||||||
else NEXT(prev) = p;
|
else NEXT(prev) = p;
|
||||||
NEXT(p) = next;
|
NEXT(p) = next;
|
||||||
}
|
}
|
||||||
@ -516,7 +516,7 @@ int ase_map_delete (map_t* map, const void* kptr, size_t klen)
|
|||||||
size_t hc;
|
size_t hc;
|
||||||
|
|
||||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||||
pair = PRIV(map)->bucket[hc];
|
pair = map->bucket[hc];
|
||||||
prev = ASE_NULL;
|
prev = ASE_NULL;
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
@ -524,7 +524,7 @@ int ase_map_delete (map_t* map, const void* kptr, size_t klen)
|
|||||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||||
{
|
{
|
||||||
if (prev == ASE_NULL)
|
if (prev == ASE_NULL)
|
||||||
PRIV(map)->bucket[hc] = NEXT(pair);
|
map->bucket[hc] = NEXT(pair);
|
||||||
else NEXT(prev) = NEXT(pair);
|
else NEXT(prev) = NEXT(pair);
|
||||||
|
|
||||||
free_pair (map, pair);
|
free_pair (map, pair);
|
||||||
@ -547,7 +547,7 @@ void ase_map_walk (map_t* map, walker_t walker, void* arg)
|
|||||||
|
|
||||||
for (i = 0; i < map->capa; i++)
|
for (i = 0; i < map->capa; i++)
|
||||||
{
|
{
|
||||||
pair = PRIV(map)->bucket[i];
|
pair = map->bucket[i];
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
@ -565,7 +565,7 @@ pair_t* ase_map_getfirstpair (map_t* map, size_t* buckno)
|
|||||||
|
|
||||||
for (i = 0; i < map->capa; i++)
|
for (i = 0; i < map->capa; i++)
|
||||||
{
|
{
|
||||||
pair = PRIV(map)->bucket[i];
|
pair = map->bucket[i];
|
||||||
if (pair != ASE_NULL)
|
if (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
*buckno = i;
|
*buckno = i;
|
||||||
@ -590,7 +590,7 @@ pair_t* ase_map_getnextpair (map_t* map, pair_t* pair, size_t* buckno)
|
|||||||
|
|
||||||
for (i = (*buckno)+1; i < map->capa; i++)
|
for (i = (*buckno)+1; i < map->capa; i++)
|
||||||
{
|
{
|
||||||
pair = PRIV(map)->bucket[i];
|
pair = map->bucket[i];
|
||||||
if (pair != ASE_NULL)
|
if (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
*buckno = i;
|
*buckno = i;
|
||||||
@ -615,7 +615,7 @@ static int reorganize (map_t* map)
|
|||||||
if (new_buck == ASE_NULL)
|
if (new_buck == ASE_NULL)
|
||||||
{
|
{
|
||||||
/* reorganization is disabled once it fails */
|
/* reorganization is disabled once it fails */
|
||||||
PRIV(map)->threshold = 0;
|
map->threshold = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,7 +623,7 @@ static int reorganize (map_t* map)
|
|||||||
|
|
||||||
for (i = 0; i < map->capa; i++)
|
for (i = 0; i < map->capa; i++)
|
||||||
{
|
{
|
||||||
pair_t* pair = PRIV(map)->bucket[i];
|
pair_t* pair = map->bucket[i];
|
||||||
|
|
||||||
while (pair != ASE_NULL)
|
while (pair != ASE_NULL)
|
||||||
{
|
{
|
||||||
@ -640,10 +640,10 @@ static int reorganize (map_t* map)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASE_MMGR_FREE (map->mmgr, PRIV(map)->bucket);
|
ASE_MMGR_FREE (map->mmgr, map->bucket);
|
||||||
PRIV(map)->bucket = new_buck;
|
map->bucket = new_buck;
|
||||||
map->capa = new_capa;
|
map->capa = new_capa;
|
||||||
PRIV(map)->threshold = map->capa * PRIV(map)->load_factor / 100;
|
map->threshold = map->capa * map->factor / 100;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user