* renamed map to htb
* added qse_awk_findgbl() * added Awk::findGlobal() * began working on red-black tree
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: Awk.hpp 318 2009-12-18 12:34:42Z hyunghwan.chung $
|
||||
* $Id: Awk.hpp 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -22,7 +22,7 @@
|
||||
#define _QSE_AWK_AWK_HPP_
|
||||
|
||||
#include <qse/awk/awk.h>
|
||||
#include <qse/cmn/map.h>
|
||||
#include <qse/cmn/htb.h>
|
||||
#include <qse/cmn/chr.h>
|
||||
#include <qse/cmn/Mmged.hpp>
|
||||
#include <stdarg.h>
|
||||
@ -42,8 +42,8 @@ QSE_BEGIN_NAMESPACE(QSE)
|
||||
class Awk: public Mmged
|
||||
{
|
||||
public:
|
||||
typedef qse_map_t map_t;
|
||||
typedef qse_map_pair_t pair_t;
|
||||
typedef qse_htb_t htb_t;
|
||||
typedef qse_htb_pair_t pair_t;
|
||||
|
||||
/** Defines a primitive handle */
|
||||
typedef qse_awk_t awk_t;
|
||||
@ -912,6 +912,15 @@ public:
|
||||
const char_t* name ///< variable name
|
||||
);
|
||||
|
||||
///
|
||||
/// The addGlobal() function returns the numeric ID of an intrinsic
|
||||
// global variable.
|
||||
/// @return integer >= 0 on success, -1 on failure.
|
||||
///
|
||||
int findGlobal (
|
||||
const char_t* name ///> variable name
|
||||
);
|
||||
|
||||
///
|
||||
/// The setGlobal() function sets the value of a global variable
|
||||
/// identified by @a id. The @a id is either a value returned by
|
||||
@ -1069,7 +1078,7 @@ protected:
|
||||
errstr_t dflerrstr;
|
||||
errinf_t errinf;
|
||||
|
||||
map_t* functionMap;
|
||||
htb_t* functionMap;
|
||||
|
||||
Source* sourceReader;
|
||||
Source* sourceWriter;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h 311 2009-12-09 11:35:54Z hyunghwan.chung $
|
||||
* $Id: awk.h 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/cmn/map.h>
|
||||
#include <qse/cmn/htb.h>
|
||||
#include <qse/cmn/str.h>
|
||||
|
||||
/** @file
|
||||
@ -216,7 +216,7 @@ struct qse_awk_val_map_t
|
||||
* integers switch to map dynamically once the
|
||||
* non-integral index is seen.
|
||||
*/
|
||||
qse_map_t* map;
|
||||
qse_htb_t* map;
|
||||
};
|
||||
typedef struct qse_awk_val_map_t qse_awk_val_map_t;
|
||||
|
||||
@ -1216,7 +1216,7 @@ int qse_awk_addgbl (
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_delgbl() function deletes an instrinsic global variable by name.
|
||||
* The qse_awk_delgbl() function deletes an intrinsic global variable by name.
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int qse_awk_delgbl (
|
||||
@ -1225,6 +1225,17 @@ int qse_awk_delgbl (
|
||||
qse_size_t len /**< name length */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_findgbl function returns the numeric ID of an intrinsic global
|
||||
* variable.
|
||||
* @return number >= 0 on success, -1 on failure
|
||||
*/
|
||||
int qse_awk_findgbl (
|
||||
qse_awk_t* awk, /**< awk */
|
||||
const qse_char_t* name, /**< variable name */
|
||||
qse_size_t len /**< name length */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_awk_addfnc() function adds an intrinsic function.
|
||||
*/
|
||||
@ -1605,7 +1616,7 @@ void* qse_awk_rtx_getxtn (
|
||||
/**
|
||||
* The qse_awk_rtx_getnvmap() gets the map of named variables
|
||||
*/
|
||||
qse_map_t* qse_awk_rtx_getnvmap (
|
||||
qse_htb_t* qse_awk_rtx_getnvmap (
|
||||
qse_awk_rtx_t* rtx /**< runtime context */
|
||||
);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
pkgincludedir = $(includedir)/qse/cmn
|
||||
|
||||
pkginclude_HEADERS = \
|
||||
mem.h chr.h str.h lda.h map.h \
|
||||
mem.h chr.h str.h lda.h htb.h rbt.h \
|
||||
rex.h sll.h dll.h opt.h tio.h \
|
||||
fio.h pio.h sio.h time.h misc.h main.h stdio.h
|
||||
|
||||
|
@ -51,9 +51,9 @@ CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__pkginclude_HEADERS_DIST = mem.h chr.h str.h lda.h map.h rex.h \
|
||||
sll.h dll.h opt.h tio.h fio.h pio.h sio.h time.h misc.h main.h \
|
||||
stdio.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
||||
am__pkginclude_HEADERS_DIST = mem.h chr.h str.h lda.h htb.h rbt.h \
|
||||
rex.h sll.h dll.h opt.h tio.h fio.h pio.h sio.h time.h misc.h \
|
||||
main.h stdio.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
@ -220,9 +220,9 @@ target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
pkginclude_HEADERS = mem.h chr.h str.h lda.h map.h rex.h sll.h dll.h \
|
||||
opt.h tio.h fio.h pio.h sio.h time.h misc.h main.h stdio.h \
|
||||
$(am__append_1)
|
||||
pkginclude_HEADERS = mem.h chr.h str.h lda.h htb.h rbt.h rex.h sll.h \
|
||||
dll.h opt.h tio.h fio.h pio.h sio.h time.h misc.h main.h \
|
||||
stdio.h $(am__append_1)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
486
qse/include/qse/cmn/htb.h
Normal file
486
qse/include/qse/cmn/htb.h
Normal file
@ -0,0 +1,486 @@
|
||||
/*
|
||||
* $Id: htb.h 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
|
||||
QSE is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
QSE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_CMN_HTB_H_
|
||||
#define _QSE_CMN_HTB_H_
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
/**@file
|
||||
* A hash table maintains buckets for key/value pairs with the same key hash
|
||||
* chained under the same bucket.
|
||||
*/
|
||||
|
||||
/* values that can be returned by qse_htb_walker_t */
|
||||
enum qse_htb_walk_t
|
||||
{
|
||||
QSE_HTB_WALK_STOP = 0,
|
||||
QSE_HTB_WALK_FORWARD = 1
|
||||
};
|
||||
|
||||
enum qse_htb_id_t
|
||||
{
|
||||
QSE_HTB_KEY = 0,
|
||||
QSE_HTB_VAL = 1
|
||||
};
|
||||
|
||||
typedef struct qse_htb_t qse_htb_t;
|
||||
typedef struct qse_htb_pair_t qse_htb_pair_t;
|
||||
typedef enum qse_htb_walk_t qse_htb_walk_t;
|
||||
typedef enum qse_htb_id_t qse_htb_id_t;
|
||||
|
||||
/**
|
||||
* The qse_htb_copier_t type defines a pair contruction callback
|
||||
*/
|
||||
typedef void* (*qse_htb_copier_t) (
|
||||
qse_htb_t* htb /* hash table */,
|
||||
void* dptr /* the pointer to a key or a value */,
|
||||
qse_size_t dlen /* the length of a key or a value */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_freeer_t defines a key/value destruction callback
|
||||
*/
|
||||
typedef void (*qse_htb_freeer_t) (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
void* dptr, /**< the pointer to a key or a value */
|
||||
qse_size_t dlen /**< the 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, /**< the pointer to a key */
|
||||
qse_size_t klen /**< the length of a key in bytes */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_comper_t type defines a key comparator that is called when
|
||||
* the htb needs to compare keys. A htb is created with a default comparator
|
||||
* which performs bitwise comparison between two keys.
|
||||
*
|
||||
* The comparator should return 0 if the keys are the same and a non-zero
|
||||
* integer otherwise.
|
||||
*/
|
||||
typedef int (*qse_htb_comper_t) (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
const void* kptr1, /**< the pointer to a key */
|
||||
qse_size_t klen1, /**< the length of a key */
|
||||
const void* kptr2, /**< the pointer to a key */
|
||||
qse_size_t klen2 /**< the length of a key */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_keeper_t type defines a value keeper that is called when
|
||||
* a value is retained in the context that it should be destroyed because
|
||||
* it is identical to a new value. Two values are identical if their beginning
|
||||
* pointers and their lengths are equal.
|
||||
*/
|
||||
typedef void (*qse_htb_keeper_t) (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
void* vptr, /**< value pointer */
|
||||
qse_size_t vlen /**< value length */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_sizer_T type defines a bucket size claculator that is called
|
||||
* when hash table should resize the bucket. The current bucket size +1 is passed
|
||||
* as the hint.
|
||||
*/
|
||||
typedef qse_size_t (*qse_htb_sizer_t) (
|
||||
qse_htb_t* htb, /**< htb */
|
||||
qse_size_t hint /**< sizing hint */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_walker_t defines a pair visitor.
|
||||
*/
|
||||
typedef qse_htb_walk_t (*qse_htb_walker_t) (
|
||||
qse_htb_t* htb, /**< htb */
|
||||
qse_htb_pair_t* pair, /**< pointer to a key/value pair */
|
||||
void* ctx /**< pointer to user-defined data */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_pair_t type defines hash table pair. A pair is composed of a key
|
||||
* and a value. It maintains pointers to the beginning of a key and a value
|
||||
* plus their length. The length is scaled down with the scale factor
|
||||
* specified in an owning htb. Use macros defined in the
|
||||
*/
|
||||
struct qse_htb_pair_t
|
||||
{
|
||||
void* kptr; /**< the pointer to a key */
|
||||
qse_size_t klen; /**< the length of a key */
|
||||
void* vptr; /**< the pointer to a value */
|
||||
qse_size_t vlen; /**< the length of a value */
|
||||
qse_htb_pair_t* next; /**< the next pair under the same slot */
|
||||
};
|
||||
|
||||
/**
|
||||
* The qse_htb_t type defines a hash table.
|
||||
*/
|
||||
struct qse_htb_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (htb)
|
||||
|
||||
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_byte_t scale[2]; /**< length scale */
|
||||
qse_byte_t factor; /**< load factor */
|
||||
qse_byte_t filler0;
|
||||
|
||||
qse_size_t size;
|
||||
qse_size_t capa;
|
||||
qse_size_t threshold;
|
||||
|
||||
qse_htb_pair_t** bucket;
|
||||
};
|
||||
|
||||
#define QSE_HTB_COPIER_SIMPLE ((qse_htb_copier_t)1)
|
||||
#define QSE_HTB_COPIER_INLINE ((qse_htb_copier_t)2)
|
||||
|
||||
/****m* Common/QSE_HTB_SIZE
|
||||
* NAME
|
||||
* QSE_HTB_SIZE - get the number of pairs
|
||||
* DESCRIPTION
|
||||
* The QSE_HTB_SIZE() macro returns the number of pairs in hash table.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
#define QSE_HTB_SIZE(m) ((m)->size)
|
||||
/*****/
|
||||
|
||||
/****m* Common/QSE_HTB_CAPA
|
||||
* NAME
|
||||
* QSE_HTB_CAPA - get the capacity of hash table
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The QSE_HTB_CAPA() macro returns the maximum number of pairs hash table can hold.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
#define QSE_HTB_CAPA(m) ((m)->capa)
|
||||
/*****/
|
||||
|
||||
#define QSE_HTB_KCOPIER(m) ((m)->copier[QSE_HTB_KEY])
|
||||
#define QSE_HTB_VCOPIER(m) ((m)->copier[QSE_HTB_VAL])
|
||||
#define QSE_HTB_KFREEER(m) ((m)->freeer[QSE_HTB_KEY])
|
||||
#define QSE_HTB_VFREEER(m) ((m)->freeer[QSE_HTB_VAL])
|
||||
#define QSE_HTB_HASHER(m) ((m)->hasher)
|
||||
#define QSE_HTB_COMPER(m) ((m)->comper)
|
||||
#define QSE_HTB_KEEPER(m) ((m)->keeper)
|
||||
#define QSE_HTB_SIZER(m) ((m)->sizer)
|
||||
|
||||
#define QSE_HTB_FACTOR(m) ((m)->factor)
|
||||
#define QSE_HTB_KSCALE(m) ((m)->scale[QSE_HTB_KEY])
|
||||
#define QSE_HTB_VSCALE(m) ((m)->scale[QSE_HTB_VAL])
|
||||
|
||||
#define QSE_HTB_KPTR(p) ((p)->kptr)
|
||||
#define QSE_HTB_KLEN(p) ((p)->klen)
|
||||
#define QSE_HTB_VPTR(p) ((p)->vptr)
|
||||
#define QSE_HTB_VLEN(p) ((p)->vlen)
|
||||
#define QSE_HTB_NEXT(p) ((p)->next)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (htb)
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
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 */
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* The qse_htb_close() function destroys a hash table.
|
||||
*/
|
||||
void qse_htb_close (
|
||||
qse_htb_t* htb /**< hash table */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_init() function initializes a hash table
|
||||
*/
|
||||
qse_htb_t* qse_htb_init (
|
||||
qse_htb_t* htb,
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t capa,
|
||||
int factor
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_fini() funtion finalizes a hash table
|
||||
*/
|
||||
void qse_htb_fini (
|
||||
qse_htb_t* htb
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_getsize() function gets the number of pairs in hash table.
|
||||
*/
|
||||
qse_size_t qse_htb_getsize (
|
||||
qse_htb_t* htb
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_getcapa() function gets the number of slots allocated
|
||||
* in a hash bucket.
|
||||
*/
|
||||
qse_size_t qse_htb_getcapa (
|
||||
qse_htb_t* htb /**< hash table */
|
||||
);
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_getcopier() function gets a data copier.
|
||||
*/
|
||||
qse_htb_copier_t qse_htb_getcopier (
|
||||
qse_htb_t* htb,
|
||||
qse_htb_id_t id /**< QSE_HTB_KEY or QSE_HTB_VAL */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_setcopier() function specifies how to clone an element.
|
||||
* A special copier QSE_HTB_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_htb_setcopier (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
qse_htb_id_t id, /**< QSE_HTB_KEY or QSE_HTB_VAL */
|
||||
qse_htb_copier_t copier /**< element copier */
|
||||
);
|
||||
|
||||
qse_htb_freeer_t qse_htb_getfreeer (
|
||||
qse_htb_t* htb, /**< htb */
|
||||
qse_htb_id_t id /**< QSE_HTB_KEY or QSE_HTB_VAL */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_setfreeer() function specifies how to destroy an element.
|
||||
* The @a freeer is called when a node containing the element is destroyed.
|
||||
*/
|
||||
void qse_htb_setfreeer (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
qse_htb_id_t id, /**< QSE_HTB_KEY or QSE_HTB_VAL */
|
||||
qse_htb_freeer_t freeer /**< an element freeer */
|
||||
);
|
||||
|
||||
|
||||
qse_htb_hasher_t qse_htb_gethasher (
|
||||
qse_htb_t* htb
|
||||
);
|
||||
|
||||
void qse_htb_sethasher (
|
||||
qse_htb_t* htb,
|
||||
qse_htb_hasher_t hasher
|
||||
);
|
||||
|
||||
qse_htb_comper_t qse_htb_getcomper (
|
||||
qse_htb_t* htb
|
||||
);
|
||||
|
||||
void qse_htb_setcomper (
|
||||
qse_htb_t* htb,
|
||||
qse_htb_comper_t comper
|
||||
);
|
||||
|
||||
qse_htb_keeper_t qse_htb_getkeeper (
|
||||
qse_htb_t* htb
|
||||
);
|
||||
|
||||
void qse_htb_setkeeper (
|
||||
qse_htb_t* htb,
|
||||
qse_htb_keeper_t keeper
|
||||
);
|
||||
|
||||
qse_htb_sizer_t qse_htb_getsizer (
|
||||
qse_htb_t* htb
|
||||
);
|
||||
|
||||
/* the sizer function is passed hash table object and htb->capa + 1 */
|
||||
void qse_htb_setsizer (
|
||||
qse_htb_t* htb,
|
||||
qse_htb_sizer_t sizer
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_search() function searches 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.
|
||||
*/
|
||||
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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_upsert() function searches hash table for the pair with a
|
||||
* 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.
|
||||
*/
|
||||
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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* 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_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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_delete() function deletes a pair with a matching key
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
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 */
|
||||
);
|
||||
|
||||
/*
|
||||
* The qse_htb_clear() function empties a hash table
|
||||
*/
|
||||
void qse_htb_clear (
|
||||
qse_htb_t* htb /**< hash table */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_walk() function traverses a hash table.
|
||||
*/
|
||||
void qse_htb_walk (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
qse_htb_walker_t walker, /**< pointer to the function for each pair */
|
||||
void* ctx /**< pointer to user-specific data */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_getfirstpair() function returns the pointer to the first pair
|
||||
* in a hash table.
|
||||
*/
|
||||
qse_htb_pair_t* qse_htb_getfirstpair (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
qse_size_t* buckno /**< bucket number */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_htb_getnextpair() function returns the pointer to the next pair
|
||||
* to the current pair @a pair in a hash table.
|
||||
*/
|
||||
qse_htb_pair_t* qse_htb_getnextpair (
|
||||
qse_htb_t* htb, /**< hash table */
|
||||
qse_htb_pair_t* pair, /**< current pair */
|
||||
qse_size_t* buckno /**< bucket number */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,509 +0,0 @@
|
||||
/*
|
||||
* $Id: map.h 327 2010-05-10 13:15:55Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
|
||||
QSE is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
QSE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_CMN_MAP_H_
|
||||
#define _QSE_CMN_MAP_H_
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
/**@file
|
||||
* A hash map maintains buckets for key/value pairs with the same key hash
|
||||
* chained under the same bucket.
|
||||
*/
|
||||
|
||||
/* values that can be returned by qse_map_walker_t */
|
||||
enum qse_map_walk_t
|
||||
{
|
||||
QSE_MAP_WALK_STOP = 0,
|
||||
QSE_MAP_WALK_FORWARD = 1
|
||||
};
|
||||
|
||||
enum qse_map_id_t
|
||||
{
|
||||
QSE_MAP_KEY = 0,
|
||||
QSE_MAP_VAL = 1
|
||||
};
|
||||
|
||||
typedef struct qse_map_t qse_map_t;
|
||||
typedef struct qse_map_pair_t qse_map_pair_t;
|
||||
typedef enum qse_map_walk_t qse_map_walk_t;
|
||||
typedef enum qse_map_id_t qse_map_id_t;
|
||||
|
||||
/**
|
||||
* The qse_map_copier_t type defines a pair contruction callback
|
||||
*/
|
||||
typedef void* (*qse_map_copier_t) (
|
||||
qse_map_t* map /* a map */,
|
||||
void* dptr /* the pointer to a key or a value */,
|
||||
qse_size_t dlen /* the length of a key or a value */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_freeer_t defines a key/value destruction callback
|
||||
*/
|
||||
typedef void (*qse_map_freeer_t) (
|
||||
qse_map_t* map /* a map */,
|
||||
void* dptr /* the pointer to a key or a value */,
|
||||
qse_size_t dlen /* the length of a key or a value */
|
||||
);
|
||||
|
||||
/* key hasher */
|
||||
typedef qse_size_t (*qse_map_hasher_t) (
|
||||
qse_map_t* map /* a map */,
|
||||
const void* kptr /* the pointer to a key */,
|
||||
qse_size_t klen /* the length of a key in bytes */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_comper_t type defines a key comparator that is called when
|
||||
* the map needs to compare keys. A map is created with a default comparator
|
||||
* which performs bitwise comparison between two keys.
|
||||
*
|
||||
* The comparator should return 0 if the keys are the same and a non-zero
|
||||
* integer otherwise.
|
||||
*/
|
||||
typedef int (*qse_map_comper_t) (
|
||||
qse_map_t* map, /**< a map */
|
||||
const void* kptr1, /**< the pointer to a key */
|
||||
qse_size_t klen1, /**< the length of a key */
|
||||
const void* kptr2, /**< the pointer to a key */
|
||||
qse_size_t klen2 /**< the length of a key */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_keeper_t type defines a value keeper that is called when
|
||||
* a value is retained in the context that it should be destroyed because
|
||||
* it is identical to a new value. Two values are identical if their beginning
|
||||
* pointers and their lengths are equal.
|
||||
*/
|
||||
typedef void (*qse_map_keeper_t) (
|
||||
qse_map_t* map, /**< a map */
|
||||
void* vptr, /**< value pointer */
|
||||
qse_size_t vlen /**< value length */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_sizer_T type defines a bucket size claculator that is called
|
||||
* when a map should resize the bucket. The current bucket size +1 is passed
|
||||
* as the hint.
|
||||
*/
|
||||
typedef qse_size_t (*qse_map_sizer_t) (
|
||||
qse_map_t* map, /**< a map */
|
||||
qse_size_t hint /**< a sizing hint */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_walker_t defines a pair visitor.
|
||||
*/
|
||||
typedef qse_map_walk_t (*qse_map_walker_t) (
|
||||
qse_map_t* map, /**< a map */
|
||||
qse_map_pair_t* pair, /**< the pointer to a key/value pair */
|
||||
void* arg /**< the pointer to user-defined data */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_pair_t type defines a map pair. A pair is composed of a key
|
||||
* and a value. It maintains pointers to the beginning of a key and a value
|
||||
* plus their length. The length is scaled down with the scale factor
|
||||
* specified in an owning map. Use macros defined in the
|
||||
*/
|
||||
struct qse_map_pair_t
|
||||
{
|
||||
void* kptr; /**< the pointer to a key */
|
||||
qse_size_t klen; /**< the length of a key */
|
||||
void* vptr; /**< the pointer to a value */
|
||||
qse_size_t vlen; /**< the length of a value */
|
||||
qse_map_pair_t* next; /**< the next pair under the same slot */
|
||||
};
|
||||
|
||||
/**
|
||||
* The qse_map_t type defines a hash map.
|
||||
*/
|
||||
struct qse_map_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (map)
|
||||
|
||||
qse_map_copier_t copier[2];
|
||||
qse_map_freeer_t freeer[2];
|
||||
qse_map_hasher_t hasher; /* key hasher */
|
||||
qse_map_comper_t comper; /* key comparator */
|
||||
qse_map_keeper_t keeper; /* value keeper */
|
||||
qse_map_sizer_t sizer; /* bucket capacity recalculator */
|
||||
qse_byte_t scale[2]; /* length scale */
|
||||
qse_byte_t factor; /* load factor */
|
||||
qse_byte_t filler0;
|
||||
qse_size_t size;
|
||||
qse_size_t capa;
|
||||
qse_size_t threshold;
|
||||
qse_map_pair_t** bucket;
|
||||
};
|
||||
|
||||
#define QSE_MAP_COPIER_SIMPLE ((qse_map_copier_t)1)
|
||||
#define QSE_MAP_COPIER_INLINE ((qse_map_copier_t)2)
|
||||
|
||||
/****m* Common/QSE_MAP_SIZE
|
||||
* NAME
|
||||
* QSE_MAP_SIZE - get the number of pairs
|
||||
* DESCRIPTION
|
||||
* The QSE_MAP_SIZE() macro returns the number of pairs in a map.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
#define QSE_MAP_SIZE(m) ((m)->size)
|
||||
/*****/
|
||||
|
||||
/****m* Common/QSE_MAP_CAPA
|
||||
* NAME
|
||||
* QSE_MAP_CAPA - get the capacity of a map
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The QSE_MAP_CAPA() macro returns the maximum number of pairs a map can hold.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
#define QSE_MAP_CAPA(m) ((m)->capa)
|
||||
/*****/
|
||||
|
||||
#define QSE_MAP_KCOPIER(m) ((m)->copier[QSE_MAP_KEY])
|
||||
#define QSE_MAP_VCOPIER(m) ((m)->copier[QSE_MAP_VAL])
|
||||
#define QSE_MAP_KFREEER(m) ((m)->freeer[QSE_MAP_KEY])
|
||||
#define QSE_MAP_VFREEER(m) ((m)->freeer[QSE_MAP_VAL])
|
||||
#define QSE_MAP_HASHER(m) ((m)->hasher)
|
||||
#define QSE_MAP_COMPER(m) ((m)->comper)
|
||||
#define QSE_MAP_KEEPER(m) ((m)->keeper)
|
||||
#define QSE_MAP_SIZER(m) ((m)->sizer)
|
||||
|
||||
#define QSE_MAP_FACTOR(m) ((m)->factor)
|
||||
#define QSE_MAP_KSCALE(m) ((m)->scale[QSE_MAP_KEY])
|
||||
#define QSE_MAP_VSCALE(m) ((m)->scale[QSE_MAP_VAL])
|
||||
|
||||
#define QSE_MAP_KPTR(p) ((p)->kptr)
|
||||
#define QSE_MAP_KLEN(p) ((p)->klen)
|
||||
#define QSE_MAP_VPTR(p) ((p)->vptr)
|
||||
#define QSE_MAP_VLEN(p) ((p)->vlen)
|
||||
#define QSE_MAP_NEXT(p) ((p)->next)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (map)
|
||||
|
||||
/****f* Common/qse_map_open
|
||||
* NAME
|
||||
* qse_map_open - creates a hash map
|
||||
* DESCRIPTION
|
||||
* The qse_map_open() function creates a hash map with a dynamic array
|
||||
* bucket and a list of values chained. The initial capacity should be larger
|
||||
* than 0. The load factor should be between 0 and 100 inclusive and the load
|
||||
* factor of 0 disables bucket resizing. If you need extra space associated
|
||||
* with a map, you may pass a non-zero value as the second parameter.
|
||||
* The QSE_MAP_XTN() macro and the qse_map_getxtn() function return the
|
||||
* pointer to the beginning of the extension.
|
||||
* RETURN
|
||||
* The qse_map_open() function returns an qse_map_t pointer on success and
|
||||
* QSE_NULL on failure.
|
||||
* SEE ALSO
|
||||
* QSE_MAP_XTN, qse_map_getxtn
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_map_t* qse_map_open (
|
||||
qse_mmgr_t* mmgr /* a memory manager */,
|
||||
qse_size_t ext /* extension size in bytes */,
|
||||
qse_size_t capa /* initial capacity */,
|
||||
int factor /* load factor */
|
||||
);
|
||||
/******/
|
||||
|
||||
|
||||
/****f* Common/qse_map_close
|
||||
* NAME
|
||||
* qse_map_close - destroy a hash map
|
||||
* DESCRIPTION
|
||||
* The qse_map_close() function destroys a hash map.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_map_close (
|
||||
qse_map_t* map /* a map */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_map_init
|
||||
* NAME
|
||||
* qse_map_init - initialize a hash map
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_map_t* qse_map_init (
|
||||
qse_map_t* map,
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t capa,
|
||||
int factor
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_map_fini
|
||||
* NAME
|
||||
* qse_map_fini - finalize a hash map
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_map_fini (
|
||||
qse_map_t* map
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_map_getsize
|
||||
* NAME
|
||||
* qse_map_getsize - get the number of pairs in a map
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_map_getsize (
|
||||
qse_map_t* map
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_map_getcapa
|
||||
* NAME
|
||||
* qse_map_getcapa - get the number of slots in a hash bucket
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_map_getcapa (
|
||||
qse_map_t* map
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_map_getscale
|
||||
* NAME
|
||||
* qse_map_getscale - get the scale factor
|
||||
* PARAMETERS
|
||||
* * id - QSE_MAP_KEY or QSE_MAP_VAL
|
||||
* SYNOPSIS
|
||||
*/
|
||||
int qse_map_getscale (
|
||||
qse_map_t* map,
|
||||
qse_map_id_t id /* QSE_MAP_KEY or QSE_MAP_VAL */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_map_setscale
|
||||
* NAME
|
||||
* qse_map_setscale - set the scale factor
|
||||
* DESCRIPTION
|
||||
* The qse_map_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 map is created with a scale factor of 1.
|
||||
* The scale factor should be larger than 0 and less than 256.
|
||||
* PARAMETERS
|
||||
* * id - QSE_MAP_KEY or QSE_MAP_VAL
|
||||
* * scale - a scale factor in bytes
|
||||
* NOTES
|
||||
* It is a bad idea to change the scale factor when a map is not empty.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_map_setscale (
|
||||
qse_map_t* map,
|
||||
qse_map_id_t id,
|
||||
int scale
|
||||
);
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_map_getcopier() function gets a data copier.
|
||||
*/
|
||||
qse_map_copier_t qse_map_getcopier (
|
||||
qse_map_t* map,
|
||||
qse_map_id_t id /**< QSE_MAP_KEY or QSE_MAP_VAL */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_setcopier() function specifies how to clone an element.
|
||||
* A special copier QSE_MAP_COPIER_INLINE is provided. This copier enables
|
||||
* you to copy the data inline to the internal node. No freeer is invoked
|
||||
* when the node is freeed.
|
||||
*
|
||||
* You may set the copier to QSE_NULL to perform no special operation
|
||||
* when the data pointer is rememebered.
|
||||
*/
|
||||
void qse_map_setcopier (
|
||||
qse_map_t* map, /**< a map */
|
||||
qse_map_id_t id, /**< QSE_MAP_KEY or QSE_MAP_VAL */
|
||||
qse_map_copier_t copier /**< element copier */
|
||||
);
|
||||
|
||||
qse_map_freeer_t qse_map_getfreeer (
|
||||
qse_map_t* map, /**< map */
|
||||
qse_map_id_t id /**< QSE_MAP_KEY or QSE_MAP_VAL */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_setfreeer() function specifies how to destroy an element.
|
||||
* The @a freeer is called when a node containing the element is destroyed.
|
||||
*/
|
||||
void qse_map_setfreeer (
|
||||
qse_map_t* map, /**< a map */
|
||||
qse_map_id_t id, /**< QSE_MAP_KEY or QSE_MAP_VAL */
|
||||
qse_map_freeer_t freeer /**< an element freeer */
|
||||
);
|
||||
|
||||
|
||||
qse_map_hasher_t qse_map_gethasher (
|
||||
qse_map_t* map
|
||||
);
|
||||
|
||||
void qse_map_sethasher (
|
||||
qse_map_t* map,
|
||||
qse_map_hasher_t hasher
|
||||
);
|
||||
|
||||
qse_map_comper_t qse_map_getcomper (
|
||||
qse_map_t* map
|
||||
);
|
||||
|
||||
void qse_map_setcomper (
|
||||
qse_map_t* map,
|
||||
qse_map_comper_t comper
|
||||
);
|
||||
|
||||
qse_map_keeper_t qse_map_getkeeper (
|
||||
qse_map_t* map
|
||||
);
|
||||
|
||||
void qse_map_setkeeper (
|
||||
qse_map_t* map,
|
||||
qse_map_keeper_t keeper
|
||||
);
|
||||
|
||||
qse_map_sizer_t qse_map_getsizer (
|
||||
qse_map_t* map
|
||||
);
|
||||
|
||||
/* the sizer function is passed a map object and map->capa + 1 */
|
||||
void qse_map_setsizer (
|
||||
qse_map_t* map,
|
||||
qse_map_sizer_t sizer
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_search() function searches a map 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.
|
||||
*/
|
||||
qse_map_pair_t* qse_map_search (
|
||||
qse_map_t* map, /**< a map */
|
||||
const void* kptr, /**< the pointer to a key */
|
||||
qse_size_t klen /**< the size of the key */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_upsert() function searches a map for the pair with a matching
|
||||
* key. If one is found, it updates the pair. Otherwise, it inserts a new
|
||||
* pair with a key and a value. 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.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_map_pair_t* qse_map_upsert (
|
||||
qse_map_t* map, /**< a map */
|
||||
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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_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.
|
||||
*/
|
||||
qse_map_pair_t* qse_map_ensert (
|
||||
qse_map_t* map, /**< a map */
|
||||
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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_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_map_pair_t* qse_map_insert (
|
||||
qse_map_t* map, /**< a map */
|
||||
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 */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_map_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
|
||||
*/
|
||||
qse_map_pair_t* qse_map_update (
|
||||
qse_map_t* map, /**< a map */
|
||||
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 */
|
||||
);
|
||||
|
||||
/* delete a pair with a matching key */
|
||||
int qse_map_delete (
|
||||
qse_map_t* map /* a map */,
|
||||
const void* kptr /* the pointer to a key */,
|
||||
qse_size_t klen /* the size of the key in bytes */
|
||||
);
|
||||
|
||||
/* clear a map */
|
||||
void qse_map_clear (
|
||||
qse_map_t* map /* a map */
|
||||
);
|
||||
|
||||
/* traverse a map */
|
||||
qse_size_t qse_map_walk (
|
||||
qse_map_t* map /* a map */,
|
||||
qse_map_walker_t walker /* the pointer to the function for each pair */,
|
||||
void* ctx /* a pointer to user-specific data */
|
||||
);
|
||||
|
||||
/* get the pointer to the first pair in the map. */
|
||||
qse_map_pair_t* qse_map_getfirstpair (
|
||||
qse_map_t* map /* a map */,
|
||||
qse_size_t* buckno
|
||||
);
|
||||
|
||||
/* get the pointer to the next pair in the map. */
|
||||
qse_map_pair_t* qse_map_getnextpair (
|
||||
qse_map_t* map /* a map */,
|
||||
qse_map_pair_t* pair,
|
||||
qse_size_t* buckno
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
140
qse/include/qse/cmn/rbt.h
Normal file
140
qse/include/qse/cmn/rbt.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
|
||||
QSE is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
QSE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_CMN_RBT_H_
|
||||
#define _QSE_CMN_RBT_H_
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
enum qse_rbt_id_t
|
||||
{
|
||||
QSE_RBT_KEY = 0,
|
||||
QSE_RBT_VAL = 1
|
||||
};
|
||||
|
||||
typedef struct qse_rbt_t qse_rbt_t;
|
||||
typedef struct qse_rbt_node_t qse_rbt_node_t;
|
||||
typedef enum qse_rbt_id_t qse_rbt_id_t;
|
||||
|
||||
typedef void* (*qse_rbt_copier_t) (
|
||||
qse_rbt_t* rbt, /**< red-black tree */
|
||||
void* dptr, /**< the pointer to a key or a value */
|
||||
qse_size_t dlen /**< the length of a key or a value */
|
||||
);
|
||||
|
||||
typedef void (*qse_rbt_freeer_t) (
|
||||
qse_rbt_t* rbt, /**< red-black tree */
|
||||
void* dptr, /**< the pointer to a key or a value */
|
||||
qse_size_t dlen /**< the length of a key or a value */
|
||||
);
|
||||
|
||||
typedef int (*qse_rbt_comper_t) (
|
||||
qse_rbt_t* rbt, /**< red-black tree */
|
||||
const void* kptr1, /**< the pointer to a key */
|
||||
qse_size_t klen1, /**< the length of a key */
|
||||
const void* kptr2, /**< the pointer to a key */
|
||||
qse_size_t klen2 /**< the length of a key */
|
||||
);
|
||||
|
||||
struct qse_rbt_node_t
|
||||
{
|
||||
int key;
|
||||
int value;
|
||||
|
||||
enum
|
||||
{
|
||||
QSE_RBT_RED,
|
||||
QSE_RBT_BLACK
|
||||
} color;
|
||||
|
||||
qse_rbt_node_t* parent;
|
||||
qse_rbt_node_t* child[2]; /* left and right */
|
||||
};
|
||||
|
||||
struct qse_rbt_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (rbt)
|
||||
|
||||
qse_rbt_node_t nil; /**< internal nil node */
|
||||
|
||||
qse_byte_t scale[2]; /**< scale factor */
|
||||
|
||||
qse_rbt_copier_t copier[2];
|
||||
qse_rbt_freeer_t freeer[2];
|
||||
qse_rbt_comper_t comper;
|
||||
|
||||
qse_size_t size; /**< number of nodes */
|
||||
qse_rbt_node_t* root;
|
||||
};
|
||||
|
||||
enum qse_rbt_walk_t
|
||||
{
|
||||
QSE_RBT_WALK_STOP = 0,
|
||||
QSE_RBT_WALK_FORWARD = 1
|
||||
};
|
||||
|
||||
typedef enum qse_rbt_walk_t qse_rbt_walk_t;
|
||||
|
||||
/**
|
||||
* The qse_rbt_walker_t defines a pair visitor.
|
||||
*/
|
||||
typedef qse_rbt_walk_t (*qse_rbt_walker_t) (
|
||||
qse_rbt_t* rbt, /**< tree */
|
||||
qse_rbt_node_t* node, /**< pointer to a node */
|
||||
void* ctx /**< pointer to user-defined context */
|
||||
);
|
||||
|
||||
#define QSE_RBT_COPIER_SIMPLE ((qse_rbt_copier_t)1)
|
||||
#define QSE_RBT_COPIER_INLINE ((qse_rbt_copier_t)2)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
qse_rbt_t* qse_rbt_open (
|
||||
qse_mmgr_t* mmgr, /**< memory manager */
|
||||
qse_size_t ext /**< size of extension area in bytes */
|
||||
);
|
||||
|
||||
void qse_rbt_close (
|
||||
qse_rbt_t* rbt /**< red-black tree */
|
||||
);
|
||||
|
||||
|
||||
qse_rbt_t* qse_rbt_init (
|
||||
qse_rbt_t* rbt, /**< red-black tree */
|
||||
qse_mmgr_t* mmgr /**< a memory manager */
|
||||
);
|
||||
|
||||
void qse_rbt_fini (
|
||||
qse_rbt_t* rbt /**< red-black tree */
|
||||
);
|
||||
|
||||
void qse_rbt_clear (
|
||||
qse_rbt_t* rbt /**< red-black tree */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: rex.h 326 2010-05-09 13:44:39Z hyunghwan.chung $
|
||||
* $Id: rex.h 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -86,16 +86,16 @@ enum qse_rex_errnum_t
|
||||
QSE_REX_ENOERR = 0,
|
||||
QSE_REX_ENOMEM, /**< no sufficient memory available */
|
||||
QSE_REX_ENOCOMP, /**< no expression compiled */
|
||||
QSE_REX_ERECUR, /**< recursion too deep */
|
||||
QSE_REX_ERPAREN, /**< right parenthesis expected */
|
||||
QSE_REX_ERBRACK, /**< right bracket expected */
|
||||
QSE_REX_ERBRACE, /**< right brace expected */
|
||||
QSE_REX_ECOLON, /**< colon expected */
|
||||
QSE_REX_ECRANGE, /**< invalid character range */
|
||||
QSE_REX_ECCLASS, /**< invalid character class */
|
||||
QSE_REX_EBOUND, /**< invalid occurrence bound */
|
||||
QSE_REX_ESPCAWP, /**< special character at wrong position */
|
||||
QSE_REX_EPREEND /**< premature expression end */
|
||||
QSE_REX_ERECUR, /**< recursion too deep */
|
||||
QSE_REX_ERPAREN, /**< right parenthesis expected */
|
||||
QSE_REX_ERBRACK, /**< right bracket expected */
|
||||
QSE_REX_ERBRACE, /**< right brace expected */
|
||||
QSE_REX_ECOLON, /**< colon expected */
|
||||
QSE_REX_ECRANGE, /**< invalid character range */
|
||||
QSE_REX_ECCLASS, /**< invalid character class */
|
||||
QSE_REX_EBOUND, /**< invalid occurrence bound */
|
||||
QSE_REX_ESPCAWP, /**< special character at wrong position */
|
||||
QSE_REX_EPREEND /**< premature expression end */
|
||||
};
|
||||
typedef enum qse_rex_errnum_t qse_rex_errnum_t;
|
||||
|
||||
@ -111,7 +111,8 @@ enum qse_rex_node_id_t
|
||||
QSE_REX_NODE_CSET, /* character set */
|
||||
QSE_REX_NODE_BRANCH,
|
||||
QSE_REX_NODE_GROUP,
|
||||
QSE_REX_NODE_GROUPEND
|
||||
QSE_REX_NODE_GROUPEND,
|
||||
QSE_REX_NODE_BACKREF /* back reference */
|
||||
};
|
||||
typedef enum qse_rex_node_id_t qse_rex_node_id_t;
|
||||
|
||||
@ -159,6 +160,11 @@ struct qse_rex_node_t
|
||||
qse_rex_node_t* group;
|
||||
int pseudo;
|
||||
} ge;
|
||||
|
||||
struct
|
||||
{
|
||||
int index;
|
||||
} bref;
|
||||
} u;
|
||||
|
||||
struct
|
||||
@ -195,9 +201,9 @@ extern "C" {
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (rex)
|
||||
|
||||
qse_rex_t* qse_rex_open (
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t xtn,
|
||||
qse_rex_node_t* code
|
||||
qse_mmgr_t* mmgr, /**< memory manager */
|
||||
qse_size_t xtn, /**< extension size */
|
||||
qse_rex_node_t* code /**< compiled regular expression code */
|
||||
);
|
||||
|
||||
void qse_rex_close (
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sll.h 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: sll.h 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -381,94 +381,63 @@ qse_sll_node_t* qse_sll_gettail (
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_search
|
||||
* NAME
|
||||
* qse_sll_search - find a node
|
||||
/**
|
||||
* The qse_sll_search() function traverses a list to find a node containing
|
||||
* the same value as the the data pointer and length. The traversal begins
|
||||
* from the next node of the positional node. If the positional node is
|
||||
* QSE_NULL, the traversal begins from the head node.
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The qse_sll_search() function traverses a list to find a node containing
|
||||
* the same value as the the data pointer and length. The traversal begins
|
||||
* from the next node of the positional node. If the positional node is
|
||||
* QSE_NULL, the traversal begins from the head node.
|
||||
* Note that no reverse search is provided because a reverse traversal can not be
|
||||
* achieved efficiently.
|
||||
*
|
||||
* RETURN
|
||||
* The pointer to the node found. Otherwise, QSE_NULL.
|
||||
*
|
||||
* NOTES
|
||||
* No reverse search is provided because a reverse traversal can not be
|
||||
* achieved efficiently.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* @return pointer to the node found. QSE_NULL if no match is found
|
||||
*/
|
||||
qse_sll_node_t* qse_sll_search (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_node_t* pos /* a positional node */,
|
||||
const void* dptr /* a data pointer */,
|
||||
qse_size_t dlen /* a data length */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
qse_sll_node_t* pos, /**< positional node */
|
||||
const void* dptr, /**< data pointer */
|
||||
qse_size_t dlen /**< data length */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_insert
|
||||
* NAME
|
||||
* qse_sll_insert - insert data to a new node
|
||||
*
|
||||
* DESCRIPTION
|
||||
* There is performance penalty unless the positional node is neither
|
||||
* the head node nor QSE_NULL. You should consider a different data
|
||||
* structure such as a doubly linked list if you need to insert data
|
||||
* into a random position.
|
||||
*
|
||||
* RETURN
|
||||
* The pointer to a new node on success and QSE_NULL on failure:w
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_insert() function inserts data to the list @a sll.
|
||||
* There is performance penalty unless the positional node is neither
|
||||
* the head node nor QSE_NULL. You should consider a different data
|
||||
* structure such as a doubly linked list if you need to insert data
|
||||
* into a random position.
|
||||
* @return pointer to a new node on success, QSE_NULL on failure
|
||||
*/
|
||||
qse_sll_node_t* qse_sll_insert (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_node_t* pos /* a node before which a new node is inserted */,
|
||||
void* dptr /* the pointer to the data */,
|
||||
qse_size_t dlen /* the length of the data */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
qse_sll_node_t* pos, /**< node before which a new node is inserted */
|
||||
void* dptr, /**< the pointer to the data */
|
||||
qse_size_t dlen /**< the length of the data */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_delete
|
||||
* NAME
|
||||
* qse_sll_delete - delete a node
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The qse_sll_delete() function deletes a node.
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_delete() function deletes a node.
|
||||
*/
|
||||
void qse_sll_delete (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_node_t* pos /* a node to delete */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
qse_sll_node_t* pos /**< node to delete */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_clear
|
||||
* NAME
|
||||
* qse_sll_clear - delete all nodes
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The qse_sll_clear() function empties a singly linked list by deletinng
|
||||
* all the nodes.
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_clear() function empties a singly linked list by deletinng
|
||||
* all the nodes.
|
||||
*/
|
||||
void qse_sll_clear (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
qse_sll_node_t* qse_sll_pushhead (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_t* sll /**< singly linked list */,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
qse_sll_node_t* qse_sll_pushtail (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_t* sll /**< singly linked list */,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
@ -482,12 +451,7 @@ void qse_sll_poptail (
|
||||
qse_sll_t* sll
|
||||
);
|
||||
|
||||
/****f* Common/qse_sll_walk
|
||||
* NAME
|
||||
* qse_sll_walk - traverse s singly linked list
|
||||
*
|
||||
* DESCRIPTION
|
||||
* A singly linked list allows uni-directional in-order traversal.
|
||||
/**
|
||||
* The qse_sll_walk() function traverses a singly linkked list from its
|
||||
* head node down to its tail node as long as the walker function returns
|
||||
* QSE_SLL_WALK_FORWARD. A walker can return QSE_SLL_WALK_STOP to cause
|
||||
@ -497,15 +461,12 @@ void qse_sll_poptail (
|
||||
* parameters: the singly linked list, the visiting node, and the
|
||||
* user-defined data passed as the third parameter in a call to the
|
||||
* qse_sll_walk() function.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_sll_walk (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_walker_t walker /* a user-defined walker function */,
|
||||
void* arg /* the pointer to user-defined data */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
qse_sll_walker_t walker, /**< user-defined walker function */
|
||||
void* ctx /**< the pointer to user-defined data */
|
||||
);
|
||||
/******/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sed.h 296 2009-10-07 12:39:18Z hyunghwan.chung $
|
||||
* $Id: sed.h 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -23,9 +23,6 @@
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/lda.h>
|
||||
#include <qse/cmn/map.h>
|
||||
|
||||
/** @file
|
||||
* A stream editor performs text transformation on a text stream.
|
||||
@ -181,8 +178,8 @@ typedef struct qse_sed_io_arg_t qse_sed_io_arg_t;
|
||||
* qse_sed_exec().
|
||||
*/
|
||||
typedef qse_ssize_t (*qse_sed_io_fun_t) (
|
||||
qse_sed_t* sed,
|
||||
qse_sed_io_cmd_t cmd,
|
||||
qse_sed_t* sed,
|
||||
qse_sed_io_cmd_t cmd,
|
||||
qse_sed_io_arg_t* arg,
|
||||
qse_char_t* data,
|
||||
qse_size_t count
|
||||
@ -339,7 +336,7 @@ void qse_sed_geterror (
|
||||
* location.
|
||||
*/
|
||||
void qse_sed_seterrnum (
|
||||
qse_sed_t* sed, /**< stream editor */
|
||||
qse_sed_t* sed, /**< stream editor */
|
||||
qse_sed_errnum_t errnum, /**< error number */
|
||||
const qse_cstr_t* errarg /**< argument for formatting error message */
|
||||
);
|
||||
@ -349,9 +346,9 @@ void qse_sed_seterrnum (
|
||||
* message for a given error number.
|
||||
*/
|
||||
void qse_sed_seterrmsg (
|
||||
qse_sed_t* sed, /**< stream editor */
|
||||
qse_sed_t* sed, /**< stream editor */
|
||||
qse_sed_errnum_t errnum, /**< error number */
|
||||
const qse_char_t* errmsg, /**< error message */
|
||||
const qse_char_t* errmsg, /**< error message */
|
||||
const qse_sed_loc_t* errloc /**< error location */
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user