fixed minor problems in a map

This commit is contained in:
hyung-hwan 2008-09-27 01:26:20 +00:00
parent 7e13bc23fc
commit 8480da56d1
4 changed files with 160 additions and 50 deletions

View File

@ -2,8 +2,6 @@ items:
NAME NAME
SYNOPSIS SYNOPSIS
DESCRIPTION DESCRIPTION
ATTRIBUTES
PARAMETERS
RETURN RETURN
SEE ALSO SEE ALSO
BUGS BUGS
@ -16,8 +14,6 @@ item order:
NAME NAME
SYNOPSIS SYNOPSIS
DESCRIPTION DESCRIPTION
ATTRIBUTES
PARAMETERS
RETURN RETURN
SEE ALSO SEE ALSO
BUGS BUGS
@ -27,3 +23,10 @@ remark begin markers:
/* /*
remark end markers: remark end markers:
*/ */
ignore files:
.svn
headertypes:
o "Overview" robo_overview 0
options:
--nosort
--cmode

View File

@ -1,5 +1,5 @@
/* /*
* $Id: map.h 385 2008-09-25 11:06:33Z baconevi $ * $Id: map.h 388 2008-09-26 07:26:20Z baconevi $
* *
* {License} * {License}
*/ */
@ -10,6 +10,20 @@
#include <ase/types.h> #include <ase/types.h>
#include <ase/macros.h> #include <ase/macros.h>
/****o* ase.cmn.map/map.h
* DESCRIPTION
* A hash map maintains buckets for key/value pairs with the same key hash
* chained under the same bucket.
*
* #include <ase/cmn/map.h>
*
* EXAMPLES
* void f (void)
* {
* }
******
*/
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; typedef enum ase_map_walk_t ase_map_walk_t;
@ -35,24 +49,47 @@ typedef ase_size_t (*ase_map_hasher_t) (
ase_size_t klen /* the length of a key in bytes */ ase_size_t klen /* the length of a key in bytes */
); );
/* key comparater */ /****t* ase.cmn.map/ase_map_comper_t
* NAME
* ase_map_comper_t - define a key comparator
*
* DESCRIPTION
* The ase_map_comper_t type defines a key comparator that is called when
* the map needs to compare keys. A map is created with a default comparator
* which performs bitwise comparison between two keys.
*
* The comparator should return 0 if the keys are the same and a non-zero
* integer otherwise.
*
* SYNOPSIS
*/
typedef int (*ase_map_comper_t) ( typedef int (*ase_map_comper_t) (
ase_map_t* map /* a map */, ase_map_t* map /* a map */,
const void* kptr1 /* the pointer to a key */, const void* kptr1 /* the pointer to a key */,
ase_size_t klen1 /* the length of a key in bytes */, ase_size_t klen1 /* the length of a key */,
const void* kptr2 /* the pointer to a key */, const void* kptr2 /* the pointer to a key */,
ase_size_t klen2 /* the length of a key in bytes */ ase_size_t klen2 /* the length of a key */
); );
/******/
/* /****t* ase.cmn.map/ase_map_keeper_t
* value keeper * NAME
* it is called when a value can be kept without explicit free and copy * ase_map_keeper_t - define a value keeper
*
* DESCRIPTION
* The ase_map_keeper_t type defines a value keeper that is called when
* a value is retained in the context that it should be destroyed because
* it is identical to a new value. Two values are identical if their beginning
* pointers and their lengths are equal.
*
* SYNOPSIS
*/ */
typedef void (*ase_map_keeper_t) ( typedef void (*ase_map_keeper_t) (
ase_map_t* map, ase_map_t* map /* a map */,
void* dptr, void* vptr /* the pointer to a value */,
ase_size_t dlen ase_size_t vlen /* the length of a value */
); );
/******/
/* /*
* bucket resizer * bucket resizer
@ -66,36 +103,40 @@ typedef ase_map_walk_t (*ase_map_walker_t) (
void* arg /* the pointer to user-defined data */ void* arg /* the pointer to user-defined data */
); );
/****s* ase/ase_map_pair_t /****s* ase.cmn.map/ase_map_pair_t
* NAME * NAME
* ase_map_pair_t - define a pair * ase_map_pair_t - define a pair
*
* DESCRIPTION * DESCRIPTION
* A pair is composed of a key and a value. It maintains pointers to the * 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 * 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 * down with the scale factor specified in an owning map. Use macros defined
* in the SEE ALSO section below to access individual attributes. * in the SEE ALSO section below to access individual fields.
* 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 * SEE ALSO
* ASE_MAP_KPTR, ASE_MAP_KLEN, ASE_MAP_VPTR, ASE_MAP_VLEN * ASE_MAP_KPTR, ASE_MAP_KLEN, ASE_MAP_VPTR, ASE_MAP_VLEN
* SOURCE *
* SYNOPSIS
*/ */
struct ase_map_pair_t struct ase_map_pair_t
{ {
void* kptr; void* kptr; /* the pointer to a key */
ase_size_t klen; ase_size_t klen; /* the length of a key */
void* vptr; void* vptr; /* the pointer to a value */
ase_size_t vlen; ase_size_t vlen; /* the length of a value */
/* an internal pointer to the next pair chained */ /* an internal pointer to the next pair chained */
ase_map_pair_t* next; ase_map_pair_t* next;
}; };
/*****/ /*****/
/****s* ase.cmn.map/ase_map_t
* NAME
* ase_map_t - define a hash map
*
* SYNOPSIS
*/
struct ase_map_t struct ase_map_t
{ {
ase_mmgr_t* mmgr; ase_mmgr_t* mmgr;
@ -117,6 +158,7 @@ struct ase_map_t
ase_map_pair_t** bucket; ase_map_pair_t** bucket;
}; };
/******/
enum ase_map_id_t enum ase_map_id_t
{ {
@ -133,18 +175,26 @@ enum ase_map_walk_t
#define ASE_MAP_COPIER_INLINE ase_map_copyinline #define ASE_MAP_COPIER_INLINE ase_map_copyinline
/****d* ase/ASE_MAP_SIZE /****d* ase.cmn.map/ASE_MAP_SIZE
* NAME
* ASE_MAP_SIZE - get the number of pairs
*
* DESCRIPTION * DESCRIPTION
* The ASE_MAP_SIZE() macro returns the number of pairs in a map. * The ASE_MAP_SIZE() macro returns the number of pairs in a map.
* SOURCE *
* SYNOPSIS
*/ */
#define ASE_MAP_SIZE(m) ((m)->size) #define ASE_MAP_SIZE(m) ((m)->size)
/*****/ /*****/
/****d* ase/ASE_MAP_CAPA /****d* ase.cmn.map/ASE_MAP_CAPA
* NAME
* ASE_MAP_CAPA - get the capacity of a map
*
* DESCRIPTION * DESCRIPTION
* The ASE_MAP_CAPA() macro returns the maximum number of pairs a map can hold. * The ASE_MAP_CAPA() macro returns the maximum number of pairs a map can hold.
* SOURCE *
* SYNOPSIS
*/ */
#define ASE_MAP_CAPA(m) ((m)->capa) #define ASE_MAP_CAPA(m) ((m)->capa)
/*****/ /*****/
@ -174,9 +224,12 @@ enum ase_map_walk_t
extern "C" { extern "C" {
#endif #endif
/****f* ase/ase_map_open /****f* ase.cmn.map/ase_map_open
* NAME
* ase_map_open - creates a hash map
*
* DESCRIPTION * DESCRIPTION
* The ase_map_open() function creates a hashed table with a dynamic array * The ase_map_open() function creates a hash map with a dynamic array
* bucket and a list of values chained. The initial capacity should be larger * 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 * 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 * factor of 0 disables bucket resizing. If you need extra space associated
@ -199,20 +252,22 @@ ase_map_t* ase_map_open (
ase_size_t capa /* initial capacity */, ase_size_t capa /* initial capacity */,
int factor /* load factor */ int factor /* load factor */
); );
/*****/ /******/
/****f* ase/ase_map_close /****f* ase.cmn.map/ase_map_close
* NAME
* ase_map_close - destroy a hash map
*
* DESCRIPTION * DESCRIPTION
* The ase_map_close() function creates a hashed map with a dynamic array * The ase_map_close() function destroys a hash map.
* bucket and a list of values linked.
* *
* SYNOPSIS * SYNOPSIS
*/ */
void ase_map_close ( void ase_map_close (
ase_map_t* map /* a map */ ase_map_t* map /* a map */
); );
/*****/ /******/
ase_map_t* ase_map_init ( ase_map_t* ase_map_init (
ase_map_t* map, ase_map_t* map,
@ -235,7 +290,7 @@ int ase_map_getscale (
int id int id
); );
/****f* ase/ase_map_setscale /****f* ase.cmn.map/ase_map_setscale
* *
* DESCRIPTION * DESCRIPTION
* The ase_map_setscale() function sets the scale factor of the length * The ase_map_setscale() function sets the scale factor of the length
@ -252,10 +307,10 @@ void ase_map_setscale (
int id /* ASE_MAP_KEY or ASE_MAP_VAL */, int id /* ASE_MAP_KEY or ASE_MAP_VAL */,
int scale /* a scale factor */ int scale /* a scale factor */
); );
/*****/ /******/
/****f* ase/ase_map_setcopier /****f* ase.cmn.map/ase_map_setcopier
* NAME * NAME
* ase_map_setcopier - specify how to clone an element * ase_map_setcopier - specify how to clone an element
* *
@ -272,7 +327,7 @@ void ase_map_setcopier (
int id /* ASE_MAP_KEY or ASE_MAP_VAL */, int id /* ASE_MAP_KEY or ASE_MAP_VAL */,
ase_map_copier_t copier /* a element copier */ ase_map_copier_t copier /* a element copier */
); );
/*****/ /******/
ase_map_copier_t ase_map_getcopier ( ase_map_copier_t ase_map_getcopier (
ase_map_t* map /* a map */, ase_map_t* map /* a map */,

View File

@ -1,5 +1,5 @@
/* /*
* $Id: str.h 380 2008-09-24 08:16:41Z baconevi $ * $Id: str.h 388 2008-09-26 07:26:20Z baconevi $
* *
* {License} * {License}
*/ */
@ -10,6 +10,21 @@
#include <ase/types.h> #include <ase/types.h>
#include <ase/macros.h> #include <ase/macros.h>
/****o* ase.cmn.str/str.h
* DESCRIPTION
* <ase/cmn/str.h> defines various functions, types, macros to manipulate
* strings.
*
* #include <ase/cmn/str.h>
*
* EXAMPLES
* void f (void)
* {
* }
******
*/
#define ASE_STR_LEN(s) ((s)->len) #define ASE_STR_LEN(s) ((s)->len)
#define ASE_STR_PTR(s) ((s)->ptr) #define ASE_STR_PTR(s) ((s)->ptr)
#define ASE_STR_CAPA(s) ((s)->capa) #define ASE_STR_CAPA(s) ((s)->capa)
@ -114,9 +129,40 @@ int ase_strxncmp (
int ase_strcasecmp ( int ase_strcasecmp (
const ase_char_t* s1, const ase_char_t* s2, ase_ccls_t* ccls); const ase_char_t* s1, const ase_char_t* s2, ase_ccls_t* ccls);
/****f* ase.cmn.str/ase_strxncasecmp
* NAME
* ase_strxncasecmp - compare strings ignoring case
*
* DESCRIPTION
* The ase_strxncasecmp() function compares characters at the same position
* in each string after converting them to the same case temporarily.
* It accepts two strings and a character class handler. A string is
* represented by its beginning pointer and length. You can write your own
* character class handler or use ASE_CCLS_GETDFL() to get the default
* character class handler.
*
* For two strings to be equal, they need to have the same length and all
* characters in the first string should be equal to their counterpart in the
* second string.
*
* RETURN
* The ase_strxncasecmp() returns 0 if two strings are equal, a positive
* number if the first string is larger, -1 if the second string is larger.
*
* EXAMPLES
* ase_strxncasecmp (ASE_T("foo"), 3, ASE_T("FoO"), 3, ASE_CCLS_GETDFL());
*
* SYNOPSIS
*/
int ase_strxncasecmp ( int ase_strxncasecmp (
const ase_char_t* s1, ase_size_t len1, const ase_char_t* s1 /* the pointer to the first string */,
const ase_char_t* s2, ase_size_t len2, ase_ccls_t* ccls); ase_size_t len1 /* the length of the first string */,
const ase_char_t* s2 /* the pointer to the second string */,
ase_size_t len2 /* the length of the second string */,
ase_ccls_t* ccls /* character class handler */
);
/******/
ase_char_t* ase_strdup (const ase_char_t* str, ase_mmgr_t* mmgr); ase_char_t* ase_strdup (const ase_char_t* str, ase_mmgr_t* mmgr);
ase_char_t* ase_strxdup ( ase_char_t* ase_strxdup (
@ -207,21 +253,26 @@ void ase_str_fini (
ase_str_t* str ase_str_t* str
); );
/* /****f* ase.cmn.str/ase_str_yield
* NAME: yield the buffer * NAME
* ase_str_yield - yield the buffer
* *
* DESCRIPTION: * DESCRIPTION
* The ase_str_yield() function assigns the buffer to an variable of the * The ase_str_yield() function assigns the buffer to an variable of the
* ase_xstr_t type and recreate a new buffer of the new_capa capacity. * ase_xstr_t type and recreate a new buffer of the new_capa capacity.
* The function fails if it fails to allocate a new buffer. * The function fails if it fails to allocate a new buffer.
* *
* RETURNS: 0 on success, -1 on failure. * RETURN
* The ase_str_yield() function returns 0 on success, and -1 on failure.
*
* SYNOPSIS
*/ */
int ase_str_yield ( int ase_str_yield (
ase_str_t* str /* a dynamic string */, ase_str_t* str /* a dynamic string */,
ase_xstr_t* buf /* the pointer to a ase_xstr_t variable */, ase_xstr_t* buf /* the pointer to a ase_xstr_t variable */,
int new_capa /* new capacity in number of characters */ int new_capa /* new capacity in number of characters */
); );
/******/
void* ase_str_getextension ( void* ase_str_getextension (
ase_str_t* str ase_str_t* str

View File

@ -1,5 +1,5 @@
/* /*
* $Id: map.c 385 2008-09-25 11:06:33Z baconevi $ * $Id: map.c 388 2008-09-26 07:26:20Z baconevi $
* *
* {License} * {License}
*/ */
@ -133,7 +133,7 @@ static void free_pair (map_t* map, pair_t* pair)
static pair_t* change_pair_val ( static pair_t* change_pair_val (
map_t* map, pair_t* pair, void* vptr, size_t vlen) map_t* map, pair_t* pair, void* vptr, size_t vlen)
{ {
if (VPTR(pair) == vptr) if (VPTR(pair) == vptr && VLEN(pair) == vlen)
{ {
/* if the old value and the new value are the same, /* if the old value and the new value are the same,
* it just calls the handler for this condition. * it just calls the handler for this condition.
@ -251,6 +251,7 @@ map_t* ase_map_init (map_t* map, mmgr_t* mmgr, size_t capa, int factor)
map->size = 0; map->size = 0;
map->capa = capa; map->capa = capa;
map->threshold = map->capa * map->factor / 100; map->threshold = map->capa * map->factor / 100;
if (map->capa > 0 && map->threshold <= 0) map->threshold = 1;
map->hasher = hash_key; map->hasher = hash_key;
map->comper = comp_key; map->comper = comp_key;