added another new hash table implementation based on fr

This commit is contained in:
hyung-hwan 2017-11-30 05:46:42 +00:00
parent 02f3adf134
commit 5db7ddc770
49 changed files with 2113 additions and 647 deletions

View File

@ -380,7 +380,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -619,7 +618,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
@ -645,7 +644,7 @@ dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@ -663,7 +662,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@ -673,7 +672,7 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac

View File

@ -355,7 +355,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -362,7 +362,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -388,7 +388,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -353,7 +353,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -353,7 +353,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

14
qse/configure vendored
View File

@ -821,7 +821,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -924,7 +923,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1177,15 +1175,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1323,7 +1312,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1476,7 +1465,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]

View File

@ -298,7 +298,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -356,7 +356,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -396,7 +396,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -347,7 +347,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -12,6 +12,7 @@ pkginclude_HEADERS = \
fmt.h \
gdl.h \
htb.h \
htl.h \
hton.h \
hwad.h \
ipad.h \

View File

@ -133,13 +133,13 @@ am__can_run_installinfo = \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__pkginclude_HEADERS_DIST = alg.h arr.h chr.h cp949.h cp950.h dll.h \
env.h fma.h fmt.h gdl.h htb.h hton.h hwad.h ipad.h main.h \
map.h mb8.h mbwc.h mem.h oht.h opt.h path.h pma.h rbt.h rex.h \
sll.h slmb.h str.h time.h tmr.h tre.h uni.h uri.h utf8.h xma.h \
Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp ScopedPtr.hpp \
SharedPtr.hpp StrBase.hpp String.hpp Mpool.hpp Association.hpp \
LinkedList.hpp HashList.hpp HashTable.hpp RedBlackTree.hpp \
RedBlackTable.hpp Array.hpp BinaryHeap.hpp
env.h fma.h fmt.h gdl.h htb.h htl.h hton.h hwad.h ipad.h \
main.h map.h mb8.h mbwc.h mem.h oht.h opt.h path.h pma.h rbt.h \
rex.h sll.h slmb.h str.h time.h tmr.h tre.h uni.h uri.h utf8.h \
xma.h Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
ScopedPtr.hpp SharedPtr.hpp StrBase.hpp String.hpp Mpool.hpp \
Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp \
RedBlackTree.hpp RedBlackTable.hpp Array.hpp BinaryHeap.hpp
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@ -361,7 +361,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -373,9 +372,9 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = alg.h arr.h chr.h cp949.h cp950.h dll.h env.h \
fma.h fmt.h gdl.h htb.h hton.h hwad.h ipad.h main.h map.h \
mb8.h mbwc.h mem.h oht.h opt.h path.h pma.h rbt.h rex.h sll.h \
slmb.h str.h time.h tmr.h tre.h uni.h uri.h utf8.h xma.h \
fma.h fmt.h gdl.h htb.h htl.h hton.h hwad.h ipad.h main.h \
map.h mb8.h mbwc.h mem.h oht.h opt.h path.h pma.h rbt.h rex.h \
sll.h slmb.h str.h time.h tmr.h tre.h uni.h uri.h utf8.h xma.h \
$(am__append_1)
all: all-am

302
qse/include/qse/cmn/htl.h Normal file
View File

