From 981ceeedf42a5710cb597fc4ddc2a860ee815271 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 26 Sep 2008 05:06:33 +0000 Subject: [PATCH] added the scale factor to a map --- ase/include/ase/cmn/map.h | 129 +++++++++++++++++++++++++++++++------- ase/lib/awk/awk.c | 4 +- ase/lib/cmn/map.c | 56 ++++++++++++----- 3 files changed, 148 insertions(+), 41 deletions(-) diff --git a/ase/include/ase/cmn/map.h b/ase/include/ase/cmn/map.h index 738db64b..6a48b300 100644 --- a/ase/include/ase/cmn/map.h +++ b/ase/include/ase/cmn/map.h @@ -1,5 +1,5 @@ /* - * $Id: map.h 380 2008-09-24 08:16:41Z baconevi $ + * $Id: map.h 385 2008-09-25 11:06:33Z baconevi $ * * {License} */ @@ -66,6 +66,23 @@ typedef ase_map_walk_t (*ase_map_walker_t) ( void* arg /* the pointer to user-defined data */ ); +/****s* ase/ase_map_pair_t + * NAME + * ase_map_pair_t - define a pair + * DESCRIPTION + * A pair is composed of a key and a value. It maintains pointers to the + * beginning of a key and a value plus their length. The length is scaled + * down with the scale factor specified in an owning map. Use macros defined + * in the SEE ALSO section below to access individual attributes. + * ATTRIBUTES + * kptr - the pointer to a key + * klen - the length of a key + * vptr - the pointer to a value + * vlen - the length of a value + * SEE ALSO + * ASE_MAP_KPTR, ASE_MAP_KLEN, ASE_MAP_VPTR, ASE_MAP_VLEN + * SOURCE + */ struct ase_map_pair_t { void* kptr; @@ -74,9 +91,10 @@ struct ase_map_pair_t void* vptr; ase_size_t vlen; - /* used internally */ + /* an internal pointer to the next pair chained */ ase_map_pair_t* next; }; +/*****/ struct ase_map_t { @@ -87,13 +105,16 @@ struct ase_map_t ase_map_hasher_t hasher; /* key hasher */ ase_map_comper_t comper; /* key comparator */ ase_map_keeper_t keeper; /* value keeper */ - ase_map_sizer_t sizer; /* bucket resizer */ + ase_map_sizer_t sizer; /* bucket capacity recalculator */ + + ase_byte_t scale[2]; /* length scale */ + ase_byte_t factor; /* load factor */ + ase_byte_t filler0; ase_size_t size; ase_size_t capa; - - ase_uint_t factor; ase_size_t threshold; + ase_map_pair_t** bucket; }; @@ -112,8 +133,21 @@ enum ase_map_walk_t #define ASE_MAP_COPIER_INLINE ase_map_copyinline +/****d* ase/ASE_MAP_SIZE + * DESCRIPTION + * The ASE_MAP_SIZE() macro returns the number of pairs in a map. + * SOURCE + */ #define ASE_MAP_SIZE(m) ((m)->size) +/*****/ + +/****d* ase/ASE_MAP_CAPA + * DESCRIPTION + * The ASE_MAP_CAPA() macro returns the maximum number of pairs a map can hold. + * SOURCE + */ #define ASE_MAP_CAPA(m) ((m)->capa) +/*****/ #define ASE_MAP_MMGR(m) ((m)->mmgr) #define ASE_MAP_KCOPIER(m) ((m)->copier[ASE_MAP_KEY]) @@ -126,45 +160,65 @@ enum ase_map_walk_t #define ASE_MAP_SIZER(m) ((m)->sizer) #define ASE_MAP_EXTENSION(m) ((void*)(((ase_map_t*)m) + 1)) +#define ASE_MAP_FACTOR(m) ((m)->factor) +#define ASE_MAP_KSCALE(m) ((m)->scale[ASE_MAP_KEY]) +#define ASE_MAP_VSCALE(m) ((m)->scale[ASE_MAP_VAL]) + #define ASE_MAP_KPTR(p) ((p)->kptr) #define ASE_MAP_KLEN(p) ((p)->klen) #define ASE_MAP_VPTR(p) ((p)->vptr) #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 -/* - * NAME: create a map +/****f* ase/ase_map_open + * DESCRIPTION + * The ase_map_open() function creates a hashed table with a dynamic array + * bucket and a list of values chained. The initial capacity should be larger + * than 0. The load factor should be between 0 and 100 inclusive and the load + * factor of 0 disables bucket resizing. If you need extra space associated + * with a map, you may pass a non-zero value as the second parameter. + * The ASE_MAP_EXTENSION() macro and the ase_map_getextension() function + * return the pointer to the beginning of the extension. * - * DESCRIPTION: - * The ase_map_open() function creates a hashed map with a dynamic array - * bucket and a list of values linked. + * RETURN + * The ase_map_open() function returns an ase_map_t pointer on success and + * ASE_NULL on failure. + * + * SEE ALSO + * ASE_MAP_EXTENSION, ase_map_getextension + * + * SYNOPSIS */ ase_map_t* ase_map_open ( - ase_mmgr_t* mmgr /* memory manager */, - ase_size_t ext /* size of extension area in bytes */, - ase_size_t capa /* initial capacity */, - ase_uint_t factor /* load factor */ + ase_mmgr_t* mmgr /* a memory manager */, + ase_size_t ext /* extension size in bytes */, + ase_size_t capa /* initial capacity */, + int factor /* load factor */ ); +/*****/ -/* destroy a map */ + +/****f* ase/ase_map_close + * DESCRIPTION + * The ase_map_close() function creates a hashed map with a dynamic array + * bucket and a list of values linked. + * + * SYNOPSIS + */ void ase_map_close ( ase_map_t* map /* a map */ ); +/*****/ ase_map_t* ase_map_init ( ase_map_t* map, ase_mmgr_t* mmgr, ase_size_t capa, - ase_uint_t factor + int factor ); void ase_map_fini ( @@ -176,10 +230,36 @@ void ase_map_clear ( ase_map_t* map /* a map */ ); -/* - * NAME: specifies how to clone an element +int ase_map_getscale ( + ase_map_t* map, + int id +); + +/****f* ase/ase_map_setscale * - * DESCRIPTION: + * DESCRIPTION + * The ase_map_setscale() function sets the scale factor of the length + * of a key and a value. A map is created with a scale factor of 1. + * The scale factor should be larger than 0 and less than 256. + * + * RETURN + * ASE_NULL on failure + * + * SYNOPSIS + */ +void ase_map_setscale ( + ase_map_t* map /* a map */, + int id /* ASE_MAP_KEY or ASE_MAP_VAL */, + int scale /* a scale factor */ +); +/*****/ + + +/****f* ase/ase_map_setcopier + * NAME + * ase_map_setcopier - specify 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. @@ -192,6 +272,7 @@ void ase_map_setcopier ( int id /* ASE_MAP_KEY or ASE_MAP_VAL */, ase_map_copier_t copier /* a element copier */ ); +/*****/ ase_map_copier_t ase_map_getcopier ( ase_map_t* map /* a map */, diff --git a/ase/lib/awk/awk.c b/ase/lib/awk/awk.c index da7df7ff..71c2b622 100644 --- a/ase/lib/awk/awk.c +++ b/ase/lib/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 382 2008-09-24 11:36:45Z baconevi $ + * $Id: awk.c 385 2008-09-25 11:06:33Z baconevi $ * * {License} */ @@ -222,7 +222,7 @@ ase_awk_t* ase_awk_open (ase_mmgr_t* mmgr, ase_size_t ext) return ASE_NULL; } *(ase_awk_t**)ASE_MAP_EXTENSION(awk->bfn.user) = awk; - ase_map_setcopier (awk->bfn.user, AES_MAP_KEY, ASE_MAP_COPIER_INLINE); + ase_map_setcopier (awk->bfn.user, ASE_MAP_KEY, ASE_MAP_COPIER_INLINE); ase_map_setfreeer (awk->bfn.user, ASE_MAP_VAL, free_bfn); awk->parse.depth.cur.block = 0; diff --git a/ase/lib/cmn/map.c b/ase/lib/cmn/map.c index 96542bd1..eb9620b8 100644 --- a/ase/lib/cmn/map.c +++ b/ase/lib/cmn/map.c @@ -1,5 +1,5 @@ /* - * $Id: map.c 376 2008-09-24 07:18:50Z baconevi $ + * $Id: map.c 385 2008-09-25 11:06:33Z baconevi $ * * {License} */ @@ -29,6 +29,9 @@ #define uint_t ase_uint_t #define mmgr_t ase_mmgr_t +#define KTOB(map,len) ((len)*(map)->scale[ASE_MAP_KEY]) +#define VTOB(map,len) ((len)*(map)->scale[ASE_MAP_VAL]) + static int reorganize (map_t* map); static size_t hash_key (map_t* map, const void* kptr, size_t klen) @@ -50,7 +53,7 @@ static int comp_key (map_t* map, const void* kptr1, size_t klen1, const void* kptr2, size_t klen2) { - if (klen1 == klen2) return ASE_MEMCMP (kptr1, kptr2, klen1); + if (klen1 == klen2) return ASE_MEMCMP (kptr1, kptr2, KTOB(map,klen1)); /* it just returns 1 to indicate that they are different. */ return 1; } @@ -63,8 +66,8 @@ 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; + if (kcop == ASE_MAP_COPIER_INLINE) as += KTOB(map,klen); + if (vcop == ASE_MAP_COPIER_INLINE) as += VTOB(map,vlen); n = (pair_t*) ASE_MMGR_ALLOC (map->mmgr, as); if (n == ASE_NULL) return ASE_NULL; @@ -79,7 +82,7 @@ static pair_t* alloc_pair (map_t* map, else if (kcop == ASE_MAP_COPIER_INLINE) { KPTR(n) = n + 1; - ASE_MEMCPY (KPTR(n), kptr, klen); + ASE_MEMCPY (KPTR(n), kptr, KTOB(map,klen)); } else { @@ -100,8 +103,8 @@ static pair_t* alloc_pair (map_t* map, { VPTR(n) = n + 1; if (kcop == ASE_MAP_COPIER_INLINE) - VPTR(n) = (byte_t*)VPTR(n) + klen; - ASE_MEMCPY (VPTR(n), vptr, vlen); + VPTR(n) = (byte_t*)VPTR(n) + KTOB(map,klen); + ASE_MEMCPY (VPTR(n), vptr, VTOB(map,vlen)); } else { @@ -156,7 +159,7 @@ static pair_t* change_pair_val ( { if (ovlen == vlen) { - ASE_MEMCPY (VPTR(pair), vptr, vlen); + ASE_MEMCPY (VPTR(pair), vptr, VTOB(map,vlen)); } else { @@ -188,7 +191,7 @@ static pair_t* change_pair_val ( return pair; } -map_t* ase_map_open (mmgr_t* mmgr, size_t ext, size_t capa, uint_t factor) +map_t* ase_map_open (mmgr_t* mmgr, size_t ext, size_t capa, int factor) { map_t* map; @@ -220,7 +223,7 @@ void ase_map_close (map_t* map) ASE_MMGR_FREE (map->mmgr, map); } -map_t* ase_map_init (map_t* map, mmgr_t* mmgr, size_t capa, uint_t factor) +map_t* ase_map_init (map_t* map, mmgr_t* mmgr, size_t capa, int factor) { ASE_ASSERTX (capa > 0, "The initial capacity should be greater than 0. Otherwise, it is adjusted to 1 in the release mode"); @@ -241,9 +244,12 @@ map_t* ase_map_init (map_t* map, mmgr_t* mmgr, size_t capa, uint_t factor) /*for (i = 0; i < capa; i++) map->bucket[i] = ASE_NULL;*/ ASE_MEMSET (map->bucket, 0, capa*SIZEOF(pair_t*)); + map->scale[ASE_MAP_KEY] = 1; + map->scale[ASE_MAP_VAL] = 1; + map->factor = factor; + map->size = 0; map->capa = capa; - map->factor = factor; map->threshold = map->capa * map->factor / 100; map->hasher = hash_key; @@ -288,6 +294,27 @@ void ase_map_clear (map_t* map) } } +int ase_map_getscale (map_t* map, int id) +{ + ASE_ASSERTX (id == ASE_MAP_KEY || id == ASE_MAP_VAL, + "The ID should be either ASE_MAP_KEY or ASE_MAP_VAL"); + return map->scale[id]; +} + +void ase_map_setscale (map_t* map, int id, int scale) +{ + ASE_ASSERTX (id == ASE_MAP_KEY || id == ASE_MAP_VAL, + "The ID should be either ASE_MAP_KEY or ASE_MAP_VAL"); + + ASE_ASSERTX (scale > 0 && scale <= ASE_TYPE_MAX(ase_byte_t), + "The scale should be larger than 0 and less than or equal to the maximum value that the ase_byte_t type can hold"); + + if (scale <= 0) scale = 1; + if (scale > ASE_TYPE_MAX(ase_byte_t)) scale = ASE_TYPE_MAX(ase_byte_t); + + map->scale[id] = scale; +} + copier_t ase_map_getcopier (map_t* map, int id) { ASE_ASSERTX (id == ASE_MAP_KEY || id == ASE_MAP_VAL, @@ -404,6 +431,7 @@ pair_t* ase_map_search (map_t* map, const void* kptr, size_t klen) return ASE_NULL; } + int ase_map_put ( map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen, pair_t** px) @@ -472,8 +500,7 @@ pair_t* ase_map_upsert ( return px; } -pair_t* ase_map_insert ( - map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen) +pair_t* ase_map_insert (map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen) { pair_t* pair; size_t hc; @@ -511,8 +538,7 @@ pair_t* ase_map_insert ( return pair; } -pair_t* ase_map_update ( - map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen) +pair_t* ase_map_update (map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen) { pair_t* pair, * p, * prev, * next; size_t hc;