enhanced qse_htb_t and qse_rbt_t

- defined builtin mancbs'
- changed qse_rbt_t to point to mancbs
- touched up a few other functions
This commit is contained in:
hyung-hwan 2010-10-30 07:54:36 +00:00
parent 2265531c97
commit d58631e70b
14 changed files with 673 additions and 551 deletions

View File

@ -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)
{

View File

@ -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,

View File

@ -29,26 +29,19 @@
#if defined(QSE_MAP_AS_HTB)
# include <qse/cmn/htb.h>
# 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 <qse/cmn/rbt.h>
# 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)

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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++)
{

View File

@ -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;
}

View File

@ -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);