@ -0,0 +1,302 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_HTL_T_
#define _QSE_HTL_T_
/** \file
* This file provides the hash table for fixed-size data.
*/
#include <qse/types.h>
#include <qse/macros.h>
/**
* The #qse_htl_walk_t type defines walking directions.
*/
enum qse_htl_walk_t
{
QSE_HTL_WALK_STOP = 0,
QSE_HTL_WALK_FORWARD = 1,
};
typedef enum qse_htl_walk_t qse_htl_walk_t;
typedef struct qse_htl_t qse_htl_t;
typedef struct qse_htl_node_t qse_htl_node_t;
/**
* The #qse_htl_hasher_t type defines a data hasher function.
*/
typedef qse_size_t (*qse_htl_hasher_t) (
qse_htl_t* htl,
const void* data
);
/**
* The #qse_htl_comper_t type defines a key comparator that is called when
* the list needs to compare data. The comparator must return 0 if the data
* are the same and a non-zero integer otherwise.
*/
typedef int (*qse_htl_comper_t) (
qse_htl_t* htl, /**< hash table */
const void* data1, /**< data pointer */
const void* data2 /**< data pointer */
);
/**
* The #qse_htl_feeeer_t type defines a data deallocation function.
*/
typedef void (*qse_htl_freeer_t) (
qse_htl_t* htl,
void* data
);
/**
* The #qse_htl_copier_t type defines a data copier function.
*/
typedef void* (*qse_htl_copier_t) (
qse_htl_t* htl,
void* data
);
/**
* The #qse_htl_walker_t function defines a callback function
* for qse_htl_walk().
*/
typedef qse_htl_walk_t (*qse_htl_walker_t) (
qse_htl_t* htl,
void* data,
void* ctx
);
struct qse_htl_node_t
{
struct qse_htl_node_t* next;
qse_uint32_t reversed;
qse_uint32_t key;
void* data;
};
struct qse_htl_t
{
qse_mmgr_t* mmgr;
int keysize; /* default key size */
int num_elements;
int num_buckets; /* power of 2 */
int next_grow;
int mask;
qse_htl_hasher_t hasher;
qse_htl_comper_t comper;
qse_htl_freeer_t freeer;
qse_htl_copier_t copier;
qse_htl_node_t null;
qse_htl_node_t** buckets;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_htl_open() function creates an hash table.
*/
QSE_EXPORT qse_htl_t* qse_htl_open (
qse_mmgr_t* mmgr,
qse_size_t xtnsize,
int scale
);
/**
* The qse_htl_close() function destroys an hash table.
*/
QSE_EXPORT void qse_htl_close (
qse_htl_t* htl /**< hash table */
);
/**
* The qse_htl_open() function initializes an hash table.
*/
QSE_EXPORT int qse_htl_init (
qse_htl_t* htl,
qse_mmgr_t* mmgr,
int scale
);
/**
* The qse_htl_close() function finalizes an hash table.
*/
QSE_EXPORT void qse_htl_fini (
qse_htl_t* htl /**< hash table */
);
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE qse_mmgr_t* qse_htl_getmmgr (qse_htl_t* htl) { return (htl)->mmgr; }
#else
#define qse_htl_getmmgr(htl) ((htl)->mmgr))
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE void* qse_htl_getxtn (qse_htl_t* htl) { return QSE_XTN(htl); }
#else
#define qse_htl_getxtn(htl) (QSE_XTN(htl))
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE int qse_htl_getsize (qse_htl_t* htl) { return htl->num_elements; }
#else
#define qse_htl_getsize(htl) ((htl)->num_elements)
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE qse_htl_hasher_t qse_htl_gethasher (qse_htl_t* htl) { return htl->hasher; }
static QSE_INLINE qse_htl_comper_t qse_htl_getcomper (qse_htl_t* htl) { return htl->comper; }
static QSE_INLINE qse_htl_freeer_t qse_htl_getfreeer (qse_htl_t* htl) { return htl->freeer; }
static QSE_INLINE void qse_htl_sethasher (qse_htl_t* htl, qse_htl_hasher_t _hasher) { htl->hasher = _hasher; }
static QSE_INLINE void qse_htl_setcomper (qse_htl_t* htl, qse_htl_comper_t _comper) { htl->comper = _comper; }
static QSE_INLINE void qse_htl_setfreeer (qse_htl_t* htl, qse_htl_freeer_t _freeer) { htl->freeer = _freeer; }
static QSE_INLINE void qse_htl_setcopier (qse_htl_t* htl, qse_htl_copier_t _copier) { htl->copier = _copier; }
#else
#define qse_htl_gethasher(htl) ((htl)->hasher)
#define qse_htl_getcomper(htl) ((htl)->comper)
#define qse_htl_getfreeer(htl) ((htl)->freeer)
#define qse_htl_sethasher(htl,_hahser) ((htl)->hasher = _hasher)
#define qse_htl_setcomper(htl,_comper) ((htl)->comper = _comper)
#define qse_htl_setfreeer(htl,_freeer) ((htl)->freeer = _freeer)
#define qse_htl_setcopier(htl,_copier) ((htl)->copier = _copier)
#endif
/**
* The qse_htl_search() function searches a hash table to find a
* matching datum. It returns the index to the slot of an internal array
* where the matching datum is found.
* \return slot index if a match if found,
* #QSE_HTL_NIL if no match is found.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_search (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_insert() function inserts a new datum. It fails if it finds
* an existing datum.
* \return slot index where the new datum is inserted on success,
* #QSE_HTL_NIL on failure.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_insert (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_upsert() function inserts a new datum if it finds no matching
* datum or updates an exsting datum if finds a matching datum.
* \return slot index where the datum is inserted or updated.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_upsert (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_update() function updates an existing datum. It fails if it finds
* no existing datum.
* \return slot index where an existing datum is updated on success,
* #QSE_HTL_NIL on failure.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_update (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_ensert() function inserts a new item if one is not found.
* It returns an existing item otherwise.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_ensert (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_delete() function deletes an existing datum. It fails if it finds
* no existing datum.
* \return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_htl_delete (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
QSE_EXPORT void* qse_htl_yank (
qse_htl_t* ht,
void* data
);
/**
* The qse_htl_clear() functions deletes all data items.
*/
QSE_EXPORT void qse_htl_clear (
qse_htl_t* htl /**< hash table */
);
/**
* The qse_htl_walk() function executes the callback function @a walker for
* each valid data item.
*/
QSE_EXPORT void qse_htl_walk (
qse_htl_t* htl, /**< hash table */
qse_htl_walker_t walker, /**< callback function */
void* ctx /**< context */
);
/* ------------------------------------------------------------------------- */
QSE_EXPORT qse_uint32_t qse_genhash_update (const void* data, qse_size_t size, qse_uint32_t hash);
QSE_EXPORT qse_uint32_t qse_genhash (const void *data, qse_size_t size);
/*qse_uint32_t qse_foldhash (qse_uint32_t hash, int bits);*/
QSE_EXPORT qse_uint32_t qse_mbshash (const qse_mchar_t* p);
QSE_EXPORT qse_uint32_t qse_wcshash (const qse_wchar_t* p);
#if defined(QSE_CHAR_IS_WCHAR)
# define qse_strhash(x) qse_wcshash (x)
#else
# define qse_strhash(x) qse_mbshash (x)
#endif
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -345,7 +345,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -345,7 +345,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -345,7 +345,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -46,16 +46,52 @@
#define QSE_RAD_ATTR_TYPE_COMBO_IP 13
#define QSE_RAD_ATTR_TYPE_TLV 14
struct qse_raddic_attr_flags_t
{
unsigned int addport : 1; /* add NAS-Port to IP address */
unsigned int has_tag : 1; /* tagged attribute */
unsigned int do_xlat : 1; /* strvalue is dynamic */
unsigned int unknown_attr : 1; /* not in dictionary */
unsigned int array : 1; /* pack multiples into 1 attr */
unsigned int has_value : 1; /* has a value */
unsigned int has_value_alias : 1; /* has a value alias */
unsigned int has_tlv : 1; /* has sub attributes */
unsigned int is_tlv : 1; /* is a sub attribute */
unsigned int encoded : 1; /* has been put into packet */
qse_int8_t tag; /* tag for tunneled attributes */
qse_uint8_t encrypt; /* encryption method */
};
typedef struct qse_raddic_attr_flags_t qse_raddic_attr_flags_t;
struct qse_raddic_attr_t
{
int attr;
int type;
int vendor;
/* ATTR_FLAGS flags;*/
char name[1];
qse_raddic_attr_flags_t flags;
qse_char_t name[1];
};
typedef struct qse_raddic_attr_t qse_raddic_attr_t;
struct qse_raddic_value_t
{
int attr;
int value;
qse_char_t name[1];
};
typedef struct qse_raddic_value_t qse_raddic_value_t;
struct qse_raddic_vendor_t
{
int vendorpec;
int type;
int length;
int flags;
qse_char_t name[1];
};
typedef struct qse_raddic_vendor_t qse_raddic_vendor_t;
typedef struct qse_raddic_t qse_raddic_t;
#if defined(__cplusplus)

View File

@ -347,7 +347,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -29,25 +29,39 @@
#include <qse/Types.hpp>
#include <qse/Uncopyable.hpp>
#include <qse/cmn/Mmged.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
class AppRoot: QSE::Uncopyable
class AppRoot: Uncopyable, public Types, public Mmged
{
public:
AppRoot (): _root_only (false) {}
AppRoot (Mmgr* mmgr): Mmged(mmgr), _root_only(false) {}
virtual ~AppRoot () {}
int daemonize (bool chdir_to_root = true, int fork_count = 1) QSE_CPP_NOEXCEPT;
static int chroot (const qse_wchar_t* wpath) QSE_CPP_NOEXCEPT;
static int chroot (const qse_mchar_t* mpath) QSE_CPP_NOEXCEPT;
int chroot (const qse_mchar_t* mpath) QSE_CPP_NOEXCEPT;
int chroot (const qse_wchar_t* wpath) QSE_CPP_NOEXCEPT;
#if 0
int switchUser (uid_t uid, gid_t gid, bool permanently) QSE_CPP_NOEXCEPT;
int restoreUser () QSE_CPP_NOEXCEPT;
#endif
protected:
bool _root_only;
#if 0
uid_t saved_uid;
gid_t saved_gid;
gid_t saved_groups[NGROUPS_MAX];
qse_size_t saved_ngroups;
void on_signal () QSE_CPP_NOEXCEPT;
void on_signal () QSE_CPP_NOEXCEPT;
#endif
};
/////////////////////////////////

View File

@ -354,7 +354,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -278,6 +278,18 @@ QSE_EXPORT void qse_log_fini (
qse_log_t* log
);
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE qse_mmgr_t* qse_log_getmmgr (qse_log_t* log) { return (log)->mmgr; }
#else
#define qse_log_getmmgr(log) ((log)->mmgr))
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE void* qse_log_getxtn (qse_log_t* log) { return QSE_XTN(log); }
#else
#define qse_log_getxtn(log) (QSE_XTN(log))
#endif
QSE_EXPORT void qse_log_setident (
qse_log_t* log,
const qse_char_t* ident

View File

@ -345,7 +345,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -390,7 +390,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -546,7 +546,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -43,6 +43,7 @@ libqsecmn_la_SOURCES = \
env.c \
gdl.c \
htb.c \
htl.c \
fma.c \
fmt-intmax.c \
fmt-out.c \

View File

@ -143,8 +143,8 @@ am__DEPENDENCIES_1 =
libqsecmn_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \
alg-sort.c arr.c assert.c chr.c dll.c env.c gdl.c htb.c fma.c \
fmt-intmax.c fmt-out.c hton.c hwad.c ipad.c main.c mb8.c \
alg-sort.c arr.c assert.c chr.c dll.c env.c gdl.c htb.c htl.c \
fma.c fmt-intmax.c fmt-out.c hton.c hwad.c ipad.c main.c mb8.c \
mbwc.c mbwc-str.c mem.c oht.c opt.c path-base.c path-canon.c \
path-core.c path-merge.c pma.c rbt.c rex.c sll.c slmb.c \
str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c str-cpy.c \
@ -159,19 +159,19 @@ am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \
@ENABLE_XCMGRS_TRUE@am__objects_2 = cp949.lo cp950.lo
am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \
alg-sort.lo arr.lo assert.lo chr.lo dll.lo env.lo gdl.lo \
htb.lo fma.lo fmt-intmax.lo fmt-out.lo hton.lo hwad.lo ipad.lo \
main.lo mb8.lo mbwc.lo mbwc-str.lo mem.lo oht.lo opt.lo \
path-base.lo path-canon.lo path-core.lo path-merge.lo pma.lo \
rbt.lo rex.lo sll.lo slmb.lo str-beg.lo str-cat.lo str-chr.lo \
str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo str-dup.lo \
str-dyn.lo str-end.lo str-excl.lo str-fcpy.lo str-fmt.lo \
str-fnmat.lo str-incl.lo str-join.lo str-len.lo str-pac.lo \
str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \
str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \
str-trm.lo str-word.lo time.lo tmr.lo tre.lo tre-ast.lo \
tre-compile.lo tre-match-bt.lo tre-match-pa.lo tre-parse.lo \
tre-stack.lo uri.lo utf8.lo xma.lo $(am__objects_1) \
$(am__objects_2)
htb.lo htl.lo fma.lo fmt-intmax.lo fmt-out.lo hton.lo hwad.lo \
ipad.lo main.lo mb8.lo mbwc.lo mbwc-str.lo mem.lo oht.lo \
opt.lo path-base.lo path-canon.lo path-core.lo path-merge.lo \
pma.lo rbt.lo rex.lo sll.lo slmb.lo str-beg.lo str-cat.lo \
str-chr.lo str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo \
str-dup.lo str-dyn.lo str-end.lo str-excl.lo str-fcpy.lo \
str-fmt.lo str-fnmat.lo str-incl.lo str-join.lo str-len.lo \
str-pac.lo str-pbrk.lo str-put.lo str-rev.lo str-rot.lo \
str-set.lo str-spl.lo str-spn.lo str-str.lo str-subst.lo \
str-tok.lo str-trm.lo str-word.lo time.lo tmr.lo tre.lo \
tre-ast.lo tre-compile.lo tre-match-bt.lo tre-match-pa.lo \
tre-parse.lo tre-stack.lo uri.lo utf8.lo xma.lo \
$(am__objects_1) $(am__objects_2)
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -443,7 +443,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -486,7 +485,7 @@ noinst_HEADERS = \
va_copy.h
libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \
arr.c assert.c chr.c dll.c env.c gdl.c htb.c fma.c \
arr.c assert.c chr.c dll.c env.c gdl.c htb.c htl.c fma.c \
fmt-intmax.c fmt-out.c hton.c hwad.c ipad.c main.c mb8.c \
mbwc.c mbwc-str.c mem.c oht.c opt.c path-base.c path-canon.c \
path-core.c path-merge.c pma.c rbt.c rex.c sll.c slmb.c \
@ -608,6 +607,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt-out.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hton.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwad.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipad.Plo@am__quote@

856
qse/lib/cmn/htl.c Normal file
View File

@ -0,0 +1,856 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* hash.c Non-thread-safe split-ordered hash table.
*
* The weird "reverse" function is based on an idea from
* "Split-Ordered Lists - Lock-free Resizable Hash Tables", with
* modifications so that they're not lock-free. :(
*
* However, the split-order idea allows a fast & easy splitting of the
* hash bucket chain when the hash table is resized. Without it, we'd
* have to check & update the pointers for every node in the buck chain,
* rather than being able to move 1/2 of the entries in the chain with
* one update.
*
* Version: $Id$
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* Copyright 2005,2006 The FreeRADIUS server project
*/
#include <qse/cmn/htl.h>
#include "mem-prv.h"
/*
* A reasonable number of buckets to start off with.
* Should be a power of two.
*/
#define QSE_HTL_NUM_BUCKETS (64)
/*
* perl -e 'foreach $i (0..255) {$r = 0; foreach $j (0 .. 7 ) { if (($i & ( 1<< $j)) != 0) { $r |= (1 << (7 - $j));}} print $r, ", ";if (($i & 7) == 7) {print "\n";}}'
*/
static const qse_uint8_t reversed_byte[256] =
{
0, 128, 64, 192, 32, 160, 96, 224,
16, 144, 80, 208, 48, 176, 112, 240,
8, 136, 72, 200, 40, 168, 104, 232,
24, 152, 88, 216, 56, 184, 120, 248,
4, 132, 68, 196, 36, 164, 100, 228,
20, 148, 84, 212, 52, 180, 116, 244,
12, 140, 76, 204, 44, 172, 108, 236,
28, 156, 92, 220, 60, 188, 124, 252,
2, 130, 66, 194, 34, 162, 98, 226,
18, 146, 82, 210, 50, 178, 114, 242,
10, 138, 74, 202, 42, 170, 106, 234,
26, 154, 90, 218, 58, 186, 122, 250,
6, 134, 70, 198, 38, 166, 102, 230,
22, 150, 86, 214, 54, 182, 118, 246,
14, 142, 78, 206, 46, 174, 110, 238,
30, 158, 94, 222, 62, 190, 126, 254,
1, 129, 65, 193, 33, 161, 97, 225,
17, 145, 81, 209, 49, 177, 113, 241,
9, 137, 73, 201, 41, 169, 105, 233,
25, 153, 89, 217, 57, 185, 121, 249,
5, 133, 69, 197, 37, 165, 101, 229,
21, 149, 85, 213, 53, 181, 117, 245,
13, 141, 77, 205, 45, 173, 109, 237,
29, 157, 93, 221, 61, 189, 125, 253,
3, 131, 67, 195, 35, 163, 99, 227,
19, 147, 83, 211, 51, 179, 115, 243,
11, 139, 75, 203, 43, 171, 107, 235,
27, 155, 91, 219, 59, 187, 123, 251,
7, 135, 71, 199, 39, 167, 103, 231,
23, 151, 87, 215, 55, 183, 119, 247,
15, 143, 79, 207, 47, 175, 111, 239,
31, 159, 95, 223, 63, 191, 127, 255
};
/*
* perl -e 'foreach $i (0..255) {$r = 0;foreach $j (0 .. 7) { $r = $i & (1 << (7 - $j)); last if ($r)} print $i & ~($r), ", ";if (($i & 7) == 7) {print "\n";}}'
*/
static qse_uint8_t parent_byte[256] =
{
0, 0, 0, 1, 0, 1, 2, 3,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127
};
/*
* Reverse a key.
*/
static qse_uint32_t reverse (qse_uint32_t key)
{
return ((reversed_byte[key & 0xff] << 24) |
(reversed_byte[(key >> 8) & 0xff] << 16) |
(reversed_byte[(key >> 16) & 0xff] << 8) |
(reversed_byte[(key >> 24) & 0xff]));
}
/*
* Take the parent by discarding the highest bit that is set.
*/
static qse_uint32_t parent_of (qse_uint32_t key)
{
if (key > 0x00ffffff)
return (key & 0x00ffffff) | (parent_byte[key >> 24] << 24);
if (key > 0x0000ffff)
return (key & 0x0000ffff) | (parent_byte[key >> 16] << 16);
if (key > 0x000000ff)
return (key & 0x000000ff) | (parent_byte[key >> 8] << 8);
return parent_byte[key];
}
static qse_htl_node_t *list_find (qse_htl_t* ht, qse_htl_node_t* head, qse_uint32_t reversed, const void* data)
{
qse_htl_node_t *cur;
for (cur = head; cur != &ht->null; cur = cur->next)
{
if (cur->reversed == reversed)
{
if (ht->comper)
{
int cmp = ht->comper(ht, data, cur->data);
if (cmp > 0) break;
if (cmp < 0) continue;
}
return cur;
}
if (cur->reversed > reversed) break;
}
return QSE_NULL;
}
/*
* Inserts a new entry into the list, in order.
*/
static int list_insert (qse_htl_t* ht, qse_htl_node_t** head, qse_htl_node_t* node)
{
qse_htl_node_t **last, *cur;
last = head;
for (cur = *head; cur != &ht->null; cur = cur->next)
{
if (cur->reversed > node->reversed) break;
last = &(cur->next);
if (cur->reversed == node->reversed)
{
if (ht->comper)
{
int cmp = ht->comper(ht, node->data, cur->data);
if (cmp > 0) break;
if (cmp < 0) continue;
}
return 0;
}
}
node->next = *last;
*last = node;
return 1;
}
/*
* Delete an entry from the list.
*/
static int list_delete (qse_htl_t* ht, qse_htl_node_t** head, qse_htl_node_t* node)
{
qse_htl_node_t **last, *cur;
last = head;
for (cur = *head; cur != &ht->null; cur = cur->next)
{
if (cur == node) break;
last = &(cur->next);
}
*last = node->next;
return 1;
}
/* ------------------------------------------------------------------------- */
static QSE_INLINE_ALWAYS qse_size_t default_hasher (qse_htl_t* htl, const void* data)
{
#if 0
qse_size_t h = 5381;
const qse_byte_t* p = (const qse_byte_t*)data;
const qse_byte_t* bound = p + htl->keysize;
while (p < bound) h = ((h << 5) + h) + *p++;
return h ;
#else
return qse_genhash (data, htl->keysize);
#endif
}
static QSE_INLINE_ALWAYS int default_comper (qse_htl_t* htl, const void* data1, const void* data2)
{
return QSE_MEMCMP(data1, data2, htl->keysize);
}
qse_htl_t* qse_htl_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, int keysize)
{
qse_htl_t* htl;
htl = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_htl_t) + xtnsize);
if (htl == QSE_NULL) return QSE_NULL;
if (qse_htl_init (htl, mmgr, keysize) <= -1)
{
QSE_MMGR_FREE (mmgr, htl);
return QSE_NULL;
}
QSE_MEMSET (htl + 1, 0, xtnsize);
return htl;
}
void qse_htl_close (qse_htl_t* htl)
{
qse_htl_fini (htl);
QSE_MMGR_FREE (htl->mmgr, htl);
}
/*
* Create the table.
*
* Memory usage in bytes is (20/3) * number of entries.
*/
int qse_htl_init (qse_htl_t* ht, qse_mmgr_t* mmgr, int keysize)
{
QSE_MEMSET (ht, 0, sizeof(*ht));
ht->mmgr = mmgr;
ht->keysize = keysize;
ht->hasher = default_hasher;
ht->comper = default_comper;
ht->freeer = QSE_NULL;
ht->copier = QSE_NULL;
ht->num_buckets = QSE_HTL_NUM_BUCKETS;
ht->mask = ht->num_buckets - 1;
/*
* Have a default load factor of 2.5. In practice this
* means that the average load will hit 3 before the
* table grows.
*/
ht->next_grow = (ht->num_buckets << 1) + (ht->num_buckets >> 1);
ht->buckets = QSE_MMGR_ALLOC (ht->mmgr, QSE_SIZEOF(*ht->buckets) * ht->num_buckets);
if (!ht->buckets) return -1;
QSE_MEMSET (ht->buckets, 0, sizeof(*ht->buckets) * ht->num_buckets);
ht->null.reversed = ~0;
ht->null.key = ~0;
ht->null.next = &ht->null;
ht->buckets[0] = &ht->null;
return 0;
}
void qse_htl_fini (qse_htl_t* ht)
{
int i;
qse_htl_node_t *node, *next;
/*
* Walk over the buckets, freeing them all.
*/
for (i = 0; i < ht->num_buckets; i++)
{
if (ht->buckets[i])
{
for (node = ht->buckets[i]; node != &ht->null; node = next)
{
next = node->next;
if (!node->data) continue; /* dummy entry */
if (ht->freeer) ht->freeer (ht, node->data);
QSE_MMGR_FREE (ht->mmgr, node);
}
}
}
QSE_MMGR_FREE (ht->mmgr, ht->buckets);
}
/* ------------------------------------------------------------------------- */
/*
* If the current bucket is uninitialized, initialize it
* by recursively copying information from the parent.
*
* We may have a situation where entry E is a parent to 2 other
* entries E' and E". If we split E into E and E', then the
* nodes meant for E" end up in E or E', either of which is
* wrong. To solve that problem, we walk down the whole chain,
* inserting the elements into the correct place.
*/
static void fixup (qse_htl_t *ht, qse_uint32_t entry)
{
qse_uint32_t parent_entry;
qse_htl_node_t** last, * cur;
qse_uint32_t thiss;
parent_entry = parent_of(entry);
/* parent_entry == entry if and only if entry == 0 */
if (!ht->buckets[parent_entry])
{
fixup(ht, parent_entry);
}
/*
* Keep walking down cur, trying to find entries that
* don't belong here any more. There may be multiple
* ones, so we can't have a naive algorithm...
*/
last = &ht->buckets[parent_entry];
thiss = parent_entry;
for (cur = *last; cur != &ht->null; cur = cur->next)
{
qse_uint32_t real_entry;
real_entry = cur->key & ht->mask;
if (real_entry != thiss)
{ /* ht->buckets[real_entry] == QSE_NULL */
*last = &ht->null;
ht->buckets[real_entry] = cur;
thiss = real_entry;
}
last = &(cur->next);
}
/*
* We may NOT have initialized this bucket, so do it now.
*/
if (!ht->buckets[entry]) ht->buckets[entry] = &ht->null;
}
/*
* This should be a power of two. Changing it to 4 doesn't seem
* to make any difference.
*/
#define GROW_FACTOR (2)
/*
* Grow the hash table.
*/
static void grow (qse_htl_t *ht)
{
qse_htl_node_t **buckets;
buckets = QSE_MMGR_ALLOC (ht->mmgr, QSE_SIZEOF(*buckets) * GROW_FACTOR * ht->num_buckets);
if (!buckets) return;
QSE_MEMCPY (buckets, ht->buckets, QSE_SIZEOF(*buckets) * ht->num_buckets);
QSE_MEMSET (&buckets[ht->num_buckets], 0, QSE_SIZEOF(*buckets) * ht->num_buckets);
QSE_MMGR_FREE (ht->mmgr, ht->buckets);
ht->buckets = buckets;
ht->num_buckets *= GROW_FACTOR;
ht->next_grow *= GROW_FACTOR;
ht->mask = ht->num_buckets - 1;
}
qse_htl_node_t *qse_htl_search (qse_htl_t* ht, void* data)
{
qse_uint32_t key;
qse_uint32_t entry;
qse_uint32_t reversed;
key = ht->hasher(ht, data);
entry = key & ht->mask;
reversed = reverse(key);
if (!ht->buckets[entry]) fixup(ht, entry);
return list_find(ht, ht->buckets[entry], reversed, data);
}
/*
* Insert data.
*/
qse_htl_node_t* qse_htl_insert (qse_htl_t* ht, void* data)
{
qse_uint32_t key;
qse_uint32_t entry;
qse_uint32_t reversed;
qse_htl_node_t *node;
key = ht->hasher(ht, data);
entry = key & ht->mask;
reversed = reverse(key);
if (!ht->buckets[entry]) fixup(ht, entry);
/*
* If we try to do our own memory allocation here, the
* speedup is only ~15% or so, which isn't worth it.
*/
node = QSE_MMGR_ALLOC(ht->mmgr, QSE_SIZEOF(*node));
if (!node) return QSE_NULL;
QSE_MEMSET (node, 0, QSE_SIZEOF(*node));
node->next = &ht->null;
node->reversed = reversed;
node->key = key;
if (ht->copier)
{
node->data = ht->copier (ht, data);
if (!node->data)
{
QSE_MMGR_FREE (ht->mmgr, node);
return QSE_NULL;
}
}
else node->data = data;
/* already in the table, can't insert it */
if (!list_insert(ht, &ht->buckets[entry], node))
{
if (ht->freeer) ht->freeer (ht, node->data);
QSE_MMGR_FREE (ht->mmgr, node);
return QSE_NULL;
}
/*
* Check the load factor, and grow the table if
* necessary.
*/
ht->num_elements++;
if (ht->num_elements >= ht->next_grow) grow(ht);
return node;
}
/*
* Replace old data with new data, OR insert if there is no old.
*/
qse_htl_node_t* qse_htl_upsert (qse_htl_t* ht, void* data)
{
qse_htl_node_t *node;
void* datap;
node = qse_htl_search(ht, data);
if (!node) return qse_htl_insert(ht, data);
if (ht->copier)
{
datap = ht->copier (ht, data);
if (!datap) return QSE_NULL;
}
else datap = data;
if (ht->freeer) ht->freeer(ht, node->data);
node->data = datap;
return node;
}
qse_htl_node_t* qse_htl_update (qse_htl_t* ht, void* data)
{
qse_htl_node_t *node;
void* datap;
node = qse_htl_search(ht, data);
if (!node) return QSE_NULL;
if (ht->copier)
{
datap = ht->copier (ht, data);
if (!datap) return QSE_NULL;
}
else datap = data;
if (ht->freeer) ht->freeer(ht, node->data);
node->data = datap;
return node;
}
qse_htl_node_t* qse_htl_ensert (qse_htl_t* ht, void* data)
{
qse_htl_node_t *node;
node = qse_htl_search(ht, data);
if (!node) return qse_htl_insert(ht, data);
return node;
}
/*
* Yank an entry from the hash table, without freeing the data.
*/
void* qse_htl_yank (qse_htl_t* ht, void* data)
{
qse_uint32_t key;
qse_uint32_t entry;
qse_uint32_t reversed;
void *old;
qse_htl_node_t* node;
if (!ht) return QSE_NULL;
key = ht->hasher(ht, data);
entry = key & ht->mask;
reversed = reverse(key);
if (!ht->buckets[entry]) fixup(ht, entry);
node = list_find(ht, ht->buckets[entry], reversed, data);
if (!node) return QSE_NULL;
list_delete(ht, &ht->buckets[entry], node);
ht->num_elements--;
old = node->data;
QSE_MMGR_FREE (ht->mmgr, node);
return old;
}
/*
* Delete a piece of data from the hash table.
*/
int qse_htl_delete(qse_htl_t *ht, void* data)
{
void* old;
old = qse_htl_yank(ht, data);
if (!old) return -1;
if (ht->freeer) ht->freeer(ht, old);
return 0;
}
/*
* Walk over the nodes, allowing deletes & inserts to happen.
*/
void qse_htl_walk (qse_htl_t *ht, qse_htl_walker_t walker, void *ctx)
{
int i;
for (i = ht->num_buckets - 1; i >= 0; i--)
{
qse_htl_node_t* node, * next;
/*
* Ensure that the current bucket is filled.
*/
if (!ht->buckets[i]) fixup(ht, i);
for (node = ht->buckets[i]; node != &ht->null; node = next)
{
next = node->next;
if (walker(ht, node->data, ctx) == QSE_HTL_WALK_STOP) return;
}
}
}
/* ------------------------------------------------------------------------- */
#if 0
/*
* Find data from a template
*/
void *qse_htl_finddata(qse_htl_t *ht, const void *data)
{
qse_htl_node_t *node;
node = qse_htl_find(ht, data);
if (!node) return NULL;
return node->data;
}
#ifdef TESTING
/*
* Show what the hash table is doing.
*/
int qse_htl_info(qse_htl_t *ht)
{
int i, a, collisions, uninitialized;
int array[256];
if (!ht) return 0;
uninitialized = collisions = 0;
memset(array, 0, sizeof(array));
for (i = 0; i < ht->num_buckets; i++) {
qse_uint32_t key;
int load;
qse_htl_node_t *node, *next;
/*
* If we haven't inserted or looked up an entry
* in a bucket, it's uninitialized.
*/
if (!ht->buckets[i]) {
uninitialized++;
continue;
}
load = 0;
key = ~0;
for (node = ht->buckets[i]; node != &ht->null; node = next) {
if (node->reversed == key) {
collisions++;
} else {
key = node->reversed;
}
next = node->next;
load++;
}
if (load > 255) load = 255;
array[load]++;
}
printf("HASH TABLE %p\tbuckets: %d\t(%d uninitialized)\n", ht,
ht->num_buckets, uninitialized);
printf("\tnum entries %d\thash collisions %d\n",
ht->num_elements, collisions);
a = 0;
for (i = 1; i < 256; i++) {
if (!array[i]) continue;
printf("%d\t%d\n", i, array[i]);
/*
* Since the entries are ordered, the lookup cost
* for any one element in a chain is (on average)
* the cost of walking half of the chain.
*/
if (i > 1) {
a += array[i] * i;
}
}
a /= 2;
a += array[1];
printf("\texpected lookup cost = %d/%d or %f\n\n",
ht->num_elements, a,
(float) ht->num_elements / (float) a);
return 0;
}
#endif
#endif
/* ------------------------------------------------------------------------- */
#define FNV_MAGIC_INIT (0x811c9dc5)
#define FNV_MAGIC_PRIME (0x01000193)
/*
* A fast hash function. For details, see:
*
* http://www.isthe.com/chongo/tech/comp/fnv/
*
* Which also includes public domain source. We've re-written
* it here for our purposes.
*/
/*
* Continue hashing data.
*/
QSE_INLINE qse_uint32_t qse_genhash_update (const void* data, qse_size_t size, qse_uint32_t hash)
{
const qse_uint8_t *p = data;
const qse_uint8_t *q = p + size;
/*
* FNV-1 hash each octet in the buffer
*/
while (p != q)
{
/*
* XOR the 8-bit quantity into the bottom of
* the hash.
*/
hash ^= (qse_uint32_t) (*p++);
/*
* Multiple by 32-bit magic FNV prime, mod 2^32
*/
hash *= FNV_MAGIC_PRIME;
#if 0
/*
* Potential optimization.
*/
hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
#endif
}
return hash;
}
qse_uint32_t qse_genhash (const void *data, qse_size_t size)
{
return qse_genhash_update (data, size, FNV_MAGIC_INIT);
}
/*
* Hash a C string, so we loop over it once.
*/
qse_uint32_t qse_mbshash (const qse_mchar_t* p)
{
qse_uint32_t hash = FNV_MAGIC_INIT;
while (*p)
{
hash ^= (qse_uint32_t) (*p++);
hash *= FNV_MAGIC_PRIME;
}
return hash;
}
qse_uint32_t qse_wcshash (const qse_wchar_t* p)
{
qse_uint32_t hash = FNV_MAGIC_INIT;
while (*p)
{
#if (QSE_SIZEOF_WCHAR_T <= QSE_SIZEOF_UINT32_T)
hash ^= (qse_uint32_t)(*p);
hash *= FNV_MAGIC_PRIME;
#else
hash = qse_genhash_update (*p, QSE_SIZEOF(*p), hash);
#endif
p++;
}
return hash;
}
#if 0
/*
* Return a "folded" hash, where the lower "bits" are the
* hash, and the upper bits are zero.
*
* If you need a non-power-of-two hash, cope.
*/
qse_uint32_t qse_foldhash (qse_uint32_t hash, int bits)
{
int count;
qse_uint32_t result;
if ((bits <= 0) || (bits >= 32)) return hash;
result = hash;
/*
* Never use the same bits twice in an xor.
*/
for (count = 0; count < 32; count += bits)
{
hash >>= bits;
result ^= hash;
}
return result & (((qse_uint32_t) (1 << bits)) - 1);
}
#endif

