diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index ef29ecab..527c960d 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 363 2010-10-27 12:54:37Z hyunghwan.chung $ + * $Id: awk.c 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -441,24 +441,9 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) goto oops; } - { - static qse_htb_mancbs_t mancbs = - { - { - QSE_HTB_COPIER_DEFAULT, /* remember the key pointer */ - QSE_HTB_COPIER_INLINE /* copy a value inline */ - }, - { - QSE_HTB_FREEER_DEFAULT, - QSE_HTB_FREEER_DEFAULT - }, - QSE_HTB_HASHER_DEFAULT, - QSE_HTB_COMPER_DEFAULT, - QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT - }; - qse_htb_setmancbs (gvm, &mancbs); - } + qse_htb_setmancbs (gvm, + qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_VALUE_COPIER) + ); while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF) { diff --git a/qse/include/qse/cmn/htb.h b/qse/include/qse/cmn/htb.h index f8523848..c626169d 100644 --- a/qse/include/qse/cmn/htb.h +++ b/qse/include/qse/cmn/htb.h @@ -1,5 +1,5 @@ /* - * $Id: htb.h 364 2010-10-28 13:09:53Z hyunghwan.chung $ + * $Id: htb.h 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -76,12 +76,6 @@ typedef void (*qse_htb_freeer_t) ( qse_size_t dlen /**< length of a key or a value */ ); -/* key hasher */ -typedef qse_size_t (*qse_htb_hasher_t) ( - qse_htb_t* htb, /**< hash table */ - const void* kptr, /**< key pointer */ - qse_size_t klen /**< key length in bytes */ -); /** * The qse_htb_comper_t type defines a key comparator that is called when @@ -92,10 +86,10 @@ typedef qse_size_t (*qse_htb_hasher_t) ( */ typedef int (*qse_htb_comper_t) ( qse_htb_t* htb, /**< hash table */ - const void* kptr1, /**< pointer to a key */ - qse_size_t klen1, /**< length of a key */ - const void* kptr2, /**< pointer to a key */ - qse_size_t klen2 /**< length of a key */ + const void* kptr1, /**< key pointer */ + qse_size_t klen1, /**< key length */ + const void* kptr2, /**< key pointer */ + qse_size_t klen2 /**< key length */ ); /** @@ -120,6 +114,15 @@ typedef qse_size_t (*qse_htb_sizer_t) ( qse_size_t hint /**< sizing hint */ ); +/** + * The qse_htb_hasher_t type defines a key hash function + */ +typedef qse_size_t (*qse_htb_hasher_t) ( + qse_htb_t* htb, /**< hash table */ + const void* kptr, /**< key pointer */ + qse_size_t klen /**< key length in bytes */ +); + /** * The qse_htb_walker_t defines a pair visitor. */ @@ -137,10 +140,10 @@ typedef qse_htb_walk_t (*qse_htb_walker_t) ( */ struct qse_htb_pair_t { - void* kptr; /**< pointer to a key */ - qse_size_t klen; /**< length of a key */ - void* vptr; /**< pointer to a value */ - qse_size_t vlen; /**< length of a value */ + void* kptr; /**< key pointer */ + qse_size_t klen; /**< key length */ + void* vptr; /**< value pointer */ + qse_size_t vlen; /**< value length */ /* management information below */ qse_htb_pair_t* next; @@ -152,12 +155,22 @@ struct qse_htb_mancbs_t { qse_htb_copier_t copier[2]; qse_htb_freeer_t freeer[2]; - qse_htb_hasher_t hasher; /**< key hasher */ qse_htb_comper_t comper; /**< key comparator */ qse_htb_keeper_t keeper; /**< value keeper */ qse_htb_sizer_t sizer; /**< bucket capacity recalculator */ + qse_htb_hasher_t hasher; /**< key hasher */ }; +enum qse_htb_mancbs_kind_t +{ + QSE_HTB_MANCBS_DEFAULT, + QSE_HTB_MANCBS_INLINE_COPIERS, + QSE_HTB_MANCBS_INLINE_KEY_COPIER, + QSE_HTB_MANCBS_INLINE_VALUE_COPIER +}; + +typedef enum qse_htb_mancbs_kind_t qse_htb_mancbs_kind_t; + /** * The qse_htb_t type defines a hash table. */ @@ -182,10 +195,10 @@ struct qse_htb_t #define QSE_HTB_COPIER_DEFAULT (QSE_HTB_COPIER_SIMPLE) #define QSE_HTB_FREEER_DEFAULT (QSE_NULL) -#define QSE_HTB_HASHER_DEFAULT (qse_htb_dflhash) #define QSE_HTB_COMPER_DEFAULT (qse_htb_dflcomp) #define QSE_HTB_KEEPER_DEFAULT (QSE_NULL) #define QSE_HTB_SIZER_DEFAULT (QSE_NULL) +#define QSE_HTB_HASHER_DEFAULT (qse_htb_dflhash) /** * The QSE_HTB_SIZE() macro returns the number of pairs in a hash table. @@ -214,23 +227,29 @@ extern "C" { QSE_DEFINE_COMMON_FUNCTIONS (htb) +const qse_htb_mancbs_t* qse_htb_mancbs ( + qse_htb_mancbs_kind_t kind +); + /** * The qse_htb_open() function creates a hash 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 hash table, you may pass a non-zero value as the second parameter. + * with hash table, you may pass a non-zero value for @a xtnsize. * The QSE_HTB_XTN() macro and the qse_htb_getxtn() function return the * pointer to the beginning of the extension. - * @return qse_htb_t pointer on success, QSE_NULL on failure. + * The @a kscale and @a vscale parameters specify the unit of the key and + * value size. + * @return #qse_htb_t pointer on success, #QSE_NULL on failure. */ qse_htb_t* qse_htb_open ( - qse_mmgr_t* mmgr, /**< memory manager */ - qse_size_t ext, /**< extension size in bytes */ - qse_size_t capa, /**< initial capacity */ - int factor, /**< load factor */ - int kscale, /**< key scale */ - int vscale /**< value scale */ + qse_mmgr_t* mmgr, /**< memory manager */ + qse_size_t xtnsize, /**< extension size in bytes */ + qse_size_t capa, /**< initial capacity */ + int factor, /**< load factor */ + int kscale, /**< key scale */ + int vscale /**< value scale */ ); @@ -260,6 +279,22 @@ void qse_htb_fini ( qse_htb_t* htb ); +/** + * The qse_htb_getmancbs() function gets manipulation callback function set. + */ +const qse_htb_mancbs_t* qse_htb_getmancbs ( + qse_htb_t* htb /**< hash table */ +); + +/** + * The qse_htb_setmancbs() function sets internal manipulation callback + * functions for data construction, destruction, resizing, hashing, etc. + */ +void qse_htb_setmancbs ( + qse_htb_t* htb, /**< hash table */ + const qse_htb_mancbs_t* mancbs /**< callback function set */ +); + /** * The qse_htb_getsize() function gets the number of pairs in hash table. */ @@ -275,50 +310,17 @@ qse_size_t qse_htb_getcapa ( qse_htb_t* htb /**< hash table */ ); -#if 0 -/** - * The qse_htb_getscale() function returns the scale factor - */ -int qse_htb_getscale ( - qse_htb_t* htb, /**< hash table */ - qse_htb_id_t id /**< QSE_HTB_KEY or QSE_HTB_VAL */ -); - -/** - * The qse_htb_setscale() function sets the scale factor of the length - * of a key and a value. A scale factor determines the actual length of - * a key and a value in bytes. A htb is created with a scale factor of 1. - * The scale factor should be larger than 0 and less than 256. - * Note that it is a bad idea to change the scale factor while a hash table - * is not empty. - */ -void qse_htb_setscale ( - qse_htb_t* htb, /**< hash table */ - qse_htb_id_t id, /**< QSE_HTB_KEY or QSE_HTB_VAL */ - int scale /**< scale factor in bytes */ -); -#endif - -const qse_htb_mancbs_t* qse_htb_getmancbs ( - qse_htb_t* htb -); - -void qse_htb_setmancbs ( - qse_htb_t* htb, - const qse_htb_mancbs_t* mancbs -); - /** * The qse_htb_search() function searches a hash table to find a pair with a * matching key. It returns the pointer to the pair found. If it fails * to find one, it returns QSE_NULL. * @return pointer to the pair with a maching key, - * or QSE_NULL if no match is found. + * or #QSE_NULL if no match is found. */ qse_htb_pair_t* qse_htb_search ( qse_htb_t* htb, /**< hash table */ - const void* kptr, /**< the pointer to a key */ - qse_size_t klen /**< the size of the key */ + const void* kptr, /**< key pointer */ + qse_size_t klen /**< key length */ ); /** @@ -326,72 +328,169 @@ qse_htb_pair_t* qse_htb_search ( * matching key. If one is found, it updates the pair. Otherwise, it inserts * a new pair with the key and value given. It returns the pointer to the * pair updated or inserted. - * @return a pointer to the updated or inserted pair on success, - * QSE_NULL on failure. + * @return pointer to the updated or inserted pair on success, + * #QSE_NULL on failure. */ qse_htb_pair_t* qse_htb_upsert ( qse_htb_t* htb, /**< hash table */ - void* kptr, /**< the pointer to a key */ - qse_size_t klen, /**< the length of the key */ - void* vptr, /**< the pointer to a value */ - qse_size_t vlen /**< the length of the value */ + void* kptr, /**< key pointer */ + qse_size_t klen, /**< key length */ + void* vptr, /**< value pointer */ + qse_size_t vlen /**< value length */ ); /** * The qse_htb_ensert() function inserts a new pair with the key and the value * given. If there exists a pair with the key given, the function returns * the pair containing the key. - * @return pointer to a pair on success, QSE_NULL on failure. + * @return pointer to a pair on success, #QSE_NULL on failure. */ qse_htb_pair_t* qse_htb_ensert ( qse_htb_t* htb, /**< hash table */ - void* kptr, /**< the pointer to a key */ - qse_size_t klen, /**< the length of the key */ - void* vptr, /**< the pointer to a value */ - qse_size_t vlen /**< the length of the value */ + void* kptr, /**< key pointer */ + qse_size_t klen, /**< key length */ + void* vptr, /**< value pointer */ + qse_size_t vlen /**< value length */ ); /** * The qse_htb_insert() function inserts a new pair with the key and the value * given. If there exists a pair with the key given, the function returns - * QSE_NULL without channging the value. - * @return pointer to the pair created on success, QSE_NULL on failure. + * #QSE_NULL without channging the value. + * @return pointer to the pair created on success, #QSE_NULL on failure. */ qse_htb_pair_t* qse_htb_insert ( qse_htb_t* htb, /**< hash table */ - void* kptr, /**< the pointer to a key */ - qse_size_t klen, /**< the length of the key */ - void* vptr, /**< the pointer to a value */ - qse_size_t vlen /**< the length of the value */ + void* kptr, /**< key pointer */ + qse_size_t klen, /**< key length */ + void* vptr, /**< value pointer */ + qse_size_t vlen /**< value length */ ); /** * The qse_htb_update() function updates the value of an existing pair * with a matching key. - * @return pointer to the pair on success, QSE_NULL on no matching pair + * @return pointer to the pair on success, #QSE_NULL on no matching pair */ qse_htb_pair_t* qse_htb_update ( qse_htb_t* htb, /**< hash table */ - void* kptr, /**< the pointer to a key */ - qse_size_t klen, /**< the length of the key */ - void* vptr, /**< the pointer to a value */ - qse_size_t vlen /**< the length of the value */ + void* kptr, /**< key pointer */ + qse_size_t klen, /**< key length */ + void* vptr, /**< value pointer */ + qse_size_t vlen /**< value length */ ); +/** + * The qse_htb_cbserter_t type defines a callback function for qse_htb_cbsert(). + * The qse_htb_cbserter() function calls it to allocate a new pair for the + * key pointed to by @a kptr of the length @a klen and the callback context + * @a ctx. The second parameter @a pair is passed the pointer to the existing + * pair for the key or #QSE_NULL in case of no existing key. The callback + * must return a pointer to a new or a reallocated pair. When reallocating the + * existing pair, this callback must destroy the existing pair and return the + * newly reallocated pair. It must return #QSE_NULL for failure. + */ typedef qse_htb_pair_t* (*qse_htb_cbserter_t) ( - qse_htb_t* htb, - qse_htb_pair_t* pair, - void* kptr, - qse_size_t klen, - void* ctx + qse_htb_t* htb, /**< hash table */ + qse_htb_pair_t* pair, /**< pair pointer */ + void* kptr, /**< key pointer */ + qse_size_t klen, /**< key length */ + void* ctx /**< callback context */ ); +/** + * The qse_htb_cbsert() function inserts a key/value pair by delegating pair + * allocation to a callback function. Depending on the callback function, + * it may behave like qse_htb_insert(), qse_htb_upsert(), qse_htb_update(), + * qse_htb_ensert(), or totally differently. The sample code below inserts + * a new pair if the key is not found and appends the new value to the + * existing value delimited by a comma if the key is found. + * + * @code + * qse_htb_walk_t print_map_pair (qse_htb_t* map, qse_htb_pair_t* pair, void* ctx) + * { + * qse_printf (QSE_T("%.*s[%d] => %.*s[%d]\n"), + * (int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair), (int)QSE_HTB_KLEN(pair), + * (int)QSE_HTB_VLEN(pair), QSE_HTB_VPTR(pair), (int)QSE_HTB_VLEN(pair)); + * return QSE_HTB_WALK_FORWARD; + * } + * + * qse_htb_pair_t* cbserter ( + * qse_htb_t* htb, qse_htb_pair_t* pair, + * void* kptr, qse_size_t klen, void* ctx) + * { + * qse_xstr_t* v = (qse_xstr_t*)ctx; + * if (pair == QSE_NULL) + * { + * // no existing key for the key + * return qse_htb_allocpair (htb, kptr, klen, v->ptr, v->len); + * } + * else + * { + * // a pair with the key exists. + * // in this sample, i will append the new value to the old value + * // separated by a comma + * qse_htb_pair_t* new_pair; + * qse_char_t comma = QSE_T(','); + * qse_byte_t* vptr; + * + * // allocate a new pair, but without filling the actual value. + * // note vptr is given QSE_NULL for that purpose + * new_pair = qse_htb_allocpair ( + * htb, kptr, klen, QSE_NULL, pair->vlen + 1 + v->len); + * if (new_pair == QSE_NULL) return QSE_NULL; + * + * // fill in the value space + * vptr = new_pair->vptr; + * qse_memcpy (vptr, pair->vptr, pair->vlen*QSE_SIZEOF(qse_char_t)); + * vptr += pair->vlen*QSE_SIZEOF(qse_char_t); + * qse_memcpy (vptr, &comma, QSE_SIZEOF(qse_char_t)); + * vptr += QSE_SIZEOF(qse_char_t); + * qse_memcpy (vptr, v->ptr, v->len*QSE_SIZEOF(qse_char_t)); + * + * // this callback requires the old pair to be destroyed + * qse_htb_freepair (htb, pair); + * + * // return the new pair + * return new_pair; + * } + * } + * + * int main () + * { + * qse_htb_t* s1; + * int i; + * qse_char_t* keys[] = { QSE_T("one"), QSE_T("two"), QSE_T("three") }; + * qse_char_t* vals[] = { QSE_T("1"), QSE_T("2"), QSE_T("3"), QSE_T("4"), QSE_T("5") }; + * + * s1 = qse_htb_open ( + * QSE_MMGR_GETDFL(), 0, 10, 70, + * QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t) + * ); // note error check is skipped + * qse_htb_setmancbs (s1, &mancbs1); + * + * for (i = 0; i < QSE_COUNTOF(vals); i++) + * { + * qse_xstr_t ctx; + * ctx.ptr = vals[i]; ctx.len = qse_strlen(vals[i]); + * qse_htb_cbsert (s1, + * keys[i%QSE_COUNTOF(keys)], qse_strlen(keys[i%QSE_COUNTOF(keys)]), + * cbserter, &ctx + * ); // note error check is skipped + * } + * qse_htb_walk (s1, print_map_pair, QSE_NULL); + * + * qse_htb_close (s1); + * return 0; + * } + * @endcode + */ qse_htb_pair_t* qse_htb_cbsert ( - qse_htb_t* htb, - void* kptr, - qse_size_t klen, - qse_htb_cbserter_t cbserter, - void* ctx + qse_htb_t* htb, /**< hash table */ + void* kptr, /**< key pointer */ + qse_size_t klen, /**< key length */ + qse_htb_cbserter_t cbserter, /**< callback function */ + void* ctx /**< callback context */ ); /** @@ -400,8 +499,8 @@ qse_htb_pair_t* qse_htb_cbsert ( */ int qse_htb_delete ( qse_htb_t* htb, /**< hash table */ - const void* kptr, /**< the pointer to a key */ - qse_size_t klen /**< the size of the key */ + const void* kptr, /**< key pointer */ + qse_size_t klen /**< key length */ ); /** @@ -442,7 +541,14 @@ qse_htb_pair_t* qse_htb_getnextpair ( /** * The qse_htb_allocpair() function allocates a pair for a key and a value * given. But it does not chain the pair allocated into the hash table @a htb. - * Use this function at your own risk. + * Use this function at your own risk. + * + * Take note of he following special behavior when the copier is + * #QSE_HTB_COPIER_INLINE. + * - If @a kptr is #QSE_NULL, the key space of the size @a klen is reserved but + * not propagated with any data. + * - If @a vptr is #QSE_NULL, the value space of the size @a vlen is reserved + * but not propagated with any data. */ qse_htb_pair_t* qse_htb_allocpair ( qse_htb_t* htb, @@ -462,12 +568,18 @@ void qse_htb_freepair ( qse_htb_pair_t* pair ); +/** + * The qse_htb_dflhash() function is a default hash function. + */ qse_size_t qse_htb_dflhash ( qse_htb_t* htb, const void* kptr, qse_size_t klen ); +/** + * The qse_htb_dflcomp() function is default comparator. + */ int qse_htb_dflcomp ( qse_htb_t* htb, const void* kptr1, diff --git a/qse/include/qse/cmn/map.h b/qse/include/qse/cmn/map.h index 4dc16b58..8ec21276 100644 --- a/qse/include/qse/cmn/map.h +++ b/qse/include/qse/cmn/map.h @@ -29,26 +29,19 @@ #if defined(QSE_MAP_AS_HTB) # include -# define qse_map_open(mmgr,ext,capa,factor) qse_htb_open(mmgr,ext,capa,factor) +# define QSE_MAP_MANCBS_DEFAULT QSE_HTB_MANCBS_DEFAULT +# define QSE_MAP_MANCBS_INLINE_COPIERS QSE_HTB_MANCBS_INLINE_COPIERS +# define QSE_MAP_MANCBS_INLINE_KEY_COPIER QSE_HTB_MANCBS_INLINE_KEY_COPIER +# define QSE_MAP_MANCBS_INLINE_VALUE_COPIER QSE_HTB_MANCBS_INLINE_VALUE_COPIER +# define qse_map_mancbs(kind) qse_htb_mancbs(kind) +# define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_htb_open(mmgr,ext,capa,factor,ks,vs) # define qse_map_close(map) qse_htb_close(map) -# define qse_map_init(map,mmgr,capa,factor) qse_htb_init(map,mmgr,capa,factor) +# define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_htb_init(map,mmgr,capa,factor,ks,vs) # define qse_map_fini(map) qse_htb_fini(map) # define qse_map_getsize(map) qse_htb_getsize(map) # define qse_map_getcapa(map) qse_htb_getcapa(map) -# define qse_map_getscale(map,id) qse_htb_getscale(map,id) -# define qse_map_setscale(map,id,scale) qse_htb_setscale(map,id,scale) -# define qse_map_getcopier(map,id) qse_htb_getcopier(map,id) -# define qse_map_setcopier(map,id,cb) qse_htb_setcopier(map,id,cb) -# define qse_map_getfreeer(map,id) qse_htb_getfreeer(map,id) -# define qse_map_setfreeer(map,id,cb) qse_htb_setfreeer(map,id,cb) -# define qse_map_getcomper(map,id) qse_htb_getcomper(map,id) -# define qse_map_setcomper(map,id,cb) qse_htb_setcomper(map,id,cb) -# define qse_map_getkeeper(map,id) qse_htb_getkeeper(map,id) -# define qse_map_setkeeper(map,id,cb) qse_htb_setkeeper(map,id,cb) -# define qse_map_gethasher(map) qse_htb_gethasher(map) -# define qse_map_sethasher(map,cb) qse_htb_sethasher(map,cb) -# define qse_map_getsizer(map) qse_htb_getsizer(map) -# define qse_map_setsizer(map,cb) qse_htb_setsizer(map,cb) +# define qse_map_getmancbs(map) qse_htb_getmancbs(map) +# define qse_map_setmancbs(map,cbs) qse_htb_setmancbs(map,cbs) # define qse_map_search(map,kptr,klen) qse_htb_search(map,kptr,klen) # define qse_map_upsert(map,kptr,klen,vptr,vlen) qse_htb_upsert(map,kptr,klen,vptr,vlen) # define qse_map_ensert(map,kptr,klen,vptr,vlen) qse_htb_ensert(map,kptr,klen,vptr,vlen) @@ -58,15 +51,22 @@ # define qse_map_clear(map) qse_htb_clear(map) # define qse_map_walk(map,walker,ctx) qse_htb_walk(map,walker,ctx) # define QSE_MAP_WALK_STOP QSE_HTB_WALK_STOP -# define QSE_MAP_WALK_FORWARD QSE_HTB_WALK_FORWARD +# define QSE_MAP_WALK_FORWARD QSE_HTB_WALK_FORWARD # define qse_map_walk_t qse_htb_walk_t # define QSE_MAP_KEY QSE_HTB_KEY # define QSE_MAP_VAL QSE_HTB_VAL # define qse_map_id_t qse_htb_id_t # define qse_map_t qse_htb_t # define qse_map_pair_t qse_htb_pair_t +# define qse_map_mancbs_t qse_htb_mancbs_t # define QSE_MAP_COPIER_SIMPLE QSE_HTB_COPIER_SIMPLE # define QSE_MAP_COPIER_INLINE QSE_HTB_COPIER_INLINE +# define QSE_MAP_COPIER_DEFAULT QSE_HTB_COPIER_DEFAULT +# define QSE_MAP_FREEER_DEFAULT QSE_HTB_FREEER_DEFAULT +# define QSE_MAP_COMPER_DEFAULT QSE_HTB_COMPER_DEFAULT +# define QSE_MAP_KEEPER_DEFAULT QSE_HTB_KEEPER_DEFAULT +# define QSE_MAP_SIZER_DEFAULT QSE_HTB_SIZER_DEFAULT +# define QSE_MAP_HASHER_DEFAULT QSE_HTB_HASHER_DEFAULT # define QSE_MAP_SIZE(map) QSE_HTB_SIZE(map) # define QSE_MAP_KCOPIER(map) QSE_HTB_KCOPIER(map) # define QSE_MAP_VCOPIER(map) QSE_HTB_VCOPIER(map) @@ -82,26 +82,19 @@ # define QSE_MAP_VLEN(p) QSE_HTB_VLEN(p) #elif defined(QSE_MAP_AS_RBT) # include -# define qse_map_open(mmgr,ext,capa,factor) qse_rbt_open(mmgr,ext) +# define QSE_MAP_MANCBS_DEFAULT QSE_RBT_MANCBS_DEFAULT +# define QSE_MAP_MANCBS_INLINE_COPIERS QSE_RBT_MANCBS_INLINE_COPIERS +# define QSE_MAP_MANCBS_INLINE_KEY_COPIER QSE_RBT_MANCBS_INLINE_KEY_COPIER +# define QSE_MAP_MANCBS_INLINE_VALUE_COPIER QSE_RBT_MANCBS_INLINE_VALUE_COPIER +# define qse_map_mancbs(kind) qse_rbt_mancbs(kind) +# define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_rbt_open(mmgr,ext,ks,vs) # define qse_map_close(map) qse_rbt_close(map) -# define qse_map_init(map,mmgr,capa,factor) qse_rbt_init(map,mmgr) +# define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_rbt_init(map,mmgr,ks,vs) # define qse_map_fini(map) qse_rbt_fini(map) # define qse_map_getsize(map) qse_rbt_getsize(map) -# define qse_map_getcapa(map) qse_rbt_getcapa(map) -# define qse_map_getscale(map,id) qse_rbt_getscale(map,id) -# define qse_map_setscale(map,id,scale) qse_rbt_setscale(map,id,scale) -# define qse_map_getcopier(map,id) qse_rbt_getcopier(map,id) -# define qse_map_setcopier(map,id,cb) qse_rbt_setcopier(map,id,cb) -# define qse_map_getfreeer(map,id) qse_rbt_getfreeer(map,id) -# define qse_map_setfreeer(map,id,cb) qse_rbt_setfreeer(map,id,cb) -# define qse_map_getcomper(map,id) qse_rbt_getcomper(map,id) -# define qse_map_setcomper(map,id,cb) qse_rbt_setcomper(map,id,cb) -# define qse_map_getkeeper(map,id) qse_rbt_getkeeper(map,id) -# define qse_map_setkeeper(map,id,cb) qse_rbt_setkeeper(map,id,cb) -# define qse_map_gethasher(map,id) -# define qse_map_sethasher(map,id,cb) -# define qse_map_getsizer(map,id) -# define qse_map_setsizer(map,id,cb) +# define qse_map_getcapa(map) qse_rbt_getsize(map) +# define qse_map_getmancbs(map) qse_rbt_getmancbs(map) +# define qse_map_setmancbs(map,cbs) qse_rbt_setmancbs(map,cbs) # define qse_map_search(map,kptr,klen) qse_rbt_search(map,kptr,klen) # define qse_map_upsert(map,kptr,klen,vptr,vlen) qse_rbt_upsert(map,kptr,klen,vptr,vlen) # define qse_map_ensert(map,kptr,klen,vptr,vlen) qse_rbt_ensert(map,kptr,klen,vptr,vlen) @@ -111,15 +104,22 @@ # define qse_map_clear(map) qse_rbt_clear(map) # define qse_map_walk(map,walker,ctx) qse_rbt_walk(map,walker,ctx) # define QSE_MAP_WALK_STOP QSE_RBT_WALK_STOP -# define QSE_MAP_WALK_FORWARD QSE_RBT_WALK_FORWARD +# define QSE_MAP_WALK_FORWARD QSE_RBT_WALK_FORWARD # define qse_map_walk_t qse_rbt_walk_t # define QSE_MAP_KEY QSE_RBT_KEY # define QSE_MAP_VAL QSE_RBT_VAL # define qse_map_id_t qse_rbt_id_t # define qse_map_t qse_rbt_t # define qse_map_pair_t qse_rbt_pair_t +# define qse_map_mancbs_t qse_rbt_mancbs_t # define QSE_MAP_COPIER_SIMPLE QSE_RBT_COPIER_SIMPLE # define QSE_MAP_COPIER_INLINE QSE_RBT_COPIER_INLINE +# define QSE_MAP_COPIER_DEFAULT QSE_RBT_COPIER_DEFAULT +# define QSE_MAP_FREEER_DEFAULT QSE_RBT_FREEER_DEFAULT +# define QSE_MAP_COMPER_DEFAULT QSE_RBT_COMPER_DEFAULT +# define QSE_MAP_KEEPER_DEFAULT QSE_RBT_KEEPER_DEFAULT +/*# define QSE_MAP_SIZER_DEFAULT +# define QSE_MAP_HASHER_DEFAULT*/ # define QSE_MAP_SIZE(map) QSE_RBT_SIZE(map) # define QSE_MAP_KCOPIER(map) QSE_RBT_KCOPIER(map) # define QSE_MAP_VCOPIER(map) QSE_RBT_VCOPIER(map) diff --git a/qse/include/qse/cmn/rbt.h b/qse/include/qse/cmn/rbt.h index 597b15dc..4cc98055 100644 --- a/qse/include/qse/cmn/rbt.h +++ b/qse/include/qse/cmn/rbt.h @@ -130,6 +130,26 @@ struct qse_rbt_pair_t qse_rbt_pair_t* child[2]; /* left and right */ }; +typedef struct qse_rbt_mancbs_t qse_rbt_mancbs_t; + +struct qse_rbt_mancbs_t +{ + qse_rbt_copier_t copier[2]; /**< key and value copier */ + qse_rbt_freeer_t freeer[2]; /**< key and value freeer */ + qse_rbt_comper_t comper; /**< key comparator */ + qse_rbt_keeper_t keeper; /**< value keeper */ +}; + +enum qse_rbt_mancbs_kind_t +{ + QSE_RBT_MANCBS_DEFAULT, + QSE_RBT_MANCBS_INLINE_COPIERS, + QSE_RBT_MANCBS_INLINE_KEY_COPIER, + QSE_RBT_MANCBS_INLINE_VALUE_COPIER +}; + +typedef enum qse_rbt_mancbs_kind_t qse_rbt_mancbs_kind_t; + /** * The qse_rbt_t type defines a red-black tree. */ @@ -137,10 +157,7 @@ struct qse_rbt_t { QSE_DEFINE_COMMON_FIELDS (rbt) - qse_rbt_copier_t copier[2]; /**< key and value copier */ - qse_rbt_freeer_t freeer[2]; /**< key and value freeer */ - qse_rbt_comper_t comper; /**< key comparator */ - qse_rbt_keeper_t keeper; /**< value keeper */ + const qse_rbt_mancbs_t* mancbs; qse_byte_t scale[2]; /**< length scale */ @@ -162,6 +179,11 @@ struct qse_rbt_t */ #define QSE_RBT_COPIER_INLINE ((qse_rbt_copier_t)2) +#define QSE_RBT_COPIER_DEFAULT (QSE_RBT_COPIER_SIMPLE) +#define QSE_RBT_FREEER_DEFAULT (QSE_NULL) +#define QSE_RBT_COMPER_DEFAULT (qse_rbt_dflcomp) +#define QSE_RBT_KEEPER_DEFAULT (QSE_NULL) + /** * The QSE_RBT_SIZE() macro returns the number of pairs in red-black tree. */ @@ -181,13 +203,19 @@ extern "C" { QSE_DEFINE_COMMON_FUNCTIONS (rbt) +const qse_rbt_mancbs_t* qse_rbt_mancbs ( + qse_rbt_mancbs_kind_t kind +); + /** * The qse_rbt_open() function creates a red-black tree. * @return qse_rbt_t pointer on success, QSE_NULL on failure. */ qse_rbt_t* qse_rbt_open ( - qse_mmgr_t* mmgr, /**< memory manager */ - qse_size_t ext /**< extension size in bytes */ + qse_mmgr_t* mmgr, /**< memory manager */ + qse_size_t xtnsize, /**< extension size in bytes */ + int kscale, /**< key scale */ + int vscale /**< value scale */ ); /** @@ -201,8 +229,10 @@ void qse_rbt_close ( * The qse_rbt_init() function initializes a red-black tree */ qse_rbt_t* qse_rbt_init ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_mmgr_t* mmgr /**< memory manager */ + qse_rbt_t* rbt, /**< red-black tree */ + qse_mmgr_t* mmgr, /**< memory manager */ + int kscale, /**< key scale */ + int vscale /**< value scale */ ); /** @@ -213,105 +243,26 @@ void qse_rbt_fini ( ); /** - * The qse_rbt_getsize() function gets the number of pairs in red-black tree. + * The qse_rbt_getmancbs() function gets manipulation callback function set. */ -qse_size_t qse_rbt_getsize ( - qse_rbt_t* rbt /**< red-black tree */ -); - -/** - * The qse_rbt_getscale() function returns the scale factor - */ -int qse_rbt_getscale ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_rbt_id_t id /**< #QSE_RBT_KEY or #QSE_RBT_VAL */ -); - -/** - * The qse_rbt_setscale() function sets the scale factor of the length - * of a key and a value. A scale factor determines the actual length of - * a key and a value in bytes. A rbt is created with a scale factor of 1. - * The scale factor should be larger than 0 and less than 256. - * Note that it is a bad idea to change the scale factor while a red-black tree - * is not empty. - */ -void qse_rbt_setscale ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_rbt_id_t id, /**< #QSE_RBT_KEY or #QSE_RBT_VAL */ - int scale /**< scale factor in bytes */ -); - -/** - * The qse_rbt_getcopier() function gets a data copier. - */ -qse_rbt_copier_t qse_rbt_getcopier ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_rbt_id_t id /**< #QSE_RBT_KEY or #QSE_RBT_VAL */ -); - -/** - * The qse_rbt_setcopier() function specifies how to clone an element. - * A special copier QSE_RBT_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. - * - * You may set the copier to QSE_NULL to perform no special operation - * when the data pointer is rememebered. - */ -void qse_rbt_setcopier ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_rbt_id_t id, /**< #QSE_RBT_KEY or #QSE_RBT_VAL */ - qse_rbt_copier_t copier /**< callback for copying a key or a value */ -); - -/** - * The qse_rb_getfreeer() function returns the element destroyer. - */ -qse_rbt_freeer_t qse_rbt_getfreeer ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_rbt_id_t id /**< #QSE_RBT_KEY or #QSE_RBT_VAL */ -); - -/** - * The qse_rbt_setfreeer() function specifies how to destroy an element. - * The @a freeer is called when a node containing the element is destroyed. - */ -void qse_rbt_setfreeer ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_rbt_id_t id, /**< #QSE_RBT_KEY or #QSE_RBT_VAL */ - qse_rbt_freeer_t freeer /**< callback for destroying a key or a value */ -); - -/** - * The qse_rbt_getcomper() function returns the key comparator. - */ -qse_rbt_comper_t qse_rbt_getcomper ( +const qse_rbt_mancbs_t* qse_rbt_getmancbs ( qse_rbt_t* rbt /**< red-black tree */ ); /** - * The qse_rbt_setcomper() function changes the key comparator. + * The qse_rbt_setmancbs() function sets internal manipulation callback + * functions for data construction, destruction, resizing, hashing, etc. */ -void qse_rbt_setcomper ( - qse_rbt_t* rbt, /**< red-black tree */ - qse_rbt_comper_t comper /**< comparator function pointer */ +void qse_rbt_setmancbs ( + qse_rbt_t* rbt, /**< red-black tree */ + const qse_rbt_mancbs_t* mancbs /**< callback function set */ ); /** - * The qse_rbt_getkeeper() function returns the value retainer function - * that is called when you change the value of an existing key with the - * same value. + * The qse_rbt_getsize() function gets the number of pairs in red-black tree. */ -qse_rbt_keeper_t qse_rbt_getkeeper ( - qse_rbt_t* rbt -); - -/** - * The qse_rbt_setkeeper() function changes the value retainer function. - */ -void qse_rbt_setkeeper ( - qse_rbt_t* rbt, - qse_rbt_keeper_t keeper +qse_size_t qse_rbt_getsize ( + qse_rbt_t* rbt /**< red-black tree */ ); /** @@ -421,6 +372,14 @@ void qse_rbt_rwalk ( void* ctx /**< pointer to user-specific data */ ); +int qse_rbt_dflcomp ( + qse_rbt_t* rbt, + const void* kptr1, + qse_size_t klen1, + const void* kptr2, + qse_size_t klen2 +); + #ifdef __cplusplus } #endif diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 3ab3a327..8a61d894 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 363 2010-10-27 12:54:37Z hyunghwan.chung $ + * $Id: Awk.cpp 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -1152,18 +1152,12 @@ int Awk::open () QSE_HTB_FREEER_DEFAULT, free_function_map_value }, - QSE_HTB_HASHER_DEFAULT, QSE_HTB_COMPER_DEFAULT, QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT }; - qse_htb_setmancbs (functionMap, &mancbs); -#if 0 - qse_htb_setscale (functionMap, QSE_HTB_KEY, QSE_SIZEOF(qse_char_t)); - qse_htb_setcopier (functionMap, QSE_HTB_KEY, QSE_HTB_COPIER_INLINE); - qse_htb_setfreeer (functionMap, QSE_HTB_VAL, free_function_map_value); -#endif return 0; } diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index e1528256..d3707a59 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 363 2010-10-27 12:54:37Z hyunghwan.chung $ + * $Id: awk.c 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -77,38 +77,6 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) { qse_awk_t* awk; - static qse_htb_mancbs_t mancbs1 = - { - { - QSE_HTB_COPIER_INLINE, - QSE_HTB_COPIER_INLINE - }, - { - QSE_HTB_FREEER_DEFAULT, - QSE_HTB_FREEER_DEFAULT - }, - QSE_HTB_HASHER_DEFAULT, - QSE_HTB_COMPER_DEFAULT, - QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT - }; - - static qse_htb_mancbs_t mancbs2 = - { - { - QSE_HTB_COPIER_INLINE, - QSE_HTB_COPIER_DEFAULT - }, - { - QSE_HTB_FREEER_DEFAULT, - QSE_HTB_FREEER_DEFAULT - }, - QSE_HTB_HASHER_DEFAULT, - QSE_HTB_COMPER_DEFAULT, - QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT - }; - static qse_htb_mancbs_t treefuncbs = { { @@ -119,10 +87,10 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) QSE_HTB_FREEER_DEFAULT, free_fun }, - QSE_HTB_HASHER_DEFAULT, QSE_HTB_COMPER_DEFAULT, QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT }; static qse_htb_mancbs_t fncusercbs = @@ -135,10 +103,10 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) QSE_HTB_FREEER_DEFAULT, free_fnc }, - QSE_HTB_HASHER_DEFAULT, QSE_HTB_COMPER_DEFAULT, QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT }; if (mmgr == QSE_NULL) @@ -184,7 +152,9 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) ); if (awk->wtab == QSE_NULL) goto oops; *(qse_awk_t**)QSE_XTN(awk->wtab) = awk; - qse_htb_setmancbs (awk->wtab, &mancbs1); + qse_htb_setmancbs (awk->wtab, + qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS) + ); awk->rwtab = qse_htb_open ( mmgr, QSE_SIZEOF(awk), @@ -192,14 +162,18 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) ); if (awk->rwtab == QSE_NULL) goto oops; *(qse_awk_t**)QSE_XTN(awk->rwtab) = awk; - qse_htb_setmancbs (awk->rwtab, &mancbs1); + qse_htb_setmancbs (awk->rwtab, + qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS) + ); awk->sio.names = qse_htb_open ( mmgr, QSE_SIZEOF(awk), 128, 70, QSE_SIZEOF(qse_char_t), 1 ); if (awk->sio.names == QSE_NULL) goto oops; *(qse_awk_t**)QSE_XTN(awk->sio.names) = awk; - qse_htb_setmancbs (awk->sio.names, &mancbs2); + qse_htb_setmancbs (awk->sio.names, + qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER) + ); awk->sio.inp = &awk->sio.arg; /* TODO: initial map size?? */ @@ -215,14 +189,18 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) ); if (awk->parse.funs == QSE_NULL) goto oops; *(qse_awk_t**)QSE_XTN(awk->parse.funs) = awk; - qse_htb_setmancbs (awk->parse.funs, &mancbs2); + qse_htb_setmancbs (awk->parse.funs, + qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER) + ); awk->parse.named = qse_htb_open ( mmgr, QSE_SIZEOF(awk), 256, 70, QSE_SIZEOF(qse_char_t), 1 ); if (awk->parse.named == QSE_NULL) goto oops; *(qse_awk_t**)QSE_XTN(awk->parse.named) = awk; - qse_htb_setmancbs (awk->parse.named, &mancbs2); + qse_htb_setmancbs (awk->parse.named, + qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER) + ); awk->parse.gbls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 128); awk->parse.lcls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 64); diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index cc173dc7..a60498af 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 363 2010-10-27 12:54:37Z hyunghwan.chung $ + * $Id: run.c 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -797,10 +797,10 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio) QSE_HTB_FREEER_DEFAULT, free_namedval }, - QSE_HTB_HASHER_DEFAULT, QSE_HTB_COMPER_DEFAULT, same_namedval, - QSE_HTB_SIZER_DEFAULT + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT }; /* zero out the runtime context excluding the extension */ diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 31e25ffa..1c4924cf 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c 363 2010-10-27 12:54:37Z hyunghwan.chung $ + * $Id: val.c 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -403,10 +403,10 @@ qse_awk_val_t* qse_awk_rtx_makemapval (qse_awk_rtx_t* rtx) QSE_HTB_FREEER_DEFAULT, free_mapval }, - QSE_HTB_HASHER_DEFAULT, QSE_HTB_COMPER_DEFAULT, same_mapval, - QSE_HTB_SIZER_DEFAULT + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT }; /* CHECK */ diff --git a/qse/lib/cmn/htb.c b/qse/lib/cmn/htb.c index 34e5cd51..e7fa4f84 100644 --- a/qse/lib/cmn/htb.c +++ b/qse/lib/cmn/htb.c @@ -1,5 +1,5 @@ /* - * $Id: htb.c 364 2010-10-28 13:09:53Z hyunghwan.chung $ + * $Id: htb.c 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -72,7 +72,9 @@ QSE_INLINE pair_t* qse_htb_allocpair ( else if (kcop == QSE_HTB_COPIER_INLINE) { KPTR(n) = n + 1; - QSE_MEMCPY (KPTR(n), kptr, KTOB(htb,klen)); + /* if kptr is QSE_NULL, the inline copier does not fill + * the actual key area */ + if (kptr) QSE_MEMCPY (KPTR(n), kptr, KTOB(htb,klen)); } else { @@ -94,7 +96,9 @@ QSE_INLINE pair_t* qse_htb_allocpair ( VPTR(n) = n + 1; if (kcop == QSE_HTB_COPIER_INLINE) VPTR(n) = (byte_t*)VPTR(n) + KTOB(htb,klen); - QSE_MEMCPY (VPTR(n), vptr, VTOB(htb,vlen)); + /* if vptr is QSE_NULL, the inline copier does not fill + * the actual value area */ + if (vptr) QSE_MEMCPY (VPTR(n), vptr, VTOB(htb,vlen)); } else { @@ -181,24 +185,76 @@ static QSE_INLINE pair_t* change_pair_val ( return pair; } -static qse_htb_mancbs_t mancbs = +static qse_htb_mancbs_t mancbs[] = { { - QSE_HTB_COPIER_DEFAULT, - QSE_HTB_COPIER_DEFAULT + { + QSE_HTB_COPIER_DEFAULT, + QSE_HTB_COPIER_DEFAULT + }, + { + QSE_HTB_FREEER_DEFAULT, + QSE_HTB_FREEER_DEFAULT + }, + QSE_HTB_COMPER_DEFAULT, + QSE_HTB_KEEPER_DEFAULT, + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT }, + { - QSE_HTB_FREEER_DEFAULT, - QSE_HTB_FREEER_DEFAULT + { + QSE_HTB_COPIER_INLINE, + QSE_HTB_COPIER_INLINE + }, + { + QSE_HTB_FREEER_DEFAULT, + QSE_HTB_FREEER_DEFAULT + }, + QSE_HTB_COMPER_DEFAULT, + QSE_HTB_KEEPER_DEFAULT, + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT }, - QSE_HTB_HASHER_DEFAULT, - QSE_HTB_COMPER_DEFAULT, - QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT + + { + { + QSE_HTB_COPIER_INLINE, + QSE_HTB_COPIER_DEFAULT + }, + { + QSE_HTB_FREEER_DEFAULT, + QSE_HTB_FREEER_DEFAULT + }, + QSE_HTB_COMPER_DEFAULT, + QSE_HTB_KEEPER_DEFAULT, + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT + }, + + { + { + QSE_HTB_COPIER_DEFAULT, + QSE_HTB_COPIER_INLINE + }, + { + QSE_HTB_FREEER_DEFAULT, + QSE_HTB_FREEER_DEFAULT + }, + QSE_HTB_COMPER_DEFAULT, + QSE_HTB_KEEPER_DEFAULT, + QSE_HTB_SIZER_DEFAULT, + QSE_HTB_HASHER_DEFAULT + } +}; + +const qse_htb_mancbs_t* qse_htb_mancbs (qse_htb_mancbs_kind_t kind) +{ + return &mancbs[kind]; }; htb_t* qse_htb_open ( - mmgr_t* mmgr, size_t ext, size_t capa, int factor, int kscale, int vscale) + mmgr_t* mmgr, size_t xtnsize, size_t capa, int factor, int kscale, int vscale) { htb_t* htb; @@ -212,7 +268,7 @@ htb_t* qse_htb_open ( if (mmgr == QSE_NULL) return QSE_NULL; } - htb = (htb_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(htb_t) + ext); + htb = (htb_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(htb_t) + xtnsize); if (htb == QSE_NULL) return QSE_NULL; if (qse_htb_init (htb, mmgr, capa, factor, kscale, vscale) == QSE_NULL) @@ -256,10 +312,6 @@ htb_t* qse_htb_init ( QSE_MEMSET (htb->bucket, 0, capa*SIZEOF(pair_t*)); htb->factor = factor; -#if 0 - htb->scale[QSE_HTB_KEY] = 1; - htb->scale[QSE_HTB_VAL] = 1; -#endif htb->scale[QSE_HTB_KEY] = (kscale < 1)? 1: kscale; htb->scale[QSE_HTB_VAL] = (vscale < 1)? 1: vscale; @@ -268,22 +320,7 @@ htb_t* qse_htb_init ( htb->threshold = htb->capa * htb->factor / 100; if (htb->capa > 0 && htb->threshold <= 0) htb->threshold = 1; - htb->mancbs = &mancbs; - -#if 0 - htb->hasher = hash_key; - htb->comper = comp_key; - htb->copier[QSE_HTB_KEY] = QSE_HTB_COPIER_SIMPLE; - htb->copier[QSE_HTB_VAL] = QSE_HTB_COPIER_SIMPLE; - - /* - htb->freeer[QSE_HTB_KEY] = QSE_NULL; - htb->freeer[QSE_HTB_VAL] = QSE_NULL; - htb->keeper = QSE_NULL; - htb->sizer = QSE_NULL; - */ -#endif - + htb->mancbs = &mancbs[0]; return htb; } @@ -293,29 +330,6 @@ void qse_htb_fini (htb_t* htb) QSE_MMGR_FREE (htb->mmgr, htb->bucket); } -#if 0 -int qse_htb_getscale (htb_t* htb, qse_htb_id_t id) -{ - QSE_ASSERTX (id == QSE_HTB_KEY || id == QSE_HTB_VAL, - "The ID should be either QSE_HTB_KEY or QSE_HTB_VAL"); - return htb->scale[id]; -} - -void qse_htb_setscale (htb_t* htb, qse_htb_id_t id, int scale) -{ - QSE_ASSERTX (id == QSE_HTB_KEY || id == QSE_HTB_VAL, - "The ID should be either QSE_HTB_KEY or QSE_HTB_VAL"); - - QSE_ASSERTX (scale > 0 && scale <= QSE_TYPE_MAX(qse_byte_t), - "The scale should be larger than 0 and less than or equal to the maximum value that the qse_byte_t type can hold"); - - if (scale <= 0) scale = 1; - if (scale > QSE_TYPE_MAX(qse_byte_t)) scale = QSE_TYPE_MAX(qse_byte_t); - - htb->scale[id] = scale; -} -#endif - const qse_htb_mancbs_t* qse_htb_getmancbs (htb_t* htb) { return htb->mancbs; diff --git a/qse/lib/cmn/rbt.c b/qse/lib/cmn/rbt.c index db5e137e..50e04fa4 100644 --- a/qse/lib/cmn/rbt.c +++ b/qse/lib/cmn/rbt.c @@ -58,37 +58,13 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (rbt) #define rotate_left(rbt,pivot) rotate(rbt,pivot,1); #define rotate_right(rbt,pivot) rotate(rbt,pivot,0); -static QSE_INLINE int comp_key ( - qse_rbt_t* rbt, - const void* kptr1, size_t klen1, - const void* kptr2, size_t klen2) -{ - size_t min; - int n, nn; - - if (klen1 < klen2) - { - min = klen1; - nn = -1; - } - else - { - min = klen2; - nn = (klen1 == klen2)? 0: 1; - } - - n = QSE_MEMCMP (kptr1, kptr2, KTOB(rbt,min)); - if (n == 0) n = nn; - return n; -} - -static pair_t* alloc_pair (rbt_t* rbt, - void* kptr, size_t klen, void* vptr, size_t vlen) +QSE_INLINE pair_t* qse_rbt_allocpair ( + rbt_t* rbt, void* kptr, size_t klen, void* vptr, size_t vlen) { pair_t* n; - copier_t kcop = rbt->copier[QSE_RBT_KEY]; - copier_t vcop = rbt->copier[QSE_RBT_VAL]; + copier_t kcop = rbt->mancbs->copier[QSE_RBT_KEY]; + copier_t vcop = rbt->mancbs->copier[QSE_RBT_VAL]; size_t as = SIZEOF(pair_t); if (kcop == QSE_RBT_COPIER_INLINE) as += KTOB(rbt,klen); @@ -110,7 +86,7 @@ static pair_t* alloc_pair (rbt_t* rbt, else if (kcop == QSE_RBT_COPIER_INLINE) { KPTR(n) = n + 1; - QSE_MEMCPY (KPTR(n), kptr, KTOB(rbt,klen)); + if (kptr) QSE_MEMCPY (KPTR(n), kptr, KTOB(rbt,klen)); } else { @@ -132,15 +108,15 @@ static pair_t* alloc_pair (rbt_t* rbt, VPTR(n) = n + 1; if (kcop == QSE_RBT_COPIER_INLINE) VPTR(n) = (byte_t*)VPTR(n) + KTOB(rbt,klen); - QSE_MEMCPY (VPTR(n), vptr, VTOB(rbt,vlen)); + if (vptr) QSE_MEMCPY (VPTR(n), vptr, VTOB(rbt,vlen)); } else { VPTR(n) = vcop (rbt, vptr, vlen); if (VPTR(n) != QSE_NULL) { - if (rbt->freeer[QSE_RBT_KEY] != QSE_NULL) - rbt->freeer[QSE_RBT_KEY] (rbt, KPTR(n), KLEN(n)); + if (rbt->mancbs->freeer[QSE_RBT_KEY] != QSE_NULL) + rbt->mancbs->freeer[QSE_RBT_KEY] (rbt, KPTR(n), KLEN(n)); QSE_MMGR_FREE (rbt->mmgr, n); return QSE_NULL; } @@ -149,16 +125,76 @@ static pair_t* alloc_pair (rbt_t* rbt, return n; } -static void free_pair (rbt_t* rbt, pair_t* pair) +QSE_INLINE void qse_rbt_freepair (rbt_t* rbt, pair_t* pair) { - if (rbt->freeer[QSE_RBT_KEY] != QSE_NULL) - rbt->freeer[QSE_RBT_KEY] (rbt, KPTR(pair), KLEN(pair)); - if (rbt->freeer[QSE_RBT_VAL] != QSE_NULL) - rbt->freeer[QSE_RBT_VAL] (rbt, VPTR(pair), VLEN(pair)); + if (rbt->mancbs->freeer[QSE_RBT_KEY] != QSE_NULL) + rbt->mancbs->freeer[QSE_RBT_KEY] (rbt, KPTR(pair), KLEN(pair)); + if (rbt->mancbs->freeer[QSE_RBT_VAL] != QSE_NULL) + rbt->mancbs->freeer[QSE_RBT_VAL] (rbt, VPTR(pair), VLEN(pair)); QSE_MMGR_FREE (rbt->mmgr, pair); } -rbt_t* qse_rbt_open (mmgr_t* mmgr, size_t ext) +static qse_rbt_mancbs_t mancbs[] = +{ + { + { + QSE_RBT_COPIER_DEFAULT, + QSE_RBT_COPIER_DEFAULT + }, + { + QSE_RBT_FREEER_DEFAULT, + QSE_RBT_FREEER_DEFAULT + }, + QSE_RBT_COMPER_DEFAULT, + QSE_RBT_KEEPER_DEFAULT + }, + + { + { + QSE_RBT_COPIER_INLINE, + QSE_RBT_COPIER_INLINE + }, + { + QSE_RBT_FREEER_DEFAULT, + QSE_RBT_FREEER_DEFAULT + }, + QSE_RBT_COMPER_DEFAULT, + QSE_RBT_KEEPER_DEFAULT + }, + + { + { + QSE_RBT_COPIER_INLINE, + QSE_RBT_COPIER_DEFAULT + }, + { + QSE_RBT_FREEER_DEFAULT, + QSE_RBT_FREEER_DEFAULT + }, + QSE_RBT_COMPER_DEFAULT, + QSE_RBT_KEEPER_DEFAULT + }, + + { + { + QSE_RBT_COPIER_DEFAULT, + QSE_RBT_COPIER_INLINE + }, + { + QSE_RBT_FREEER_DEFAULT, + QSE_RBT_FREEER_DEFAULT + }, + QSE_RBT_COMPER_DEFAULT, + QSE_RBT_KEEPER_DEFAULT + } +}; + +const qse_rbt_mancbs_t* qse_rbt_mancbs (qse_rbt_mancbs_kind_t kind) +{ + return &mancbs[kind]; +}; + +rbt_t* qse_rbt_open (mmgr_t* mmgr, size_t xtnsize, int kscale, int vscale) { rbt_t* rbt; @@ -172,10 +208,10 @@ rbt_t* qse_rbt_open (mmgr_t* mmgr, size_t ext) if (mmgr == QSE_NULL) return QSE_NULL; } - rbt = (rbt_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(rbt_t) + ext); + rbt = (rbt_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(rbt_t) + xtnsize); if (rbt == QSE_NULL) return QSE_NULL; - if (qse_rbt_init (rbt, mmgr) == QSE_NULL) + if (qse_rbt_init (rbt, mmgr, kscale, vscale) == QSE_NULL) { QSE_MMGR_FREE (mmgr, rbt); return QSE_NULL; @@ -190,7 +226,7 @@ void qse_rbt_close (rbt_t* rbt) QSE_MMGR_FREE (rbt->mmgr, rbt); } -rbt_t* qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr) +rbt_t* qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr, int kscale, int vscale) { if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL(); @@ -198,19 +234,11 @@ rbt_t* qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr) QSE_MEMSET (rbt, 0, SIZEOF(*rbt)); rbt->mmgr = mmgr; - rbt->scale[QSE_RBT_KEY] = 1; - rbt->scale[QSE_RBT_VAL] = 1; + rbt->scale[QSE_RBT_KEY] = (kscale < 1)? 1: kscale; + rbt->scale[QSE_RBT_VAL] = (vscale < 1)? 1: vscale; rbt->size = 0; - rbt->comper = comp_key; - rbt->copier[QSE_RBT_KEY] = QSE_RBT_COPIER_SIMPLE; - rbt->copier[QSE_RBT_VAL] = QSE_RBT_COPIER_SIMPLE; - - /* - rbt->freeer[QSE_RBT_KEY] = QSE_NULL; - rbt->freeer[QSE_RBT_VAL] = QSE_NULL; - rbt->keeper = QSE_NULL; - */ + rbt->mancbs = &mancbs[0]; /* self-initializing nil */ QSE_MEMSET(&rbt->nil, 0, QSE_SIZEOF(rbt->nil)); @@ -229,75 +257,15 @@ void qse_rbt_fini (rbt_t* rbt) qse_rbt_clear (rbt); } -int qse_rbt_getscale (rbt_t* rbt, id_t id) +const qse_rbt_mancbs_t* qse_rbt_getmancbs (rbt_t* rbt) { - QSE_ASSERTX (id == QSE_RBT_KEY || id == QSE_RBT_VAL, - "The ID should be either QSE_RBT_KEY or QSE_RBT_VAL"); - return rbt->scale[id]; + return rbt->mancbs; } -void qse_rbt_setscale (rbt_t* rbt, id_t id, int scale) +void qse_rbt_setmancbs (rbt_t* rbt, const qse_rbt_mancbs_t* mancbs) { - QSE_ASSERTX (id == QSE_RBT_KEY || id == QSE_RBT_VAL, - "The ID should be either QSE_RBT_KEY or QSE_RBT_VAL"); - - QSE_ASSERTX (scale > 0 && scale <= QSE_TYPE_MAX(qse_byte_t), - "The scale should be larger than 0 and less than or equal to the maximum value that the qse_byte_t type can hold"); - - if (scale <= 0) scale = 1; - if (scale > QSE_TYPE_MAX(qse_byte_t)) scale = QSE_TYPE_MAX(qse_byte_t); - - rbt->scale[id] = scale; -} - -copier_t qse_rbt_getcopier (rbt_t* rbt, id_t id) -{ - QSE_ASSERTX (id == QSE_RBT_KEY || id == QSE_RBT_VAL, - "The ID should be either QSE_RBT_KEY or QSE_RBT_VAL"); - return rbt->copier[id]; -} - -void qse_rbt_setcopier (rbt_t* rbt, id_t id, copier_t copier) -{ - QSE_ASSERTX (id == QSE_RBT_KEY || id == QSE_RBT_VAL, - "The ID should be either QSE_RBT_KEY or QSE_RBT_VAL"); - if (copier == QSE_NULL) copier = QSE_RBT_COPIER_SIMPLE; - rbt->copier[id] = copier; -} - -freeer_t qse_rbt_getfreeer (rbt_t* rbt, id_t id) -{ - QSE_ASSERTX (id == QSE_RBT_KEY || id == QSE_RBT_VAL, - "The ID should be either QSE_RBT_KEY or QSE_RBT_VAL"); - return rbt->freeer[id]; -} - -void qse_rbt_setfreeer (rbt_t* rbt, id_t id, freeer_t freeer) -{ - QSE_ASSERTX (id == QSE_RBT_KEY || id == QSE_RBT_VAL, - "The ID should be either QSE_RBT_KEY or QSE_RBT_VAL"); - rbt->freeer[id] = freeer; -} - -comper_t qse_rbt_getcomper (rbt_t* rbt) -{ - return rbt->comper; -} - -void qse_rbt_setcomper (rbt_t* rbt, comper_t comper) -{ - if (comper == QSE_NULL) comper = comp_key; - rbt->comper = comper; -} - -keeper_t qse_rbt_getkeeper (rbt_t* rbt) -{ - return rbt->keeper; -} - -void qse_rbt_setkeeper (rbt_t* rbt, keeper_t keeper) -{ - rbt->keeper = keeper; + QSE_ASSERT (mancbs != QSE_NULL); + rbt->mancbs = mancbs; } size_t qse_rbt_getsize (rbt_t* rbt) @@ -311,7 +279,7 @@ pair_t* qse_rbt_search (rbt_t* rbt, const void* kptr, size_t klen) while (!IS_NIL(rbt,pair)) { - int n = rbt->comper (rbt, kptr, klen, pair->kptr, pair->klen); + int n = rbt->mancbs->comper (rbt, kptr, klen, pair->kptr, pair->klen); if (n == 0) return pair; if (n > 0) pair = pair->right; @@ -461,14 +429,14 @@ static pair_t* change_pair_val ( /* if the old value and the new value are the same, * it just calls the handler for this condition. * No value replacement occurs. */ - if (rbt->keeper != QSE_NULL) + if (rbt->mancbs->keeper != QSE_NULL) { - rbt->keeper (rbt, vptr, vlen); + rbt->mancbs->keeper (rbt, vptr, vlen); } } else { - copier_t vcop = rbt->copier[QSE_RBT_VAL]; + copier_t vcop = rbt->mancbs->copier[QSE_RBT_VAL]; void* ovptr = VPTR(pair); size_t ovlen = VLEN(pair); @@ -487,7 +455,7 @@ static pair_t* change_pair_val ( else { /* need to reconstruct the pair */ - pair_t* p = alloc_pair (rbt, + pair_t* p = qse_rbt_allocpair (rbt, KPTR(pair), KLEN(pair), vptr, vlen); if (p == QSE_NULL) return QSE_NULL; @@ -514,7 +482,7 @@ static pair_t* change_pair_val ( if (pair == rbt->root) rbt->root = p; - free_pair (rbt, pair); + qse_rbt_freepair (rbt, pair); return p; } } @@ -527,9 +495,9 @@ static pair_t* change_pair_val ( } /* free up the old value */ - if (rbt->freeer[QSE_RBT_VAL] != QSE_NULL) + if (rbt->mancbs->freeer[QSE_RBT_VAL] != QSE_NULL) { - rbt->freeer[QSE_RBT_VAL] (rbt, ovptr, ovlen); + rbt->mancbs->freeer[QSE_RBT_VAL] (rbt, ovptr, ovlen); } } @@ -545,7 +513,7 @@ static pair_t* insert ( while (!IS_NIL(rbt,xcur)) { - int n = rbt->comper (rbt, kptr, klen, xcur->kptr, xcur->klen); + int n = rbt->mancbs->comper (rbt, kptr, klen, xcur->kptr, xcur->klen); if (n == 0) { switch (opt) @@ -572,7 +540,7 @@ static pair_t* insert ( if (opt == UPDATE) return QSE_NULL; - xnew = alloc_pair (rbt, kptr, klen, vptr, vlen); + xnew = qse_rbt_allocpair (rbt, kptr, klen, vptr, vlen); if (xnew == QSE_NULL) return QSE_NULL; if (xpar == QSE_NULL) @@ -584,7 +552,7 @@ static pair_t* insert ( else { /* perform normal binary insert */ - int n = rbt->comper (rbt, kptr, klen, xpar->kptr, xpar->klen); + int n = rbt->mancbs->comper (rbt, kptr, klen, xpar->kptr, xpar->klen); if (n > 0) { QSE_ASSERT (xpar->right == &rbt->nil); @@ -755,7 +723,7 @@ static void delete_pair (rbt_t* rbt, pair_t* pair) if (y->color == QSE_RBT_BLACK && !IS_NIL(rbt,x)) adjust_for_delete (rbt, x, par); - free_pair (rbt, y); + qse_rbt_freepair (rbt, y); } else { @@ -796,7 +764,7 @@ static void delete_pair (rbt_t* rbt, pair_t* pair) if (y->right->parent == pair) y->right->parent = y; #endif - free_pair (rbt, pair); + qse_rbt_freepair (rbt, pair); } rbt->size--; @@ -917,3 +885,27 @@ void qse_rbt_rwalk (rbt_t* rbt, walker_t walker, void* ctx) walk (rbt, walker, ctx, RIGHT, LEFT); } +int qse_rbt_dflcomp ( + qse_rbt_t* rbt, + const void* kptr1, size_t klen1, + const void* kptr2, size_t klen2) +{ + size_t min; + int n, nn; + + if (klen1 < klen2) + { + min = klen1; + nn = -1; + } + else + { + min = klen2; + nn = (klen1 == klen2)? 0: 1; + } + + n = QSE_MEMCMP (kptr1, kptr2, KTOB(rbt,min)); + if (n == 0) n = nn; + return n; +} + diff --git a/qse/lib/sed/sed.c b/qse/lib/sed/sed.c index dee775b8..1dbc8340 100644 --- a/qse/lib/sed/sed.c +++ b/qse/lib/sed/sed.c @@ -1,5 +1,5 @@ /* - * $Id: sed.c 360 2010-10-21 13:29:12Z hyunghwan.chung $ + * $Id: sed.c 365 2010-10-29 13:54:36Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -94,15 +94,17 @@ static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr) return QSE_NULL; } - if (qse_map_init (&sed->tmp.labs, mmgr, 128, 70) == QSE_NULL) + if (qse_map_init (&sed->tmp.labs, mmgr, + 128, 70, QSE_SIZEOF(qse_char_t), 1) == QSE_NULL) { qse_str_fini (&sed->tmp.lab); qse_str_fini (&sed->tmp.rex); SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); return QSE_NULL; } - qse_map_setcopier (&sed->tmp.labs, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE); - qse_map_setscale (&sed->tmp.labs, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t)); + qse_map_setmancbs (&sed->tmp.labs, + qse_map_mancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER) + ); if (qse_lda_init (&sed->e.txt.appended, mmgr, 32) == QSE_NULL) { @@ -2627,6 +2629,25 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf) qse_ssize_t n; int ret = 0; + static qse_map_mancbs_t mancbs = + { + { + QSE_MAP_COPIER_INLINE, + QSE_MAP_COPIER_INLINE + }, + { + QSE_MAP_FREEER_DEFAULT, + close_outfile + }, + QSE_MAP_COMPER_DEFAULT, + QSE_MAP_KEEPER_DEFAULT +#ifdef QSE_MAP_AS_HTB + , + QSE_MAP_SIZER_DEFAULT, + QSE_MAP_HASHER_DEFAULT +#endif + }; + sed->e.subst_done = 0; qse_lda_clear (&sed->e.txt.appended); qse_str_clear (&sed->e.txt.read); @@ -2641,20 +2662,14 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf) sed->e.out.fun = outf; sed->e.out.eof = 0; sed->e.out.len = 0; - if (qse_map_init (&sed->e.out.files, sed->mmgr, 128, 70) == QSE_NULL) + if (qse_map_init (&sed->e.out.files, sed->mmgr, + 128, 70, QSE_SIZEOF(qse_char_t), 1) == QSE_NULL) { SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); return -1; } *(qse_sed_t**)QSE_XTN(&sed->e.out.files) = sed; - qse_map_setcopier ( - &sed->e.out.files, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE); - qse_map_setscale ( - &sed->e.out.files, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t)); - qse_map_setcopier ( - &sed->e.out.files, QSE_MAP_VAL, QSE_MAP_COPIER_INLINE); - qse_map_setfreeer ( - &sed->e.out.files, QSE_MAP_VAL, close_outfile); + qse_map_setmancbs (&sed->e.out.files, &mancbs); sed->e.in.fun = inf; sed->e.in.eof = 0; diff --git a/qse/samples/cmn/fma.c b/qse/samples/cmn/fma.c index 67a343ab..e46b3b73 100644 --- a/qse/samples/cmn/fma.c +++ b/qse/samples/cmn/fma.c @@ -9,6 +9,20 @@ if (f() == -1) return -1; \ } while (0) +static qse_rbt_mancbs_t mancbs = +{ + { + QSE_RBT_COPIER_INLINE, + QSE_RBT_COPIER_INLINE + }, + { + QSE_RBT_FREEER_DEFAULT, + QSE_RBT_FREEER_DEFAULT + }, + QSE_RBT_COMPER_DEFAULT, + QSE_RBT_KEEPER_DEFAULT +}; + static int test1 () { int i; @@ -97,17 +111,13 @@ static int test2 () } mmgr.udd = fma; - if (qse_rbt_init (&rbt, &mmgr) == QSE_NULL) + if (qse_rbt_init (&rbt, &mmgr, QSE_SIZEOF(long), QSE_SIZEOF(long)) == QSE_NULL) { qse_printf (QSE_T("cannot initialize a tree\n")); qse_fma_close (fma); return -1; } - - qse_rbt_setcopier (&rbt, QSE_RBT_KEY, QSE_RBT_COPIER_INLINE); - qse_rbt_setcopier (&rbt, QSE_RBT_VAL, QSE_RBT_COPIER_INLINE); - qse_rbt_setscale (&rbt, QSE_RBT_KEY, QSE_SIZEOF(long)); - qse_rbt_setscale (&rbt, QSE_RBT_VAL, QSE_SIZEOF(long)); + qse_rbt_setmancbs (&rbt, &mancbs); for (x = 10; x < 100; x++) { diff --git a/qse/samples/cmn/htb.c b/qse/samples/cmn/htb.c index b06ea52a..3ba01e22 100644 --- a/qse/samples/cmn/htb.c +++ b/qse/samples/cmn/htb.c @@ -10,23 +10,6 @@ if (f() == -1) return -1; \ } while (0) -static qse_htb_mancbs_t mancbs1 = -{ - { - QSE_HTB_COPIER_INLINE, - QSE_HTB_COPIER_INLINE - }, - { - QSE_HTB_FREEER_DEFAULT, - QSE_HTB_FREEER_DEFAULT - }, - QSE_HTB_HASHER_DEFAULT, - QSE_HTB_COMPER_DEFAULT, - QSE_HTB_KEEPER_DEFAULT, - QSE_HTB_SIZER_DEFAULT -}; - - static int test1_build (qse_htb_t* s1) { int i; @@ -129,10 +112,10 @@ static int test1 () s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 5, 70, 1, 1); if (s1 == QSE_NULL) { - qse_printf (QSE_T("cannot open a map\n")); + qse_printf (QSE_T("cannot open a hash table\n")); return -1; } - qse_htb_setmancbs (s1, &mancbs1); + qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS)); if (test1_build(s1) == -1) { @@ -174,17 +157,17 @@ static int test2 () QSE_T("what the hell is this"), QSE_T("oh my goddess"), QSE_T("hello mr monkey"), - QSE_T("is this good?") + QSE_T("this is good") }; s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 1, 70, QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t)); if (s1 == QSE_NULL) { - qse_printf (QSE_T("cannot open a map\n")); + qse_printf (QSE_T("cannot open a hash table\n")); return -1; } - qse_htb_setmancbs (s1, &mancbs1); + qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS)); for (i = 0; i < QSE_COUNTOF(keys); i++) { @@ -261,7 +244,7 @@ static int test3 () s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 1, 70); if (s1 == QSE_NULL) { - qse_printf (QSE_T("cannot open a map\n")); + qse_printf (QSE_T("cannot open a hash table\n")); return -1; } @@ -307,7 +290,7 @@ static int test4 () s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 1, 70); if (s1 == QSE_NULL) { - qse_printf (QSE_T("cannot open a map\n")); + qse_printf (QSE_T("cannot open a hash table\n")); return -1; } @@ -336,6 +319,98 @@ static int test4 () } #endif +static qse_htb_pair_t* test5_cbserter ( + qse_htb_t* htb, qse_htb_pair_t* pair, + void* kptr, qse_size_t klen, void* ctx) +{ + qse_xstr_t* v = (qse_xstr_t*)ctx; + if (pair == QSE_NULL) + { + /* no existing key for the key */ + return qse_htb_allocpair (htb, kptr, klen, v->ptr, v->len); + } + else + { + /* a pair with the key exists. + * in this sample, i will append the new value to the old value + * separated by a comma */ + + qse_htb_pair_t* new_pair; + qse_char_t comma = QSE_T(','); + qse_byte_t* vptr; + + /* allocate a new pair, but without filling the actual value. + * note vptr is given QSE_NULL for that purpose */ + new_pair = qse_htb_allocpair ( + htb, kptr, klen, QSE_NULL, pair->vlen + 1 + v->len); + if (new_pair == QSE_NULL) return QSE_NULL; + + /* fill in the value space */ + vptr = new_pair->vptr; + qse_memcpy (vptr, pair->vptr, pair->vlen*QSE_SIZEOF(qse_char_t)); + vptr += pair->vlen*QSE_SIZEOF(qse_char_t); + qse_memcpy (vptr, &comma, QSE_SIZEOF(qse_char_t)); + vptr += QSE_SIZEOF(qse_char_t); + qse_memcpy (vptr, v->ptr, v->len*QSE_SIZEOF(qse_char_t)); + + /* this callback requires the old pair to be destroyed */ + qse_htb_freepair (htb, pair); + + /* return the new pair */ + return new_pair; + } +} + +static int test5 () +{ + qse_htb_t* s1; + int i; + + qse_char_t* keys[] = + { + QSE_T("one"), QSE_T("two"), QSE_T("three") + }; + qse_char_t* vals[] = + { + QSE_T("1"), QSE_T("2"), QSE_T("3"), QSE_T("4"), QSE_T("5"), + }; + + s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 10, 70, + QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t)); + if (s1 == QSE_NULL) + { + qse_printf (QSE_T("cannot open a hash table\n")); + return -1; + } + qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS)); + + for (i = 0; i < QSE_COUNTOF(vals); i++) + { + qse_xstr_t ctx; + + qse_printf (QSE_T("setting a key [%s] and a value [%s]: "), keys[i%QSE_COUNTOF(keys)], vals[i]); + + ctx.ptr = vals[i]; + ctx.len = qse_strlen(vals[i]); + if (qse_htb_cbsert (s1, + keys[i%QSE_COUNTOF(keys)], + qse_strlen(keys[i%QSE_COUNTOF(keys)]), + test5_cbserter, &ctx) == QSE_NULL) + { + qse_printf (QSE_T("[FAILED]\n")); + } + else + { + qse_printf (QSE_T("[OK]\n")); + } + } + qse_htb_walk (s1, print_map_pair, QSE_NULL); + + + qse_htb_close (s1); + return 0; +} + int main () { R (test1); @@ -344,5 +419,6 @@ int main () R (test3); R (test4); #endif + R (test5); return 0; } diff --git a/qse/samples/cmn/rbt.c b/qse/samples/cmn/rbt.c index dbb85c56..5347fbcd 100644 --- a/qse/samples/cmn/rbt.c +++ b/qse/samples/cmn/rbt.c @@ -34,22 +34,13 @@ static int test1 () qse_rbt_t* s1; int i; - s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0); + s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0, 1, 1); if (s1 == QSE_NULL) { qse_printf (QSE_T("cannot open a table\n")); return -1; } - - qse_rbt_setcopier (s1, QSE_RBT_KEY, QSE_RBT_COPIER_INLINE); - qse_rbt_setcopier (s1, QSE_RBT_VAL, QSE_RBT_COPIER_INLINE); - /* - qse_rbt_setscale (s1, QSE_RBT_KEY, QSE_SIZEOF(int)); - qse_rbt_setscale (s1, QSE_RBT_VAL, QSE_SIZEOF(int)); - */ - /* - qse_rbt_setkeeper (s1, keeper1); - */ + qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS)); for (i = 0; i < 20; i++) { @@ -103,17 +94,13 @@ static int test2 () { qse_rbt_t* s1; - s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0); + s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0, QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t)); if (s1 == QSE_NULL) { qse_printf (QSE_T("cannot open a table\n")); return -1; } - - qse_rbt_setcopier (s1, QSE_RBT_KEY, QSE_RBT_COPIER_INLINE); - qse_rbt_setcopier (s1, QSE_RBT_VAL, QSE_RBT_COPIER_INLINE); - qse_rbt_setscale (s1, QSE_RBT_KEY, QSE_SIZEOF(qse_char_t)); - qse_rbt_setscale (s1, QSE_RBT_VAL, QSE_SIZEOF(qse_char_t)); + qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS)); qse_rbt_insert (s1, QSE_T("hello"), 5, QSE_T("mr. monkey"), 10); qse_rbt_insert (s1, QSE_T("world"), 5, QSE_T("ms. panda"), 9);