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:
parent
2265531c97
commit
d58631e70b
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
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;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
qse_htb_setmancbs (gvm,
|
||||||
static qse_htb_mancbs_t mancbs =
|
qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_VALUE_COPIER)
|
||||||
{
|
);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF)
|
while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF)
|
||||||
{
|
{
|
||||||
|
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
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 */
|
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
|
* 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) (
|
typedef int (*qse_htb_comper_t) (
|
||||||
qse_htb_t* htb, /**< hash table */
|
qse_htb_t* htb, /**< hash table */
|
||||||
const void* kptr1, /**< pointer to a key */
|
const void* kptr1, /**< key pointer */
|
||||||
qse_size_t klen1, /**< length of a key */
|
qse_size_t klen1, /**< key length */
|
||||||
const void* kptr2, /**< pointer to a key */
|
const void* kptr2, /**< key pointer */
|
||||||
qse_size_t klen2 /**< length of a key */
|
qse_size_t klen2 /**< key length */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,6 +114,15 @@ typedef qse_size_t (*qse_htb_sizer_t) (
|
|||||||
qse_size_t hint /**< sizing hint */
|
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.
|
* 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
|
struct qse_htb_pair_t
|
||||||
{
|
{
|
||||||
void* kptr; /**< pointer to a key */
|
void* kptr; /**< key pointer */
|
||||||
qse_size_t klen; /**< length of a key */
|
qse_size_t klen; /**< key length */
|
||||||
void* vptr; /**< pointer to a value */
|
void* vptr; /**< value pointer */
|
||||||
qse_size_t vlen; /**< length of a value */
|
qse_size_t vlen; /**< value length */
|
||||||
|
|
||||||
/* management information below */
|
/* management information below */
|
||||||
qse_htb_pair_t* next;
|
qse_htb_pair_t* next;
|
||||||
@ -152,12 +155,22 @@ struct qse_htb_mancbs_t
|
|||||||
{
|
{
|
||||||
qse_htb_copier_t copier[2];
|
qse_htb_copier_t copier[2];
|
||||||
qse_htb_freeer_t freeer[2];
|
qse_htb_freeer_t freeer[2];
|
||||||
qse_htb_hasher_t hasher; /**< key hasher */
|
|
||||||
qse_htb_comper_t comper; /**< key comparator */
|
qse_htb_comper_t comper; /**< key comparator */
|
||||||
qse_htb_keeper_t keeper; /**< value keeper */
|
qse_htb_keeper_t keeper; /**< value keeper */
|
||||||
qse_htb_sizer_t sizer; /**< bucket capacity recalculator */
|
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.
|
* 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_COPIER_DEFAULT (QSE_HTB_COPIER_SIMPLE)
|
||||||
#define QSE_HTB_FREEER_DEFAULT (QSE_NULL)
|
#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_COMPER_DEFAULT (qse_htb_dflcomp)
|
||||||
#define QSE_HTB_KEEPER_DEFAULT (QSE_NULL)
|
#define QSE_HTB_KEEPER_DEFAULT (QSE_NULL)
|
||||||
#define QSE_HTB_SIZER_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.
|
* The QSE_HTB_SIZE() macro returns the number of pairs in a hash table.
|
||||||
@ -214,19 +227,25 @@ extern "C" {
|
|||||||
|
|
||||||
QSE_DEFINE_COMMON_FUNCTIONS (htb)
|
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
|
* 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
|
* bucket and a list of values chained. The initial capacity should be larger
|
||||||
* than 0. The load factor should be between 0 and 100 inclusive and the load
|
* than 0. The load factor should be between 0 and 100 inclusive and the load
|
||||||
* factor of 0 disables bucket resizing. If you need extra space associated
|
* factor of 0 disables bucket resizing. If you need extra space associated
|
||||||
* 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
|
* The QSE_HTB_XTN() macro and the qse_htb_getxtn() function return the
|
||||||
* pointer to the beginning of the extension.
|
* 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_htb_t* qse_htb_open (
|
||||||
qse_mmgr_t* mmgr, /**< memory manager */
|
qse_mmgr_t* mmgr, /**< memory manager */
|
||||||
qse_size_t ext, /**< extension size in bytes */
|
qse_size_t xtnsize, /**< extension size in bytes */
|
||||||
qse_size_t capa, /**< initial capacity */
|
qse_size_t capa, /**< initial capacity */
|
||||||
int factor, /**< load factor */
|
int factor, /**< load factor */
|
||||||
int kscale, /**< key scale */
|
int kscale, /**< key scale */
|
||||||
@ -260,6 +279,22 @@ void qse_htb_fini (
|
|||||||
qse_htb_t* htb
|
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.
|
* 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 */
|
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
|
* 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
|
* matching key. It returns the pointer to the pair found. If it fails
|
||||||
* to find one, it returns QSE_NULL.
|
* to find one, it returns QSE_NULL.
|
||||||
* @return pointer to the pair with a maching key,
|
* @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_pair_t* qse_htb_search (
|
||||||
qse_htb_t* htb, /**< hash table */
|
qse_htb_t* htb, /**< hash table */
|
||||||
const void* kptr, /**< the pointer to a key */
|
const void* kptr, /**< key pointer */
|
||||||
qse_size_t klen /**< the size of the key */
|
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
|
* 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
|
* a new pair with the key and value given. It returns the pointer to the
|
||||||
* pair updated or inserted.
|
* pair updated or inserted.
|
||||||
* @return a pointer to the updated or inserted pair on success,
|
* @return pointer to the updated or inserted pair on success,
|
||||||
* QSE_NULL on failure.
|
* #QSE_NULL on failure.
|
||||||
*/
|
*/
|
||||||
qse_htb_pair_t* qse_htb_upsert (
|
qse_htb_pair_t* qse_htb_upsert (
|
||||||
qse_htb_t* htb, /**< hash table */
|
qse_htb_t* htb, /**< hash table */
|
||||||
void* kptr, /**< the pointer to a key */
|
void* kptr, /**< key pointer */
|
||||||
qse_size_t klen, /**< the length of the key */
|
qse_size_t klen, /**< key length */
|
||||||
void* vptr, /**< the pointer to a value */
|
void* vptr, /**< value pointer */
|
||||||
qse_size_t vlen /**< the length of the value */
|
qse_size_t vlen /**< value length */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_htb_ensert() function inserts a new pair with the key and the value
|
* 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
|
* given. If there exists a pair with the key given, the function returns
|
||||||
* the pair containing the key.
|
* 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_pair_t* qse_htb_ensert (
|
||||||
qse_htb_t* htb, /**< hash table */
|
qse_htb_t* htb, /**< hash table */
|
||||||
void* kptr, /**< the pointer to a key */
|
void* kptr, /**< key pointer */
|
||||||
qse_size_t klen, /**< the length of the key */
|
qse_size_t klen, /**< key length */
|
||||||
void* vptr, /**< the pointer to a value */
|
void* vptr, /**< value pointer */
|
||||||
qse_size_t vlen /**< the length of the value */
|
qse_size_t vlen /**< value length */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_htb_insert() function inserts a new pair with the key and the value
|
* 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
|
* given. If there exists a pair with the key given, the function returns
|
||||||
* QSE_NULL without channging the value.
|
* #QSE_NULL without channging the value.
|
||||||
* @return pointer to the pair created on success, QSE_NULL on failure.
|
* @return pointer to the pair created on success, #QSE_NULL on failure.
|
||||||
*/
|
*/
|
||||||
qse_htb_pair_t* qse_htb_insert (
|
qse_htb_pair_t* qse_htb_insert (
|
||||||
qse_htb_t* htb, /**< hash table */
|
qse_htb_t* htb, /**< hash table */
|
||||||
void* kptr, /**< the pointer to a key */
|
void* kptr, /**< key pointer */
|
||||||
qse_size_t klen, /**< the length of the key */
|
qse_size_t klen, /**< key length */
|
||||||
void* vptr, /**< the pointer to a value */
|
void* vptr, /**< value pointer */
|
||||||
qse_size_t vlen /**< the length of the value */
|
qse_size_t vlen /**< value length */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_htb_update() function updates the value of an existing pair
|
* The qse_htb_update() function updates the value of an existing pair
|
||||||
* with a matching key.
|
* 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_pair_t* qse_htb_update (
|
||||||
qse_htb_t* htb, /**< hash table */
|
qse_htb_t* htb, /**< hash table */
|
||||||
void* kptr, /**< the pointer to a key */
|
void* kptr, /**< key pointer */
|
||||||
qse_size_t klen, /**< the length of the key */
|
qse_size_t klen, /**< key length */
|
||||||
void* vptr, /**< the pointer to a value */
|
void* vptr, /**< value pointer */
|
||||||
qse_size_t vlen /**< the length of the value */
|
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) (
|
typedef qse_htb_pair_t* (*qse_htb_cbserter_t) (
|
||||||
qse_htb_t* htb,
|
qse_htb_t* htb, /**< hash table */
|
||||||
qse_htb_pair_t* pair,
|
qse_htb_pair_t* pair, /**< pair pointer */
|
||||||
void* kptr,
|
void* kptr, /**< key pointer */
|
||||||
qse_size_t klen,
|
qse_size_t klen, /**< key length */
|
||||||
void* ctx
|
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_pair_t* qse_htb_cbsert (
|
||||||
qse_htb_t* htb,
|
qse_htb_t* htb, /**< hash table */
|
||||||
void* kptr,
|
void* kptr, /**< key pointer */
|
||||||
qse_size_t klen,
|
qse_size_t klen, /**< key length */
|
||||||
qse_htb_cbserter_t cbserter,
|
qse_htb_cbserter_t cbserter, /**< callback function */
|
||||||
void* ctx
|
void* ctx /**< callback context */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -400,8 +499,8 @@ qse_htb_pair_t* qse_htb_cbsert (
|
|||||||
*/
|
*/
|
||||||
int qse_htb_delete (
|
int qse_htb_delete (
|
||||||
qse_htb_t* htb, /**< hash table */
|
qse_htb_t* htb, /**< hash table */
|
||||||
const void* kptr, /**< the pointer to a key */
|
const void* kptr, /**< key pointer */
|
||||||
qse_size_t klen /**< the size of the key */
|
qse_size_t klen /**< key length */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -443,6 +542,13 @@ qse_htb_pair_t* qse_htb_getnextpair (
|
|||||||
* The qse_htb_allocpair() function allocates a pair for a key and a value
|
* 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.
|
* 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_pair_t* qse_htb_allocpair (
|
||||||
qse_htb_t* htb,
|
qse_htb_t* htb,
|
||||||
@ -462,12 +568,18 @@ void qse_htb_freepair (
|
|||||||
qse_htb_pair_t* pair
|
qse_htb_pair_t* pair
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_htb_dflhash() function is a default hash function.
|
||||||
|
*/
|
||||||
qse_size_t qse_htb_dflhash (
|
qse_size_t qse_htb_dflhash (
|
||||||
qse_htb_t* htb,
|
qse_htb_t* htb,
|
||||||
const void* kptr,
|
const void* kptr,
|
||||||
qse_size_t klen
|
qse_size_t klen
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_htb_dflcomp() function is default comparator.
|
||||||
|
*/
|
||||||
int qse_htb_dflcomp (
|
int qse_htb_dflcomp (
|
||||||
qse_htb_t* htb,
|
qse_htb_t* htb,
|
||||||
const void* kptr1,
|
const void* kptr1,
|
||||||
|
@ -29,26 +29,19 @@
|
|||||||
|
|
||||||
#if defined(QSE_MAP_AS_HTB)
|
#if defined(QSE_MAP_AS_HTB)
|
||||||
# include <qse/cmn/htb.h>
|
# 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_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_fini(map) qse_htb_fini(map)
|
||||||
# define qse_map_getsize(map) qse_htb_getsize(map)
|
# define qse_map_getsize(map) qse_htb_getsize(map)
|
||||||
# define qse_map_getcapa(map) qse_htb_getcapa(map)
|
# define qse_map_getcapa(map) qse_htb_getcapa(map)
|
||||||
# define qse_map_getscale(map,id) qse_htb_getscale(map,id)
|
# define qse_map_getmancbs(map) qse_htb_getmancbs(map)
|
||||||
# define qse_map_setscale(map,id,scale) qse_htb_setscale(map,id,scale)
|
# define qse_map_setmancbs(map,cbs) qse_htb_setmancbs(map,cbs)
|
||||||
# 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_search(map,kptr,klen) qse_htb_search(map,kptr,klen)
|
# 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_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)
|
# define qse_map_ensert(map,kptr,klen,vptr,vlen) qse_htb_ensert(map,kptr,klen,vptr,vlen)
|
||||||
@ -65,8 +58,15 @@
|
|||||||
# define qse_map_id_t qse_htb_id_t
|
# define qse_map_id_t qse_htb_id_t
|
||||||
# define qse_map_t qse_htb_t
|
# define qse_map_t qse_htb_t
|
||||||
# define qse_map_pair_t qse_htb_pair_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_SIMPLE QSE_HTB_COPIER_SIMPLE
|
||||||
# define QSE_MAP_COPIER_INLINE QSE_HTB_COPIER_INLINE
|
# 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_SIZE(map) QSE_HTB_SIZE(map)
|
||||||
# define QSE_MAP_KCOPIER(map) QSE_HTB_KCOPIER(map)
|
# define QSE_MAP_KCOPIER(map) QSE_HTB_KCOPIER(map)
|
||||||
# define QSE_MAP_VCOPIER(map) QSE_HTB_VCOPIER(map)
|
# define QSE_MAP_VCOPIER(map) QSE_HTB_VCOPIER(map)
|
||||||
@ -82,26 +82,19 @@
|
|||||||
# define QSE_MAP_VLEN(p) QSE_HTB_VLEN(p)
|
# define QSE_MAP_VLEN(p) QSE_HTB_VLEN(p)
|
||||||
#elif defined(QSE_MAP_AS_RBT)
|
#elif defined(QSE_MAP_AS_RBT)
|
||||||
# include <qse/cmn/rbt.h>
|
# 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_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_fini(map) qse_rbt_fini(map)
|
||||||
# define qse_map_getsize(map) qse_rbt_getsize(map)
|
# define qse_map_getsize(map) qse_rbt_getsize(map)
|
||||||
# define qse_map_getcapa(map) qse_rbt_getcapa(map)
|
# define qse_map_getcapa(map) qse_rbt_getsize(map)
|
||||||
# define qse_map_getscale(map,id) qse_rbt_getscale(map,id)
|
# define qse_map_getmancbs(map) qse_rbt_getmancbs(map)
|
||||||
# define qse_map_setscale(map,id,scale) qse_rbt_setscale(map,id,scale)
|
# define qse_map_setmancbs(map,cbs) qse_rbt_setmancbs(map,cbs)
|
||||||
# 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_search(map,kptr,klen) qse_rbt_search(map,kptr,klen)
|
# 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_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)
|
# define qse_map_ensert(map,kptr,klen,vptr,vlen) qse_rbt_ensert(map,kptr,klen,vptr,vlen)
|
||||||
@ -118,8 +111,15 @@
|
|||||||
# define qse_map_id_t qse_rbt_id_t
|
# define qse_map_id_t qse_rbt_id_t
|
||||||
# define qse_map_t qse_rbt_t
|
# define qse_map_t qse_rbt_t
|
||||||
# define qse_map_pair_t qse_rbt_pair_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_SIMPLE QSE_RBT_COPIER_SIMPLE
|
||||||
# define QSE_MAP_COPIER_INLINE QSE_RBT_COPIER_INLINE
|
# 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_SIZE(map) QSE_RBT_SIZE(map)
|
||||||
# define QSE_MAP_KCOPIER(map) QSE_RBT_KCOPIER(map)
|
# define QSE_MAP_KCOPIER(map) QSE_RBT_KCOPIER(map)
|
||||||
# define QSE_MAP_VCOPIER(map) QSE_RBT_VCOPIER(map)
|
# define QSE_MAP_VCOPIER(map) QSE_RBT_VCOPIER(map)
|
||||||
|
@ -130,6 +130,26 @@ struct qse_rbt_pair_t
|
|||||||
qse_rbt_pair_t* child[2]; /* left and right */
|
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.
|
* The qse_rbt_t type defines a red-black tree.
|
||||||
*/
|
*/
|
||||||
@ -137,10 +157,7 @@ struct qse_rbt_t
|
|||||||
{
|
{
|
||||||
QSE_DEFINE_COMMON_FIELDS (rbt)
|
QSE_DEFINE_COMMON_FIELDS (rbt)
|
||||||
|
|
||||||
qse_rbt_copier_t copier[2]; /**< key and value copier */
|
const qse_rbt_mancbs_t* mancbs;
|
||||||
qse_rbt_freeer_t freeer[2]; /**< key and value freeer */
|
|
||||||
qse_rbt_comper_t comper; /**< key comparator */
|
|
||||||
qse_rbt_keeper_t keeper; /**< value keeper */
|
|
||||||
|
|
||||||
qse_byte_t scale[2]; /**< length scale */
|
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_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.
|
* 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)
|
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.
|
* The qse_rbt_open() function creates a red-black tree.
|
||||||
* @return qse_rbt_t pointer on success, QSE_NULL on failure.
|
* @return qse_rbt_t pointer on success, QSE_NULL on failure.
|
||||||
*/
|
*/
|
||||||
qse_rbt_t* qse_rbt_open (
|
qse_rbt_t* qse_rbt_open (
|
||||||
qse_mmgr_t* mmgr, /**< memory manager */
|
qse_mmgr_t* mmgr, /**< memory manager */
|
||||||
qse_size_t ext /**< extension size in bytes */
|
qse_size_t xtnsize, /**< extension size in bytes */
|
||||||
|
int kscale, /**< key scale */
|
||||||
|
int vscale /**< value scale */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,7 +230,9 @@ void qse_rbt_close (
|
|||||||
*/
|
*/
|
||||||
qse_rbt_t* qse_rbt_init (
|
qse_rbt_t* qse_rbt_init (
|
||||||
qse_rbt_t* rbt, /**< red-black tree */
|
qse_rbt_t* rbt, /**< red-black tree */
|
||||||
qse_mmgr_t* mmgr /**< memory manager */
|
qse_mmgr_t* mmgr, /**< memory manager */
|
||||||
|
int kscale, /**< key scale */
|
||||||
|
int vscale /**< value scale */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,6 +242,22 @@ void qse_rbt_fini (
|
|||||||
qse_rbt_t* rbt /**< red-black tree */
|
qse_rbt_t* rbt /**< red-black tree */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_rbt_getmancbs() function gets manipulation callback function set.
|
||||||
|
*/
|
||||||
|
const qse_rbt_mancbs_t* qse_rbt_getmancbs (
|
||||||
|
qse_rbt_t* rbt /**< red-black tree */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_rbt_setmancbs() function sets internal manipulation callback
|
||||||
|
* functions for data construction, destruction, resizing, hashing, etc.
|
||||||
|
*/
|
||||||
|
void qse_rbt_setmancbs (
|
||||||
|
qse_rbt_t* rbt, /**< red-black tree */
|
||||||
|
const qse_rbt_mancbs_t* mancbs /**< callback function set */
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_rbt_getsize() function gets the number of pairs in red-black tree.
|
* The qse_rbt_getsize() function gets the number of pairs in red-black tree.
|
||||||
*/
|
*/
|
||||||
@ -219,101 +265,6 @@ qse_size_t qse_rbt_getsize (
|
|||||||
qse_rbt_t* rbt /**< red-black tree */
|
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 (
|
|
||||||
qse_rbt_t* rbt /**< red-black tree */
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The qse_rbt_setcomper() function changes the key comparator.
|
|
||||||
*/
|
|
||||||
void qse_rbt_setcomper (
|
|
||||||
qse_rbt_t* rbt, /**< red-black tree */
|
|
||||||
qse_rbt_comper_t comper /**< comparator function pointer */
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_rbt_search() function searches red-black tree to find a pair with a
|
* The qse_rbt_search() function searches red-black tree to find a pair with a
|
||||||
* matching key. It returns the pointer to the pair found. If it fails
|
* matching key. It returns the pointer to the pair found. If it fails
|
||||||
@ -421,6 +372,14 @@ void qse_rbt_rwalk (
|
|||||||
void* ctx /**< pointer to user-specific data */
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -1152,18 +1152,12 @@ int Awk::open ()
|
|||||||
QSE_HTB_FREEER_DEFAULT,
|
QSE_HTB_FREEER_DEFAULT,
|
||||||
free_function_map_value
|
free_function_map_value
|
||||||
},
|
},
|
||||||
QSE_HTB_HASHER_DEFAULT,
|
|
||||||
QSE_HTB_COMPER_DEFAULT,
|
QSE_HTB_COMPER_DEFAULT,
|
||||||
QSE_HTB_KEEPER_DEFAULT,
|
QSE_HTB_KEEPER_DEFAULT,
|
||||||
QSE_HTB_SIZER_DEFAULT
|
QSE_HTB_SIZER_DEFAULT,
|
||||||
|
QSE_HTB_HASHER_DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
qse_htb_setmancbs (functionMap, &mancbs);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
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;
|
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 =
|
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,
|
QSE_HTB_FREEER_DEFAULT,
|
||||||
free_fun
|
free_fun
|
||||||
},
|
},
|
||||||
QSE_HTB_HASHER_DEFAULT,
|
|
||||||
QSE_HTB_COMPER_DEFAULT,
|
QSE_HTB_COMPER_DEFAULT,
|
||||||
QSE_HTB_KEEPER_DEFAULT,
|
QSE_HTB_KEEPER_DEFAULT,
|
||||||
QSE_HTB_SIZER_DEFAULT
|
QSE_HTB_SIZER_DEFAULT,
|
||||||
|
QSE_HTB_HASHER_DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
static qse_htb_mancbs_t fncusercbs =
|
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,
|
QSE_HTB_FREEER_DEFAULT,
|
||||||
free_fnc
|
free_fnc
|
||||||
},
|
},
|
||||||
QSE_HTB_HASHER_DEFAULT,
|
|
||||||
QSE_HTB_COMPER_DEFAULT,
|
QSE_HTB_COMPER_DEFAULT,
|
||||||
QSE_HTB_KEEPER_DEFAULT,
|
QSE_HTB_KEEPER_DEFAULT,
|
||||||
QSE_HTB_SIZER_DEFAULT
|
QSE_HTB_SIZER_DEFAULT,
|
||||||
|
QSE_HTB_HASHER_DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mmgr == QSE_NULL)
|
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;
|
if (awk->wtab == QSE_NULL) goto oops;
|
||||||
*(qse_awk_t**)QSE_XTN(awk->wtab) = awk;
|
*(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 (
|
awk->rwtab = qse_htb_open (
|
||||||
mmgr, QSE_SIZEOF(awk),
|
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;
|
if (awk->rwtab == QSE_NULL) goto oops;
|
||||||
*(qse_awk_t**)QSE_XTN(awk->rwtab) = awk;
|
*(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 (
|
awk->sio.names = qse_htb_open (
|
||||||
mmgr, QSE_SIZEOF(awk), 128, 70, QSE_SIZEOF(qse_char_t), 1
|
mmgr, QSE_SIZEOF(awk), 128, 70, QSE_SIZEOF(qse_char_t), 1
|
||||||
);
|
);
|
||||||
if (awk->sio.names == QSE_NULL) goto oops;
|
if (awk->sio.names == QSE_NULL) goto oops;
|
||||||
*(qse_awk_t**)QSE_XTN(awk->sio.names) = awk;
|
*(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;
|
awk->sio.inp = &awk->sio.arg;
|
||||||
|
|
||||||
/* TODO: initial map size?? */
|
/* 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;
|
if (awk->parse.funs == QSE_NULL) goto oops;
|
||||||
*(qse_awk_t**)QSE_XTN(awk->parse.funs) = awk;
|
*(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 (
|
awk->parse.named = qse_htb_open (
|
||||||
mmgr, QSE_SIZEOF(awk), 256, 70, QSE_SIZEOF(qse_char_t), 1
|
mmgr, QSE_SIZEOF(awk), 256, 70, QSE_SIZEOF(qse_char_t), 1
|
||||||
);
|
);
|
||||||
if (awk->parse.named == QSE_NULL) goto oops;
|
if (awk->parse.named == QSE_NULL) goto oops;
|
||||||
*(qse_awk_t**)QSE_XTN(awk->parse.named) = awk;
|
*(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.gbls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 128);
|
||||||
awk->parse.lcls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 64);
|
awk->parse.lcls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 64);
|
||||||
|
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
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,
|
QSE_HTB_FREEER_DEFAULT,
|
||||||
free_namedval
|
free_namedval
|
||||||
},
|
},
|
||||||
QSE_HTB_HASHER_DEFAULT,
|
|
||||||
QSE_HTB_COMPER_DEFAULT,
|
QSE_HTB_COMPER_DEFAULT,
|
||||||
same_namedval,
|
same_namedval,
|
||||||
QSE_HTB_SIZER_DEFAULT
|
QSE_HTB_SIZER_DEFAULT,
|
||||||
|
QSE_HTB_HASHER_DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
/* zero out the runtime context excluding the extension */
|
/* zero out the runtime context excluding the extension */
|
||||||
|
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
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,
|
QSE_HTB_FREEER_DEFAULT,
|
||||||
free_mapval
|
free_mapval
|
||||||
},
|
},
|
||||||
QSE_HTB_HASHER_DEFAULT,
|
|
||||||
QSE_HTB_COMPER_DEFAULT,
|
QSE_HTB_COMPER_DEFAULT,
|
||||||
same_mapval,
|
same_mapval,
|
||||||
QSE_HTB_SIZER_DEFAULT
|
QSE_HTB_SIZER_DEFAULT,
|
||||||
|
QSE_HTB_HASHER_DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CHECK */
|
/* CHECK */
|
||||||
|
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -72,7 +72,9 @@ QSE_INLINE pair_t* qse_htb_allocpair (
|
|||||||
else if (kcop == QSE_HTB_COPIER_INLINE)
|
else if (kcop == QSE_HTB_COPIER_INLINE)
|
||||||
{
|
{
|
||||||
KPTR(n) = n + 1;
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -94,7 +96,9 @@ QSE_INLINE pair_t* qse_htb_allocpair (
|
|||||||
VPTR(n) = n + 1;
|
VPTR(n) = n + 1;
|
||||||
if (kcop == QSE_HTB_COPIER_INLINE)
|
if (kcop == QSE_HTB_COPIER_INLINE)
|
||||||
VPTR(n) = (byte_t*)VPTR(n) + KTOB(htb,klen);
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -181,8 +185,9 @@ static QSE_INLINE pair_t* change_pair_val (
|
|||||||
return pair;
|
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
|
||||||
@ -191,14 +196,65 @@ static qse_htb_mancbs_t mancbs =
|
|||||||
QSE_HTB_FREEER_DEFAULT,
|
QSE_HTB_FREEER_DEFAULT,
|
||||||
QSE_HTB_FREEER_DEFAULT
|
QSE_HTB_FREEER_DEFAULT
|
||||||
},
|
},
|
||||||
QSE_HTB_HASHER_DEFAULT,
|
|
||||||
QSE_HTB_COMPER_DEFAULT,
|
QSE_HTB_COMPER_DEFAULT,
|
||||||
QSE_HTB_KEEPER_DEFAULT,
|
QSE_HTB_KEEPER_DEFAULT,
|
||||||
QSE_HTB_SIZER_DEFAULT
|
QSE_HTB_SIZER_DEFAULT,
|
||||||
|
QSE_HTB_HASHER_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_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 (
|
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;
|
htb_t* htb;
|
||||||
|
|
||||||
@ -212,7 +268,7 @@ htb_t* qse_htb_open (
|
|||||||
if (mmgr == QSE_NULL) return QSE_NULL;
|
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 (htb == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
if (qse_htb_init (htb, mmgr, capa, factor, kscale, vscale) == 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*));
|
QSE_MEMSET (htb->bucket, 0, capa*SIZEOF(pair_t*));
|
||||||
|
|
||||||
htb->factor = factor;
|
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_KEY] = (kscale < 1)? 1: kscale;
|
||||||
htb->scale[QSE_HTB_VAL] = (vscale < 1)? 1: vscale;
|
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;
|
htb->threshold = htb->capa * htb->factor / 100;
|
||||||
if (htb->capa > 0 && htb->threshold <= 0) htb->threshold = 1;
|
if (htb->capa > 0 && htb->threshold <= 0) htb->threshold = 1;
|
||||||
|
|
||||||
htb->mancbs = &mancbs;
|
htb->mancbs = &mancbs[0];
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
return htb;
|
return htb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,29 +330,6 @@ void qse_htb_fini (htb_t* htb)
|
|||||||
QSE_MMGR_FREE (htb->mmgr, htb->bucket);
|
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)
|
const qse_htb_mancbs_t* qse_htb_getmancbs (htb_t* htb)
|
||||||
{
|
{
|
||||||
return htb->mancbs;
|
return htb->mancbs;
|
||||||
|
@ -58,37 +58,13 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (rbt)
|
|||||||
#define rotate_left(rbt,pivot) rotate(rbt,pivot,1);
|
#define rotate_left(rbt,pivot) rotate(rbt,pivot,1);
|
||||||
#define rotate_right(rbt,pivot) rotate(rbt,pivot,0);
|
#define rotate_right(rbt,pivot) rotate(rbt,pivot,0);
|
||||||
|
|
||||||
static QSE_INLINE int comp_key (
|
QSE_INLINE pair_t* qse_rbt_allocpair (
|
||||||
qse_rbt_t* rbt,
|
rbt_t* rbt, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
pair_t* n;
|
pair_t* n;
|
||||||
|
|
||||||
copier_t kcop = rbt->copier[QSE_RBT_KEY];
|
copier_t kcop = rbt->mancbs->copier[QSE_RBT_KEY];
|
||||||
copier_t vcop = rbt->copier[QSE_RBT_VAL];
|
copier_t vcop = rbt->mancbs->copier[QSE_RBT_VAL];
|
||||||
|
|
||||||
size_t as = SIZEOF(pair_t);
|
size_t as = SIZEOF(pair_t);
|
||||||
if (kcop == QSE_RBT_COPIER_INLINE) as += KTOB(rbt,klen);
|
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)
|
else if (kcop == QSE_RBT_COPIER_INLINE)
|
||||||
{
|
{
|
||||||
KPTR(n) = n + 1;
|
KPTR(n) = n + 1;
|
||||||
QSE_MEMCPY (KPTR(n), kptr, KTOB(rbt,klen));
|
if (kptr) QSE_MEMCPY (KPTR(n), kptr, KTOB(rbt,klen));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -132,15 +108,15 @@ static pair_t* alloc_pair (rbt_t* rbt,
|
|||||||
VPTR(n) = n + 1;
|
VPTR(n) = n + 1;
|
||||||
if (kcop == QSE_RBT_COPIER_INLINE)
|
if (kcop == QSE_RBT_COPIER_INLINE)
|
||||||
VPTR(n) = (byte_t*)VPTR(n) + KTOB(rbt,klen);
|
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
|
else
|
||||||
{
|
{
|
||||||
VPTR(n) = vcop (rbt, vptr, vlen);
|
VPTR(n) = vcop (rbt, vptr, vlen);
|
||||||
if (VPTR(n) != QSE_NULL)
|
if (VPTR(n) != QSE_NULL)
|
||||||
{
|
{
|
||||||
if (rbt->freeer[QSE_RBT_KEY] != QSE_NULL)
|
if (rbt->mancbs->freeer[QSE_RBT_KEY] != QSE_NULL)
|
||||||
rbt->freeer[QSE_RBT_KEY] (rbt, KPTR(n), KLEN(n));
|
rbt->mancbs->freeer[QSE_RBT_KEY] (rbt, KPTR(n), KLEN(n));
|
||||||
QSE_MMGR_FREE (rbt->mmgr, n);
|
QSE_MMGR_FREE (rbt->mmgr, n);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -149,16 +125,76 @@ static pair_t* alloc_pair (rbt_t* rbt,
|
|||||||
return n;
|
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)
|
if (rbt->mancbs->freeer[QSE_RBT_KEY] != QSE_NULL)
|
||||||
rbt->freeer[QSE_RBT_KEY] (rbt, KPTR(pair), KLEN(pair));
|
rbt->mancbs->freeer[QSE_RBT_KEY] (rbt, KPTR(pair), KLEN(pair));
|
||||||
if (rbt->freeer[QSE_RBT_VAL] != QSE_NULL)
|
if (rbt->mancbs->freeer[QSE_RBT_VAL] != QSE_NULL)
|
||||||
rbt->freeer[QSE_RBT_VAL] (rbt, VPTR(pair), VLEN(pair));
|
rbt->mancbs->freeer[QSE_RBT_VAL] (rbt, VPTR(pair), VLEN(pair));
|
||||||
QSE_MMGR_FREE (rbt->mmgr, 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;
|
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;
|
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 (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);
|
QSE_MMGR_FREE (mmgr, rbt);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
@ -190,7 +226,7 @@ void qse_rbt_close (rbt_t* rbt)
|
|||||||
QSE_MMGR_FREE (rbt->mmgr, 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();
|
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));
|
QSE_MEMSET (rbt, 0, SIZEOF(*rbt));
|
||||||
rbt->mmgr = mmgr;
|
rbt->mmgr = mmgr;
|
||||||
|
|
||||||
rbt->scale[QSE_RBT_KEY] = 1;
|
rbt->scale[QSE_RBT_KEY] = (kscale < 1)? 1: kscale;
|
||||||
rbt->scale[QSE_RBT_VAL] = 1;
|
rbt->scale[QSE_RBT_VAL] = (vscale < 1)? 1: vscale;
|
||||||
rbt->size = 0;
|
rbt->size = 0;
|
||||||
|
|
||||||
rbt->comper = comp_key;
|
rbt->mancbs = &mancbs[0];
|
||||||
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;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* self-initializing nil */
|
/* self-initializing nil */
|
||||||
QSE_MEMSET(&rbt->nil, 0, QSE_SIZEOF(rbt->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);
|
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,
|
return rbt->mancbs;
|
||||||
"The ID should be either QSE_RBT_KEY or QSE_RBT_VAL");
|
|
||||||
return rbt->scale[id];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
QSE_ASSERT (mancbs != QSE_NULL);
|
||||||
"The ID should be either QSE_RBT_KEY or QSE_RBT_VAL");
|
rbt->mancbs = mancbs;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t qse_rbt_getsize (rbt_t* rbt)
|
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))
|
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) return pair;
|
||||||
|
|
||||||
if (n > 0) pair = pair->right;
|
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,
|
/* if the old value and the new value are the same,
|
||||||
* it just calls the handler for this condition.
|
* it just calls the handler for this condition.
|
||||||
* No value replacement occurs. */
|
* 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
|
else
|
||||||
{
|
{
|
||||||
copier_t vcop = rbt->copier[QSE_RBT_VAL];
|
copier_t vcop = rbt->mancbs->copier[QSE_RBT_VAL];
|
||||||
void* ovptr = VPTR(pair);
|
void* ovptr = VPTR(pair);
|
||||||
size_t ovlen = VLEN(pair);
|
size_t ovlen = VLEN(pair);
|
||||||
|
|
||||||
@ -487,7 +455,7 @@ static pair_t* change_pair_val (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* need to reconstruct the pair */
|
/* need to reconstruct the pair */
|
||||||
pair_t* p = alloc_pair (rbt,
|
pair_t* p = qse_rbt_allocpair (rbt,
|
||||||
KPTR(pair), KLEN(pair),
|
KPTR(pair), KLEN(pair),
|
||||||
vptr, vlen);
|
vptr, vlen);
|
||||||
if (p == QSE_NULL) return QSE_NULL;
|
if (p == QSE_NULL) return QSE_NULL;
|
||||||
@ -514,7 +482,7 @@ static pair_t* change_pair_val (
|
|||||||
|
|
||||||
if (pair == rbt->root) rbt->root = p;
|
if (pair == rbt->root) rbt->root = p;
|
||||||
|
|
||||||
free_pair (rbt, pair);
|
qse_rbt_freepair (rbt, pair);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -527,9 +495,9 @@ static pair_t* change_pair_val (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* free up the old value */
|
/* 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))
|
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)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
@ -572,7 +540,7 @@ static pair_t* insert (
|
|||||||
|
|
||||||
if (opt == UPDATE) return QSE_NULL;
|
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 (xnew == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
if (xpar == QSE_NULL)
|
if (xpar == QSE_NULL)
|
||||||
@ -584,7 +552,7 @@ static pair_t* insert (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* perform normal binary insert */
|
/* 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)
|
if (n > 0)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (xpar->right == &rbt->nil);
|
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))
|
if (y->color == QSE_RBT_BLACK && !IS_NIL(rbt,x))
|
||||||
adjust_for_delete (rbt, x, par);
|
adjust_for_delete (rbt, x, par);
|
||||||
|
|
||||||
free_pair (rbt, y);
|
qse_rbt_freepair (rbt, y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -796,7 +764,7 @@ static void delete_pair (rbt_t* rbt, pair_t* pair)
|
|||||||
if (y->right->parent == pair) y->right->parent = y;
|
if (y->right->parent == pair) y->right->parent = y;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free_pair (rbt, pair);
|
qse_rbt_freepair (rbt, pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
rbt->size--;
|
rbt->size--;
|
||||||
@ -917,3 +885,27 @@ void qse_rbt_rwalk (rbt_t* rbt, walker_t walker, void* ctx)
|
|||||||
walk (rbt, walker, ctx, RIGHT, LEFT);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
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;
|
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.lab);
|
||||||
qse_str_fini (&sed->tmp.rex);
|
qse_str_fini (&sed->tmp.rex);
|
||||||
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
qse_map_setcopier (&sed->tmp.labs, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
|
qse_map_setmancbs (&sed->tmp.labs,
|
||||||
qse_map_setscale (&sed->tmp.labs, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
|
qse_map_mancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER)
|
||||||
|
);
|
||||||
|
|
||||||
if (qse_lda_init (&sed->e.txt.appended, mmgr, 32) == QSE_NULL)
|
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;
|
qse_ssize_t n;
|
||||||
int ret = 0;
|
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;
|
sed->e.subst_done = 0;
|
||||||
qse_lda_clear (&sed->e.txt.appended);
|
qse_lda_clear (&sed->e.txt.appended);
|
||||||
qse_str_clear (&sed->e.txt.read);
|
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.fun = outf;
|
||||||
sed->e.out.eof = 0;
|
sed->e.out.eof = 0;
|
||||||
sed->e.out.len = 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);
|
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*(qse_sed_t**)QSE_XTN(&sed->e.out.files) = sed;
|
*(qse_sed_t**)QSE_XTN(&sed->e.out.files) = sed;
|
||||||
qse_map_setcopier (
|
qse_map_setmancbs (&sed->e.out.files, &mancbs);
|
||||||
&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);
|
|
||||||
|
|
||||||
sed->e.in.fun = inf;
|
sed->e.in.fun = inf;
|
||||||
sed->e.in.eof = 0;
|
sed->e.in.eof = 0;
|
||||||
|
@ -9,6 +9,20 @@
|
|||||||
if (f() == -1) return -1; \
|
if (f() == -1) return -1; \
|
||||||
} while (0)
|
} 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 ()
|
static int test1 ()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -97,17 +111,13 @@ static int test2 ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
mmgr.udd = fma;
|
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_printf (QSE_T("cannot initialize a tree\n"));
|
||||||
qse_fma_close (fma);
|
qse_fma_close (fma);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
qse_rbt_setmancbs (&rbt, &mancbs);
|
||||||
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));
|
|
||||||
|
|
||||||
for (x = 10; x < 100; x++)
|
for (x = 10; x < 100; x++)
|
||||||
{
|
{
|
||||||
|
@ -10,23 +10,6 @@
|
|||||||
if (f() == -1) return -1; \
|
if (f() == -1) return -1; \
|
||||||
} while (0)
|
} 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)
|
static int test1_build (qse_htb_t* s1)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -129,10 +112,10 @@ static int test1 ()
|
|||||||
s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 5, 70, 1, 1);
|
s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 5, 70, 1, 1);
|
||||||
if (s1 == QSE_NULL)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
qse_htb_setmancbs (s1, &mancbs1);
|
qse_htb_setmancbs (s1, qse_htb_mancbs(QSE_HTB_MANCBS_INLINE_COPIERS));
|
||||||
|
|
||||||
if (test1_build(s1) == -1)
|
if (test1_build(s1) == -1)
|
||||||
{
|
{
|
||||||
@ -174,17 +157,17 @@ static int test2 ()
|
|||||||
QSE_T("what the hell is this"),
|
QSE_T("what the hell is this"),
|
||||||
QSE_T("oh my goddess"),
|
QSE_T("oh my goddess"),
|
||||||
QSE_T("hello mr monkey"),
|
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,
|
s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 1, 70,
|
||||||
QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t));
|
QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t));
|
||||||
if (s1 == QSE_NULL)
|
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;
|
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++)
|
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);
|
s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 1, 70);
|
||||||
if (s1 == QSE_NULL)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +290,7 @@ static int test4 ()
|
|||||||
s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 1, 70);
|
s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 1, 70);
|
||||||
if (s1 == QSE_NULL)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,6 +319,98 @@ static int test4 ()
|
|||||||
}
|
}
|
||||||
#endif
|
#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 ()
|
int main ()
|
||||||
{
|
{
|
||||||
R (test1);
|
R (test1);
|
||||||
@ -344,5 +419,6 @@ int main ()
|
|||||||
R (test3);
|
R (test3);
|
||||||
R (test4);
|
R (test4);
|
||||||
#endif
|
#endif
|
||||||
|
R (test5);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -34,22 +34,13 @@ static int test1 ()
|
|||||||
qse_rbt_t* s1;
|
qse_rbt_t* s1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0);
|
s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0, 1, 1);
|
||||||
if (s1 == QSE_NULL)
|
if (s1 == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("cannot open a table\n"));
|
qse_printf (QSE_T("cannot open a table\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS));
|
||||||
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);
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = 0; i < 20; i++)
|
for (i = 0; i < 20; i++)
|
||||||
{
|
{
|
||||||
@ -103,17 +94,13 @@ static int test2 ()
|
|||||||
{
|
{
|
||||||
qse_rbt_t* s1;
|
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)
|
if (s1 == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("cannot open a table\n"));
|
qse_printf (QSE_T("cannot open a table\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
qse_rbt_setmancbs (s1, qse_rbt_mancbs(QSE_RBT_MANCBS_INLINE_COPIERS));
|
||||||
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_insert (s1, QSE_T("hello"), 5, QSE_T("mr. monkey"), 10);
|
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);
|
qse_rbt_insert (s1, QSE_T("world"), 5, QSE_T("ms. panda"), 9);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user