View File

@ -377,7 +377,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -384,7 +384,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -377,7 +377,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

File diff suppressed because it is too large Load Diff

View File

@ -408,7 +408,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -26,9 +26,8 @@
#include <qse/si/AppRoot.hpp>
#include <qse/si/sinfo.h>
#include <qse/cmn/mem.h>
#include <qse/cmn/mbwc.h>
#include "../cmn/syscall.h"
#include <qse/cmn/mbwc.h>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
@ -42,7 +41,6 @@ int AppRoot::daemonize (bool chdir_to_root, int fork_count) QSE_CPP_NOEXCEPT
{
if (fork_count >= 2)
{
struct sigaction sa;
int n = QSE_FORK();
if (n == -1) return -1;
if (n != 0) QSE_EXIT(0);
@ -103,64 +101,53 @@ int AppRoot::daemonize (bool chdir_to_root, int fork_count) QSE_CPP_NOEXCEPT
return 0;
}
#if 0
int AppRoot::switchUser () QSE_CPP_NOEXCEPT
{
struct passwd* pw;
pw = getpwnam (username);
if (!pw)
if (QSE_SETGID(pw->pw_gid) == -1)
{
}
QSE_SETEGID(gid);
QSE_SETUID(uid);
QSE_SETEUID(uid);
}
#endif
int AppRoot::chroot (const qse_mchar_t* mpath) QSE_CPP_NOEXCEPT
{
int orgdirfd;
orgdirfd = QSE_OPEN (".", O_RDONLY, 0);
if (orgdirfd == -1) return -1;
if (QSE_CHDIR(mpath) == -1) return -1;
if (QSE_CHROOT(mpath) == -1)
{
QSE_FCHDIR (orgdirfd);
QSE_CLOSE (orgdirfd);
return -1;
}
QSE_CLOSE (orgdirfd);
QSE_CHROOT ("/");
return 0;
return QSE_CHROOT (mpath);
}
int AppRoot::chroot (const qse_wchar_t* wpath) QSE_CPP_NOEXCEPT
{
qse_mchar_t* mpath;
mpath = qse_wcstombsdup (wpath, QSE_NULL, QSE_MMGR_GETDFL());
mpath = qse_wcstombsdup (wpath, QSE_NULL, this->getMmgr());
if (!mpath) return -1;
int n = AppRoot::chroot ((const qse_mchar_t*)mpath);
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), mpath);
this->getMmgr()->dispose (mpath);
return n;
}
void AppRoot::on_signal () QSE_CPP_NOEXCEPT
#if 0
int AppRoot::switchPrivilege (int gid, int uid, bool permanently)
{
gid = QSE_GETGID();
uid = QSE_GETUID();
this->saved_egid = QSE_GETEGID();
this->saved_euid = QSE_GETEUID();
this->saved_ngroups = getgroups (QSE_COUNTOF(this->saved_groups), this->saved_groups);
if (this->saved_euid == 0) setgrops (1, gid);
setegid (gid);
//setregid (-1, gid);
if (uid != this->saved_euid)
{
seteuid (uid);
//setreuid (-1, uid);
}
}
int AppRoot::restorePrivilege ()
{
if (QSE_GETEUID() != this->saved_euid) seteuid (this->saved_euid);
if (QSE_GETEGID() != this->saved_egid) setegid (this->saved_egid);
if (this->saved_euid == 0) setgroups (this->saved_ngroups, this->saved_groups);
return 0;
}
#endif
#if 0
int main ()
@ -168,8 +155,10 @@ int main ()
AppRoot app;
app.daemonize();
app.switchUser ("nobody", "nobody");
app.switchUser (10, 20);
app.chuser ();
app.chgroup ();
app.chroot ();
app.catchSignal (SIGINT, xxxxx);
app.catchSignal (SIGTERM, xxx);

View File

@ -423,7 +423,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -377,7 +377,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -356,7 +356,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -298,7 +298,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -300,7 +300,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -356,7 +356,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -480,7 +480,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -15,6 +15,7 @@ bin_PROGRAMS = \
fmt01 \
fmt02 \
htb01 \
htl01 \
ipad01 \
main01 \
main02 \

View File

@ -90,11 +90,12 @@ build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = arr01$(EXEEXT) chr01$(EXEEXT) dll$(EXEEXT) \
env01$(EXEEXT) fma$(EXEEXT) fmt01$(EXEEXT) fmt02$(EXEEXT) \
htb01$(EXEEXT) ipad01$(EXEEXT) main01$(EXEEXT) main02$(EXEEXT) \
mbwc01$(EXEEXT) mbwc02$(EXEEXT) oht$(EXEEXT) path01$(EXEEXT) \
pma$(EXEEXT) rex01$(EXEEXT) rbt01$(EXEEXT) sll$(EXEEXT) \
slmb01$(EXEEXT) str01$(EXEEXT) str02$(EXEEXT) time$(EXEEXT) \
tre01$(EXEEXT) uri01$(EXEEXT) xma$(EXEEXT) $(am__EXEEXT_1)
htb01$(EXEEXT) htl01$(EXEEXT) ipad01$(EXEEXT) main01$(EXEEXT) \
main02$(EXEEXT) mbwc01$(EXEEXT) mbwc02$(EXEEXT) oht$(EXEEXT) \
path01$(EXEEXT) pma$(EXEEXT) rex01$(EXEEXT) rbt01$(EXEEXT) \
sll$(EXEEXT) slmb01$(EXEEXT) str01$(EXEEXT) str02$(EXEEXT) \
time$(EXEEXT) tre01$(EXEEXT) uri01$(EXEEXT) xma$(EXEEXT) \
$(am__EXEEXT_1)
@WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS)
#bin_PROGRAMS += rex02
@ -188,6 +189,10 @@ am__htb02_SOURCES_DIST = htb02.cpp
@ENABLE_CXX_TRUE@am_htb02_OBJECTS = htb02.$(OBJEXT)
htb02_OBJECTS = $(am_htb02_OBJECTS)
@ENABLE_CXX_TRUE@htb02_DEPENDENCIES = $(am__DEPENDENCIES_3)
htl01_SOURCES = htl01.c
htl01_OBJECTS = htl01.$(OBJEXT)
htl01_LDADD = $(LDADD)
htl01_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_ipad01_OBJECTS = ipad01.$(OBJEXT)
ipad01_OBJECTS = $(am_ipad01_OBJECTS)
ipad01_LDADD = $(LDADD)
@ -332,7 +337,7 @@ SOURCES = $(arr01_SOURCES) $(arr02_SOURCES) $(arr03_SOURCES) \
$(bh01_SOURCES) $(bh02_SOURCES) $(chr01_SOURCES) \
$(dll_SOURCES) $(env01_SOURCES) $(fma_SOURCES) \
$(fmt01_SOURCES) $(fmt02_SOURCES) $(hl01_SOURCES) \
$(htb01_SOURCES) $(htb02_SOURCES) $(ipad01_SOURCES) \
$(htb01_SOURCES) $(htb02_SOURCES) htl01.c $(ipad01_SOURCES) \
$(main01_SOURCES) $(main02_SOURCES) $(mbwc01_SOURCES) \
$(mbwc02_SOURCES) $(oht_SOURCES) $(path01_SOURCES) \
$(pma_SOURCES) $(rbt01_SOURCES) $(rbt02_SOURCES) \
@ -345,10 +350,10 @@ DIST_SOURCES = $(arr01_SOURCES) $(am__arr02_SOURCES_DIST) \
$(am__bh02_SOURCES_DIST) $(chr01_SOURCES) $(dll_SOURCES) \
$(env01_SOURCES) $(fma_SOURCES) $(fmt01_SOURCES) \
$(fmt02_SOURCES) $(am__hl01_SOURCES_DIST) $(htb01_SOURCES) \
$(am__htb02_SOURCES_DIST) $(ipad01_SOURCES) $(main01_SOURCES) \
$(main02_SOURCES) $(mbwc01_SOURCES) $(mbwc02_SOURCES) \
$(oht_SOURCES) $(path01_SOURCES) $(pma_SOURCES) \
$(rbt01_SOURCES) $(am__rbt02_SOURCES_DIST) \
$(am__htb02_SOURCES_DIST) htl01.c $(ipad01_SOURCES) \
$(main01_SOURCES) $(main02_SOURCES) $(mbwc01_SOURCES) \
$(mbwc02_SOURCES) $(oht_SOURCES) $(path01_SOURCES) \
$(pma_SOURCES) $(rbt01_SOURCES) $(am__rbt02_SOURCES_DIST) \
$(am__rbt03_SOURCES_DIST) $(rex01_SOURCES) $(sll_SOURCES) \
$(slmb01_SOURCES) $(am__sp01_SOURCES_DIST) \
$(am__sp02_SOURCES_DIST) $(str01_SOURCES) \
@ -550,7 +555,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -754,6 +758,10 @@ htb02$(EXEEXT): $(htb02_OBJECTS) $(htb02_DEPENDENCIES) $(EXTRA_htb02_DEPENDENCIE
@rm -f htb02$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(htb02_OBJECTS) $(htb02_LDADD) $(LIBS)
htl01$(EXEEXT): $(htl01_OBJECTS) $(htl01_DEPENDENCIES) $(EXTRA_htl01_DEPENDENCIES)
@rm -f htl01$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(htl01_OBJECTS) $(htl01_LDADD) $(LIBS)
ipad01$(EXEEXT): $(ipad01_OBJECTS) $(ipad01_DEPENDENCIES) $(EXTRA_ipad01_DEPENDENCIES)
@rm -f ipad01$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(ipad01_OBJECTS) $(ipad01_LDADD) $(LIBS)
@ -862,6 +870,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hl01.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb01.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb02.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htl01.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipad01.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main01.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main02.Po@am__quote@

209
qse/samples/cmn/htl01.c Normal file
View File

@ -0,0 +1,209 @@
#include <qse/cmn/mem.h>
#include <qse/cmn/str.h>
#include <qse/cmn/htl.h>
#include <qse/si/sio.h>
#define R(f) \
do { \
qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \
if (f() == -1) return -1; \
} while (0)
typedef struct item_t item_t;
struct item_t
{
long a;
long x;
long y;
};
static qse_htl_walk_t walk1 (qse_htl_t* htl, void* data, void* ctx)
{
qse_printf (QSE_T("[%ld]\n"), *(long*)data);
return QSE_HTL_WALK_FORWARD;
}
static qse_htl_walk_t walk2 (qse_htl_t* htl, void* data, void* ctx)
{
item_t* item = (item_t*)data;
qse_printf (QSE_T("a [%ld] x [%ld] y [%ld]\n"), item->a, item->x, item->y);
return QSE_HTL_WALK_FORWARD;
}
static qse_size_t hash_item (qse_htl_t* htl, const void* data)
{
item_t* item = (item_t*)data;
//return item->a + 123445;
return qse_genhash (&item->a, QSE_SIZEOF(item->a));
}
static int comp_item (qse_htl_t* htl, const void* data1, const void* data2)
{
return ((item_t*)data1)->a != ((item_t*)data2)->a;
}
static void* copy_item (qse_htl_t* htl, void* data)
{
item_t* x = (item_t*)QSE_MMGR_ALLOC (htl->mmgr, QSE_SIZEOF(item_t));
if (x) *x = *(item_t*)data;
return x;
}
static void free_item (qse_htl_t* htl, void* data)
{
QSE_MMGR_FREE (htl->mmgr, data);
}
static void* copy_long (qse_htl_t* htl, void* data)
{
long* x = (long*)QSE_MMGR_ALLOC (htl->mmgr, QSE_SIZEOF(long));
if (x) *x = *(long*)data;
return x;
}
static void free_long (qse_htl_t* htl, void* data)
{
QSE_MMGR_FREE (htl->mmgr, data);
}
static int test1 ()
{
long x;
qse_htl_t* htl;
qse_htl_node_t* np;
htl = qse_htl_open (QSE_MMGR_GETDFL(), 0, QSE_SIZEOF(x));
if (htl == QSE_NULL)
{
qse_printf (QSE_T("failed to open a table\n"));
return -1;
}
qse_htl_setcopier (htl, copy_long);
qse_htl_setfreeer (htl, free_long);
for (x = 9; x < 20; x++)
{
if (qse_htl_insert(htl, &x))
{
qse_printf (QSE_T("SUCCESS: inserted %ld\n"), x);
}
else
{
qse_printf (QSE_T("FAILURE: failed to insert %ld\n"), x);
}
}
x = 10;
if ((np = qse_htl_search(htl, &x)))
{
qse_printf (QSE_T("SUCCESS: found %ld\n"), *(long*)np->data);
QSE_ASSERT (*(long*)np->data == x);
}
else
{
qse_printf (QSE_T("FAILURE: failed to found %ld\n"), x);
}
x = 10;
if (qse_htl_delete(htl, &x) == 0)
{
qse_printf (QSE_T("SUCCESS: deleted %ld\n"), x);
}
else
{
qse_printf (QSE_T("FAILURE: failed to delete %ld\n"), x);
}
x = 10;
qse_printf (QSE_T("searching for %ld\n"), x);
np = qse_htl_search(htl, &x);
QSE_ASSERT (np == QSE_NULL);
if (np)
{
qse_printf (QSE_T("FAILURE: found something that must not be found - %ld\n"), x);
}
qse_printf (QSE_T("total %lu items\n"), (unsigned long)qse_htl_getsize(htl));
qse_htl_walk (htl, walk1, QSE_NULL);
qse_htl_close (htl);
return 0;
}
static int test2 ()
{
item_t x;
qse_htl_t* htl;
qse_htl_node_t* np;
htl = qse_htl_open (QSE_MMGR_GETDFL(), 0, QSE_SIZEOF(x));
if (htl == QSE_NULL)
{
qse_printf (QSE_T("failed to open a table\n"));
return -1;
}
qse_htl_sethasher (htl, hash_item);
qse_htl_setcomper (htl, comp_item);
qse_htl_setcopier (htl, copy_item);
qse_htl_setfreeer (htl, free_item);
for (x.a = 9; x.a < 20; x.a++)
{
x.x = x.a * 10;
x.y = x.a * 100;
if (qse_htl_insert(htl, &x))
{
qse_printf (QSE_T("SUCCESS: inserted %ld\n"), x.a);
}
else
{
qse_printf (QSE_T("FAILURE: failed to insert %ld\n"), x.a);
}
}
x.a = 10;
if ((np = qse_htl_search(htl, &x)))
{
qse_printf (QSE_T("SUCCESS: found %ld\n"), *(long*)np->data);
QSE_ASSERT (*(long*)np->data == x.a);
}
else
{
qse_printf (QSE_T("FAILURE: failed to found %ld\n"), x.a);
}
x.a = 10;
if (qse_htl_delete(htl, &x) == 0)
{
qse_printf (QSE_T("SUCCESS: deleted %ld\n"), x.a);
}
else
{
qse_printf (QSE_T("FAILURE: failed to delete %ld\n"), x.a);
}
x.a = 10;
qse_printf (QSE_T("searching for %ld\n"), x.a);
np = qse_htl_search(htl, &x);
QSE_ASSERT (np == QSE_NULL);
if (np)
{
qse_printf (QSE_T("FAILURE: found something that must not be found - %ld\n"), x.a);
}
qse_printf (QSE_T("total %lu items\n"), (unsigned long)qse_htl_getsize(htl));
qse_htl_walk (htl, walk2, QSE_NULL);
qse_htl_close (htl);
return 0;
}
int main ()
{
qse_open_stdsios ();
R (test1);
R (test2);
qse_close_stdsios ();
return 0;
}

View File

@ -351,7 +351,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -352,7 +352,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -391,7 +391,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -433,7 +433,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -298,7 +298,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@