added open-addressed hash table
This commit is contained in:
parent
af72767aa5
commit
95e975f514
@ -1,7 +1,7 @@
|
|||||||
pkgincludedir = $(includedir)/qse/cmn
|
pkgincludedir = $(includedir)/qse/cmn
|
||||||
|
|
||||||
pkginclude_HEADERS = \
|
pkginclude_HEADERS = \
|
||||||
mem.h xma.h fma.h chr.h str.h lda.h htb.h rbt.h \
|
mem.h xma.h fma.h chr.h str.h lda.h oht.h htb.h rbt.h \
|
||||||
rex.h sll.h gdl.h dll.h opt.h tio.h \
|
rex.h sll.h gdl.h dll.h opt.h tio.h \
|
||||||
fio.h pio.h sio.h time.h misc.h main.h stdio.h
|
fio.h pio.h sio.h time.h misc.h main.h stdio.h
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ CONFIG_CLEAN_VPATH_FILES =
|
|||||||
SOURCES =
|
SOURCES =
|
||||||
DIST_SOURCES =
|
DIST_SOURCES =
|
||||||
am__pkginclude_HEADERS_DIST = mem.h xma.h fma.h chr.h str.h lda.h \
|
am__pkginclude_HEADERS_DIST = mem.h xma.h fma.h chr.h str.h lda.h \
|
||||||
htb.h rbt.h rex.h sll.h gdl.h dll.h opt.h tio.h fio.h pio.h \
|
oht.h htb.h rbt.h rex.h sll.h gdl.h dll.h opt.h tio.h fio.h \
|
||||||
sio.h time.h misc.h main.h stdio.h Mmgr.hpp StdMmgr.hpp \
|
pio.h sio.h time.h misc.h main.h stdio.h Mmgr.hpp StdMmgr.hpp \
|
||||||
Mmged.hpp
|
Mmged.hpp
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||||
am__vpath_adj = case $$p in \
|
am__vpath_adj = case $$p in \
|
||||||
@ -221,9 +221,9 @@ target_alias = @target_alias@
|
|||||||
top_build_prefix = @top_build_prefix@
|
top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
pkginclude_HEADERS = mem.h xma.h fma.h chr.h str.h lda.h htb.h rbt.h \
|
pkginclude_HEADERS = mem.h xma.h fma.h chr.h str.h lda.h oht.h htb.h \
|
||||||
rex.h sll.h gdl.h dll.h opt.h tio.h fio.h pio.h sio.h time.h \
|
rbt.h rex.h sll.h gdl.h dll.h opt.h tio.h fio.h pio.h sio.h \
|
||||||
misc.h main.h stdio.h $(am__append_1)
|
time.h misc.h main.h stdio.h $(am__append_1)
|
||||||
all: all-am
|
all: all-am
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: htb.h 354 2010-09-03 12:50:08Z hyunghwan.chung $
|
* $Id: htb.h 355 2010-09-07 10:57:43Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -157,7 +157,7 @@ struct qse_htb_t
|
|||||||
qse_htb_sizer_t sizer; /**< bucket capacity recalculator */
|
qse_htb_sizer_t sizer; /**< bucket capacity recalculator */
|
||||||
|
|
||||||
qse_byte_t scale[2]; /**< length scale */
|
qse_byte_t scale[2]; /**< length scale */
|
||||||
qse_byte_t factor; /**< load factor */
|
qse_byte_t factor; /**< load factor in percentage */
|
||||||
qse_byte_t filler0;
|
qse_byte_t filler0;
|
||||||
|
|
||||||
qse_size_t size;
|
qse_size_t size;
|
||||||
|
194
qse/include/qse/cmn/oht.h
Normal file
194
qse/include/qse/cmn/oht.h
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* $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 toht 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
* This file provides the open-addressed hash table for fixed-size data.
|
||||||
|
*/
|
||||||
|
#ifndef _QSE_OHT_T_
|
||||||
|
#define _QSE_OHT_T_
|
||||||
|
|
||||||
|
#include <qse/types.h>
|
||||||
|
#include <qse/macros.h>
|
||||||
|
|
||||||
|
#define QSE_OHT_INVALID_INDEX ((qse_size_t)-1)
|
||||||
|
|
||||||
|
enum qse_oht_mark_t
|
||||||
|
{
|
||||||
|
QSE_OHT_EMPTY = 0,
|
||||||
|
QSE_OHT_OCCUPIED = 1 /*,
|
||||||
|
QSE_OHT_DELETED = 2 */
|
||||||
|
};
|
||||||
|
typedef enum qse_oht_mark_t qse_oht_mark_t;
|
||||||
|
|
||||||
|
enum qse_oht_walk_t
|
||||||
|
{
|
||||||
|
QSE_OHT_WALK_STOP = 0,
|
||||||
|
QSE_OHT_WALK_FORWARD = 1,
|
||||||
|
};
|
||||||
|
typedef enum qse_oht_walk_t qse_oht_walk_t;
|
||||||
|
|
||||||
|
typedef struct qse_oht_t qse_oht_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_oht_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_oht_comper_t) (
|
||||||
|
qse_oht_t* oht, /**< open-addressed hash table */
|
||||||
|
const void* data1, /**< data pointer */
|
||||||
|
const void* data2 /**< data pointer */
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef void (*qse_oht_copier_t) (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
void* dst,
|
||||||
|
const void* src
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef qse_size_t (*qse_oht_hasher_t) (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
const void* data
|
||||||
|
);
|
||||||
|
|
||||||
|
struct qse_oht_t
|
||||||
|
{
|
||||||
|
QSE_DEFINE_COMMON_FIELDS(oht)
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
qse_size_t hard;
|
||||||
|
qse_size_t soft;
|
||||||
|
} capa;
|
||||||
|
qse_size_t size;
|
||||||
|
qse_size_t scale;
|
||||||
|
|
||||||
|
qse_oht_hasher_t hasher;
|
||||||
|
qse_oht_comper_t comper;
|
||||||
|
qse_oht_copier_t copier;
|
||||||
|
|
||||||
|
qse_oht_mark_t* mark;
|
||||||
|
void* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef qse_oht_walk_t (*qse_oht_walker_t) (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
void* data,
|
||||||
|
void* ctx
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QSE_DEFINE_COMMON_FUNCTIONS (oht)
|
||||||
|
|
||||||
|
qse_oht_t* qse_oht_open (
|
||||||
|
qse_mmgr_t* mmgr,
|
||||||
|
qse_size_t xtnsize,
|
||||||
|
qse_size_t scale,
|
||||||
|
qse_size_t capa,
|
||||||
|
qse_size_t limit
|
||||||
|
);
|
||||||
|
|
||||||
|
void qse_oht_close (
|
||||||
|
qse_oht_t* oht
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_oht_t* qse_oht_init (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
qse_mmgr_t* mmgr,
|
||||||
|
qse_size_t scale,
|
||||||
|
qse_size_t capa,
|
||||||
|
qse_size_t limit
|
||||||
|
);
|
||||||
|
|
||||||
|
void qse_oht_fini (
|
||||||
|
qse_oht_t* oht
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_oht_hasher_t qse_oht_gethasher (
|
||||||
|
qse_oht_t* oht
|
||||||
|
);
|
||||||
|
|
||||||
|
void qse_oht_sethasher (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
qse_oht_hasher_t hahser
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_oht_comper_t qse_oht_getcomper (
|
||||||
|
qse_oht_t* oht
|
||||||
|
);
|
||||||
|
|
||||||
|
void qse_oht_setcomper (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
qse_oht_comper_t hahser
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_oht_copier_t qse_oht_getcopier (
|
||||||
|
qse_oht_t* oht
|
||||||
|
);
|
||||||
|
|
||||||
|
void qse_oht_setcopier (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
qse_oht_copier_t hahser
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_size_t qse_oht_search (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
void* data
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_size_t qse_oht_insert (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
const void* data
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_size_t qse_oht_upsert (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
const void* data
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_size_t qse_oht_update (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
const void* data
|
||||||
|
);
|
||||||
|
|
||||||
|
qse_size_t qse_oht_delete (
|
||||||
|
qse_oht_t* oht,
|
||||||
|
const void* data
|
||||||
|
);
|
||||||
|
|
||||||
|
void qse_oht_clear (
|
||||||
|
qse_oht_t* oht
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
void qse_oht_walk (
|
||||||
|
qse_oht_t* oht, /**< open-addressed hash table */
|
||||||
|
qse_oht_walker_t walker, /**< walker function */
|
||||||
|
void* ctx /**< context */
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sll.h 354 2010-09-03 12:50:08Z hyunghwan.chung $
|
* $Id: sll.h 355 2010-09-07 10:57:43Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -123,9 +123,9 @@ struct qse_sll_t
|
|||||||
*/
|
*/
|
||||||
struct qse_sll_node_t
|
struct qse_sll_node_t
|
||||||
{
|
{
|
||||||
void* dptr; /* the pointer to data */
|
qse_sll_node_t* next; /* point to the next node */
|
||||||
qse_size_t dlen; /* the length of data */
|
void* dptr; /* data pointer */
|
||||||
qse_sll_node_t* next; /* the pointer to the next node */
|
qse_size_t dlen; /* data length */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QSE_SLL_COPIER_SIMPLE ((qse_sll_copier_t)1)
|
#define QSE_SLL_COPIER_SIMPLE ((qse_sll_copier_t)1)
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
* ptr2 = qse_xma_alloc (xma, 1000); // allocate a 1K block from the zone
|
* ptr2 = qse_xma_alloc (xma, 1000); // allocate a 1K block from the zone
|
||||||
* ptr1 = qse_xma_realloc (xma, ptr1, 6000); // resize the 5K block to 6K.
|
* ptr1 = qse_xma_realloc (xma, ptr1, 6000); // resize the 5K block to 6K.
|
||||||
*
|
*
|
||||||
* qse_xma_dump (xma, qse_printf); // dump memory blocks
|
* qse_xma_dump (xma, qse_fprintf, QSE_STDOUT); // dump memory blocks
|
||||||
*
|
*
|
||||||
* // the following two lines are not actually needed as the allocator
|
* // the following two lines are not actually needed as the allocator
|
||||||
* // is closed after them.
|
* // is closed after them.
|
||||||
@ -104,6 +104,8 @@ struct qse_xma_t
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef int (*qse_xma_dumper_t) (void* target, const qse_char_t* fmt,...);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -189,8 +191,9 @@ void qse_xma_free (
|
|||||||
* more statistical counters.
|
* more statistical counters.
|
||||||
*/
|
*/
|
||||||
void qse_xma_dump (
|
void qse_xma_dump (
|
||||||
qse_xma_t* xma, /**< memory allocator */
|
qse_xma_t* xma, /**< memory allocator */
|
||||||
int (*printf)(const qse_char_t* fmt,...) /**< output function */
|
qse_xma_dumper_t dumper, /**< output function */
|
||||||
|
void* target /**< first parameter to output function */
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -7,7 +7,7 @@ libqsecmn_la_SOURCES = \
|
|||||||
syscall.h mem.h \
|
syscall.h mem.h \
|
||||||
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
|
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
|
||||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||||
lda.c htb.c rbt.c sll.c gdl.c dll.c opt.c \
|
lda.c oht.c htb.c rbt.c sll.c gdl.c dll.c opt.c \
|
||||||
tio.c tio_get.c tio_put.c \
|
tio.c tio_get.c tio_put.c \
|
||||||
fio.c pio.c sio.c \
|
fio.c pio.c sio.c \
|
||||||
time.c \
|
time.c \
|
||||||
|
@ -75,9 +75,9 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
|
|||||||
libqsecmn_la_DEPENDENCIES =
|
libqsecmn_la_DEPENDENCIES =
|
||||||
am_libqsecmn_la_OBJECTS = mem.lo xma.lo fma.lo chr.lo chr_cnv.lo \
|
am_libqsecmn_la_OBJECTS = mem.lo xma.lo fma.lo chr.lo chr_cnv.lo \
|
||||||
rex.lo str_bas.lo str_cnv.lo str_dyn.lo str_utl.lo lda.lo \
|
rex.lo str_bas.lo str_cnv.lo str_dyn.lo str_utl.lo lda.lo \
|
||||||
htb.lo rbt.lo sll.lo gdl.lo dll.lo opt.lo tio.lo tio_get.lo \
|
oht.lo htb.lo rbt.lo sll.lo gdl.lo dll.lo opt.lo tio.lo \
|
||||||
tio_put.lo fio.lo pio.lo sio.lo time.lo misc.lo assert.lo \
|
tio_get.lo tio_put.lo fio.lo pio.lo sio.lo time.lo misc.lo \
|
||||||
main.lo stdio.lo
|
assert.lo main.lo stdio.lo
|
||||||
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
||||||
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||||
@ -264,7 +264,7 @@ libqsecmn_la_SOURCES = \
|
|||||||
syscall.h mem.h \
|
syscall.h mem.h \
|
||||||
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
|
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
|
||||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||||
lda.c htb.c rbt.c sll.c gdl.c dll.c opt.c \
|
lda.c oht.c htb.c rbt.c sll.c gdl.c dll.c opt.c \
|
||||||
tio.c tio_get.c tio_put.c \
|
tio.c tio_get.c tio_put.c \
|
||||||
fio.c pio.c sio.c \
|
fio.c pio.c sio.c \
|
||||||
time.c \
|
time.c \
|
||||||
@ -369,6 +369,7 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Plo@am__quote@
|
||||||
|
322
qse/lib/cmn/oht.c
Normal file
322
qse/lib/cmn/oht.c
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
#include <qse/cmn/oht.h>
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
#define DATA_PTR(oht,index) \
|
||||||
|
((void*)(((qse_byte_t*)(oht)->data) + ((index) * (oht)->scale)))
|
||||||
|
|
||||||
|
QSE_IMPLEMENT_COMMON_FUNCTIONS (oht)
|
||||||
|
|
||||||
|
static QSE_INLINE_ALWAYS qse_size_t default_hasher (
|
||||||
|
qse_oht_t* oht, const void* data)
|
||||||
|
{
|
||||||
|
size_t h = 5381;
|
||||||
|
const qse_byte_t* p = (const qse_byte_t*)data;
|
||||||
|
const qse_byte_t* bound = p + oht->scale;
|
||||||
|
while (p < bound) h = ((h << 5) + h) + *p++;
|
||||||
|
return h ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSE_INLINE_ALWAYS int default_comper (
|
||||||
|
qse_oht_t* oht, const void* data1, const void* data2)
|
||||||
|
{
|
||||||
|
return QSE_MEMCMP(data1, data2, oht->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSE_INLINE_ALWAYS void default_copier (
|
||||||
|
qse_oht_t* oht, void* dst, const void* src)
|
||||||
|
{
|
||||||
|
QSE_MEMCPY (dst, src, oht->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HASH_DATA(oht,data) \
|
||||||
|
((oht)->hasher? (oht)->hasher ((oht), (data)): \
|
||||||
|
default_hasher (oht, data))
|
||||||
|
|
||||||
|
#define COMP_DATA(oht,d1,d2) \
|
||||||
|
((oht)->comper? (oht)->comper ((oht), (d1), (d2)): \
|
||||||
|
QSE_MEMCMP ((d1), (d2), (oht)->scale))
|
||||||
|
|
||||||
|
#define COPY_DATA(oht,dst,src) \
|
||||||
|
QSE_BLOCK ( \
|
||||||
|
if ((oht)->copier) (oht)->copier ((oht), (dst), (src)); \
|
||||||
|
else QSE_MEMCPY ((dst), (src), (oht)->scale); \
|
||||||
|
)
|
||||||
|
|
||||||
|
qse_oht_t* qse_oht_open (
|
||||||
|
qse_mmgr_t* mmgr, qse_size_t xtnsize,
|
||||||
|
qse_size_t scale, qse_size_t capa, qse_size_t limit)
|
||||||
|
{
|
||||||
|
qse_oht_t* oht;
|
||||||
|
|
||||||
|
if (mmgr == QSE_NULL)
|
||||||
|
{
|
||||||
|
mmgr = QSE_MMGR_GETDFL();
|
||||||
|
|
||||||
|
QSE_ASSERTX (mmgr != QSE_NULL,
|
||||||
|
"Set the memory manager with QSE_MMGR_SETDFL()");
|
||||||
|
|
||||||
|
if (mmgr == QSE_NULL) return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
oht = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_oht_t) + xtnsize);
|
||||||
|
if (oht == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
|
if (qse_oht_init (oht, mmgr, scale, capa, limit) == QSE_NULL)
|
||||||
|
{
|
||||||
|
QSE_MMGR_FREE (mmgr, oht);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return oht;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_oht_close (qse_oht_t* oht)
|
||||||
|
{
|
||||||
|
qse_oht_fini (oht);
|
||||||
|
QSE_MMGR_FREE (oht->mmgr, oht);
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_oht_t* qse_oht_init (
|
||||||
|
qse_oht_t* oht, qse_mmgr_t* mmgr,
|
||||||
|
qse_size_t scale, qse_size_t capa, qse_size_t limit)
|
||||||
|
{
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
if (scale <= 0) scale = 1;
|
||||||
|
if (capa >= QSE_OHT_INVALID_INDEX - 1) capa = QSE_OHT_INVALID_INDEX - 1;
|
||||||
|
if (limit > capa || limit <= 0) limit = capa;
|
||||||
|
|
||||||
|
QSE_MEMSET (oht, 0, QSE_SIZEOF(*oht));
|
||||||
|
|
||||||
|
oht->mmgr = mmgr;
|
||||||
|
oht->capa.hard = capa;
|
||||||
|
oht->capa.soft = limit;
|
||||||
|
oht->scale = scale;
|
||||||
|
oht->size = 0;
|
||||||
|
|
||||||
|
/*oht->hasher = default_hasher;
|
||||||
|
oht->comper = default_comper;
|
||||||
|
oht->copier = default_copier;*/
|
||||||
|
|
||||||
|
oht->mark = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_oht_mark_t) * capa);
|
||||||
|
if (!oht->mark) return QSE_NULL;
|
||||||
|
|
||||||
|
oht->data = QSE_MMGR_ALLOC (mmgr, scale * capa);
|
||||||
|
if (!oht->data)
|
||||||
|
{
|
||||||
|
QSE_MMGR_FREE (mmgr, oht->mark);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < capa; i++) oht->mark[i] = QSE_OHT_EMPTY;
|
||||||
|
return oht;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_oht_fini (qse_oht_t* oht)
|
||||||
|
{
|
||||||
|
QSE_MMGR_FREE (oht->mmgr, oht->mark);
|
||||||
|
QSE_MMGR_FREE (oht->mmgr, oht->data);
|
||||||
|
oht->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_oht_hasher_t qse_oht_gethasher (qse_oht_t* oht)
|
||||||
|
{
|
||||||
|
return oht->hasher? oht->hasher: default_hasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_oht_sethasher (qse_oht_t* oht, qse_oht_hasher_t hasher)
|
||||||
|
{
|
||||||
|
oht->hasher = hasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_oht_comper_t qse_oht_getcomper (qse_oht_t* oht)
|
||||||
|
{
|
||||||
|
return oht->comper? oht->comper: default_comper;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_oht_setcomper (qse_oht_t* oht, qse_oht_comper_t comper)
|
||||||
|
{
|
||||||
|
oht->comper = comper;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_oht_copier_t qse_oht_getcopier (qse_oht_t* oht)
|
||||||
|
{
|
||||||
|
return oht->copier? oht->copier: default_copier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_oht_setcopier (qse_oht_t* oht, qse_oht_copier_t copier)
|
||||||
|
{
|
||||||
|
oht->copier = copier;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSE_INLINE qse_size_t search (
|
||||||
|
qse_oht_t* oht, const void* data, qse_size_t hash)
|
||||||
|
{
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < oht->capa.hard; i++)
|
||||||
|
{
|
||||||
|
qse_size_t index = (hash + i) % oht->capa.hard;
|
||||||
|
if (oht->mark[index] == QSE_OHT_EMPTY) break;
|
||||||
|
if (oht->mark[index] == QSE_OHT_OCCUPIED)
|
||||||
|
{
|
||||||
|
if (COMP_DATA (oht, data, DATA_PTR(oht,index)) == 0)
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_OHT_INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t qse_oht_search (qse_oht_t* oht, void* data)
|
||||||
|
{
|
||||||
|
qse_size_t i = search (oht, data, HASH_DATA(oht,data));
|
||||||
|
if (i != QSE_OHT_INVALID_INDEX && data)
|
||||||
|
COPY_DATA (oht, data, DATA_PTR(oht,i));
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t qse_oht_update (qse_oht_t* oht, const void* data)
|
||||||
|
{
|
||||||
|
qse_size_t i = search (oht, data, HASH_DATA(oht,data));
|
||||||
|
if (i != QSE_OHT_INVALID_INDEX)
|
||||||
|
COPY_DATA (oht, DATA_PTR(oht,i), data);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t qse_oht_upsert (qse_oht_t* oht, const void* data)
|
||||||
|
{
|
||||||
|
qse_size_t i, hash = HASH_DATA (oht, data);
|
||||||
|
|
||||||
|
/* find the existing item */
|
||||||
|
i = search (oht, data, hash);
|
||||||
|
if (i != QSE_OHT_INVALID_INDEX)
|
||||||
|
{
|
||||||
|
COPY_DATA (oht, DATA_PTR(oht,i), data);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if there is a free slot to insert data into */
|
||||||
|
if (oht->size >= oht->capa.soft) return QSE_OHT_INVALID_INDEX;
|
||||||
|
|
||||||
|
/* get the unoccupied slot and insert the data into it.
|
||||||
|
* iterate at most 'the number of items (oht->size)' times + 1. */
|
||||||
|
for (i = 0; i <= oht->size; i++)
|
||||||
|
{
|
||||||
|
qse_size_t index = (hash + i) % oht->capa.hard;
|
||||||
|
if (oht->mark[index] != QSE_OHT_OCCUPIED)
|
||||||
|
{
|
||||||
|
oht->mark[index] = QSE_OHT_OCCUPIED;
|
||||||
|
COPY_DATA (oht, DATA_PTR(oht,index), data);
|
||||||
|
oht->size++;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_OHT_INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t qse_oht_insert (qse_oht_t* oht, const void* data)
|
||||||
|
{
|
||||||
|
qse_size_t i, hash;
|
||||||
|
|
||||||
|
/* check if there is a free slot to insert data into */
|
||||||
|
if (oht->size >= oht->capa.soft) return QSE_OHT_INVALID_INDEX;
|
||||||
|
|
||||||
|
hash = HASH_DATA (oht, data);
|
||||||
|
|
||||||
|
/* check if the item already exits */
|
||||||
|
i = search (oht, data, hash);
|
||||||
|
if (i != QSE_OHT_INVALID_INDEX) return QSE_OHT_INVALID_INDEX;
|
||||||
|
|
||||||
|
/* get the unoccupied slot and insert the data into it.
|
||||||
|
* iterate at most 'the number of items (oht->size)' times + 1. */
|
||||||
|
for (i = 0; i <= oht->size; i++)
|
||||||
|
{
|
||||||
|
qse_size_t index = (hash + i) % oht->capa.hard;
|
||||||
|
if (oht->mark[index] != QSE_OHT_OCCUPIED)
|
||||||
|
{
|
||||||
|
oht->mark[index] = QSE_OHT_OCCUPIED;
|
||||||
|
COPY_DATA (oht, DATA_PTR(oht,index), data);
|
||||||
|
oht->size++;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_OHT_INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t qse_oht_delete (qse_oht_t* oht, const void* data)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
qse_size_t index;
|
||||||
|
|
||||||
|
if (oht->size <= 0) return QSE_OHT_INVALID_INDEX;
|
||||||
|
|
||||||
|
index = search (oht, data, HASH_DATA(oht,data));
|
||||||
|
if (index != QSE_OHT_INVALID_INDEX)
|
||||||
|
{
|
||||||
|
oht->mark[index] = QSE_OHT_DELETED;
|
||||||
|
oht->size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
qse_size_t index, i, x, y, z;
|
||||||
|
|
||||||
|
/* check if the oht is empty. if so, do nothing */
|
||||||
|
if (oht->size <= 0) return QSE_OHT_INVALID_INDEX;
|
||||||
|
|
||||||
|
/* check if the item exists. otherwise, do nothing. */
|
||||||
|
index = search (oht, data, HASH_DATA(oht,data));
|
||||||
|
if (index == QSE_OHT_INVALID_INDEX) return QSE_OHT_INVALID_INDEX;
|
||||||
|
|
||||||
|
/* compact the cluster */
|
||||||
|
for (i = 0, x = index, y = index; i < oht->size; i++)
|
||||||
|
{
|
||||||
|
y = (y + 1) % oht->capa.hard;
|
||||||
|
|
||||||
|
/* done if the slot at the current hash index is empty */
|
||||||
|
if (oht->mark[y] == QSE_OHT_EMPTY) break;
|
||||||
|
|
||||||
|
/* get the natural hash index for the data in the slot at
|
||||||
|
* the current hash index */
|
||||||
|
z = HASH_DATA(oht,DATA_PTR(oht,y)) % oht->capa.hard;
|
||||||
|
|
||||||
|
/* move an element if necesary */
|
||||||
|
if ((y > x && (z <= x || z > y)) ||
|
||||||
|
(y < x && (z <= x && z > y)))
|
||||||
|
{
|
||||||
|
COPY_DATA (oht, DATA_PTR(oht,x), DATA_PTR(oht,y));
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oht->mark[x] = QSE_OHT_EMPTY;
|
||||||
|
oht->size--;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_oht_clear (qse_oht_t* oht)
|
||||||
|
{
|
||||||
|
qse_size_t i;
|
||||||
|
for (i = 0; i < oht->capa.hard; i++)
|
||||||
|
oht->mark[i] = QSE_OHT_EMPTY;
|
||||||
|
oht->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_oht_walk (qse_oht_t* oht, qse_oht_walker_t walker, void* ctx)
|
||||||
|
{
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < oht->capa.hard; i++)
|
||||||
|
{
|
||||||
|
if (oht->mark[i] == QSE_OHT_OCCUPIED)
|
||||||
|
{
|
||||||
|
if (walker (oht, DATA_PTR(oht,i), ctx) == QSE_OHT_WALK_STOP)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -702,7 +702,7 @@ void qse_xma_free (qse_xma_t* xma, void* b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qse_xma_dump (qse_xma_t* xma, int (*printf)(const qse_char_t* fmt,...))
|
void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* target)
|
||||||
{
|
{
|
||||||
qse_xma_blk_t* tmp;
|
qse_xma_blk_t* tmp;
|
||||||
unsigned long long fsum, asum;
|
unsigned long long fsum, asum;
|
||||||
@ -710,19 +710,19 @@ void qse_xma_dump (qse_xma_t* xma, int (*printf)(const qse_char_t* fmt,...))
|
|||||||
unsigned long long isum;
|
unsigned long long isum;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printf (QSE_T("<XMA DUMP>\n"));
|
dumper (target, QSE_T("<XMA DUMP>\n"));
|
||||||
#ifdef QSE_XMA_ENABLE_STAT
|
#ifdef QSE_XMA_ENABLE_STAT
|
||||||
printf (QSE_T("== statistics ==\n"));
|
dumper (target, QSE_T("== statistics ==\n"));
|
||||||
printf (QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total);
|
dumper (target, QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total);
|
||||||
printf (QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc);
|
dumper (target, QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc);
|
||||||
printf (QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail);
|
dumper (target, QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printf (QSE_T("== blocks ==\n"));
|
dumper (target, QSE_T("== blocks ==\n"));
|
||||||
printf (QSE_T(" size avail address\n"));
|
dumper (target, QSE_T(" size avail address\n"));
|
||||||
for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next)
|
for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next)
|
||||||
{
|
{
|
||||||
printf (QSE_T(" %-18llu %-5d %p\n"), (unsigned long long)tmp->size, tmp->avail, tmp);
|
dumper (target, QSE_T(" %-18llu %-5d %p\n"), (unsigned long long)tmp->size, tmp->avail, tmp);
|
||||||
if (tmp->avail) fsum += tmp->size;
|
if (tmp->avail) fsum += tmp->size;
|
||||||
else asum += tmp->size;
|
else asum += tmp->size;
|
||||||
}
|
}
|
||||||
@ -731,12 +731,12 @@ void qse_xma_dump (qse_xma_t* xma, int (*printf)(const qse_char_t* fmt,...))
|
|||||||
isum = (xma->stat.nfree + xma->stat.nused) * HDRSIZE;
|
isum = (xma->stat.nfree + xma->stat.nused) * HDRSIZE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printf (QSE_T("---------------------------------------\n"));
|
dumper (target, QSE_T("---------------------------------------\n"));
|
||||||
printf (QSE_T("Allocated blocks: %18llu bytes\n"), asum);
|
dumper (target, QSE_T("Allocated blocks: %18llu bytes\n"), asum);
|
||||||
printf (QSE_T("Available blocks: %18llu bytes\n"), fsum);
|
dumper (target, QSE_T("Available blocks: %18llu bytes\n"), fsum);
|
||||||
#ifdef QSE_XMA_ENABLE_STAT
|
#ifdef QSE_XMA_ENABLE_STAT
|
||||||
printf (QSE_T("Internal use : %18llu bytes\n"), isum);
|
dumper (target, QSE_T("Internal use : %18llu bytes\n"), isum);
|
||||||
printf (QSE_T("Total : %18llu bytes\n"), asum + fsum + isum);
|
dumper (target, QSE_T("Total : %18llu bytes\n"), asum + fsum + isum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QSE_ASSERT (asum == xma->stat.alloc);
|
QSE_ASSERT (asum == xma->stat.alloc);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
|
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
|
||||||
|
|
||||||
bin_PROGRAMS = xma fma chr str sll dll lda htb rbt fio pio sio time main rex01
|
bin_PROGRAMS = xma fma chr str sll dll lda oht htb rbt fio pio sio time main rex01
|
||||||
|
|
||||||
LDFLAGS = -L../../lib/cmn
|
LDFLAGS = -L../../lib/cmn
|
||||||
LDADD = -lqsecmn
|
LDADD = -lqsecmn
|
||||||
@ -12,6 +12,7 @@ str_SOURCES = str.c
|
|||||||
sll_SOURCES = sll.c
|
sll_SOURCES = sll.c
|
||||||
dll_SOURCES = dll.c
|
dll_SOURCES = dll.c
|
||||||
lda_SOURCES = lda.c
|
lda_SOURCES = lda.c
|
||||||
|
oht_SOURCES = oht.c
|
||||||
htb_SOURCES = htb.c
|
htb_SOURCES = htb.c
|
||||||
rbt_SOURCES = rbt.c
|
rbt_SOURCES = rbt.c
|
||||||
fio_SOURCES = fio.c
|
fio_SOURCES = fio.c
|
||||||
|
@ -35,9 +35,9 @@ POST_UNINSTALL = :
|
|||||||
build_triplet = @build@
|
build_triplet = @build@
|
||||||
host_triplet = @host@
|
host_triplet = @host@
|
||||||
bin_PROGRAMS = xma$(EXEEXT) fma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) \
|
bin_PROGRAMS = xma$(EXEEXT) fma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) \
|
||||||
sll$(EXEEXT) dll$(EXEEXT) lda$(EXEEXT) htb$(EXEEXT) \
|
sll$(EXEEXT) dll$(EXEEXT) lda$(EXEEXT) oht$(EXEEXT) \
|
||||||
rbt$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) sio$(EXEEXT) \
|
htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) \
|
||||||
time$(EXEEXT) main$(EXEEXT) rex01$(EXEEXT)
|
sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) rex01$(EXEEXT)
|
||||||
subdir = samples/cmn
|
subdir = samples/cmn
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
@ -82,6 +82,10 @@ am_main_OBJECTS = main.$(OBJEXT)
|
|||||||
main_OBJECTS = $(am_main_OBJECTS)
|
main_OBJECTS = $(am_main_OBJECTS)
|
||||||
main_LDADD = $(LDADD)
|
main_LDADD = $(LDADD)
|
||||||
main_DEPENDENCIES =
|
main_DEPENDENCIES =
|
||||||
|
am_oht_OBJECTS = oht.$(OBJEXT)
|
||||||
|
oht_OBJECTS = $(am_oht_OBJECTS)
|
||||||
|
oht_LDADD = $(LDADD)
|
||||||
|
oht_DEPENDENCIES =
|
||||||
am_pio_OBJECTS = pio.$(OBJEXT)
|
am_pio_OBJECTS = pio.$(OBJEXT)
|
||||||
pio_OBJECTS = $(am_pio_OBJECTS)
|
pio_OBJECTS = $(am_pio_OBJECTS)
|
||||||
pio_LDADD = $(LDADD)
|
pio_LDADD = $(LDADD)
|
||||||
@ -128,13 +132,14 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
|||||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||||
$(LDFLAGS) -o $@
|
$(LDFLAGS) -o $@
|
||||||
SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(fio_SOURCES) $(fma_SOURCES) \
|
SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(fio_SOURCES) $(fma_SOURCES) \
|
||||||
$(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) $(pio_SOURCES) \
|
$(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) $(oht_SOURCES) \
|
||||||
$(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \
|
|
||||||
$(str_SOURCES) $(time_SOURCES) $(xma_SOURCES)
|
|
||||||
DIST_SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(fio_SOURCES) \
|
|
||||||
$(fma_SOURCES) $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) \
|
|
||||||
$(pio_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) \
|
$(pio_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) \
|
||||||
$(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) $(xma_SOURCES)
|
$(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) $(xma_SOURCES)
|
||||||
|
DIST_SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(fio_SOURCES) \
|
||||||
|
$(fma_SOURCES) $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) \
|
||||||
|
$(oht_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) \
|
||||||
|
$(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) \
|
||||||
|
$(xma_SOURCES)
|
||||||
ETAGS = etags
|
ETAGS = etags
|
||||||
CTAGS = ctags
|
CTAGS = ctags
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
@ -286,6 +291,7 @@ str_SOURCES = str.c
|
|||||||
sll_SOURCES = sll.c
|
sll_SOURCES = sll.c
|
||||||
dll_SOURCES = dll.c
|
dll_SOURCES = dll.c
|
||||||
lda_SOURCES = lda.c
|
lda_SOURCES = lda.c
|
||||||
|
oht_SOURCES = oht.c
|
||||||
htb_SOURCES = htb.c
|
htb_SOURCES = htb.c
|
||||||
rbt_SOURCES = rbt.c
|
rbt_SOURCES = rbt.c
|
||||||
fio_SOURCES = fio.c
|
fio_SOURCES = fio.c
|
||||||
@ -392,6 +398,9 @@ lda$(EXEEXT): $(lda_OBJECTS) $(lda_DEPENDENCIES)
|
|||||||
main$(EXEEXT): $(main_OBJECTS) $(main_DEPENDENCIES)
|
main$(EXEEXT): $(main_OBJECTS) $(main_DEPENDENCIES)
|
||||||
@rm -f main$(EXEEXT)
|
@rm -f main$(EXEEXT)
|
||||||
$(LINK) $(main_OBJECTS) $(main_LDADD) $(LIBS)
|
$(LINK) $(main_OBJECTS) $(main_LDADD) $(LIBS)
|
||||||
|
oht$(EXEEXT): $(oht_OBJECTS) $(oht_DEPENDENCIES)
|
||||||
|
@rm -f oht$(EXEEXT)
|
||||||
|
$(LINK) $(oht_OBJECTS) $(oht_LDADD) $(LIBS)
|
||||||
pio$(EXEEXT): $(pio_OBJECTS) $(pio_DEPENDENCIES)
|
pio$(EXEEXT): $(pio_OBJECTS) $(pio_DEPENDENCIES)
|
||||||
@rm -f pio$(EXEEXT)
|
@rm -f pio$(EXEEXT)
|
||||||
$(LINK) $(pio_OBJECTS) $(pio_LDADD) $(LIBS)
|
$(LINK) $(pio_OBJECTS) $(pio_LDADD) $(LIBS)
|
||||||
@ -430,6 +439,7 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex01.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex01.Po@am__quote@
|
||||||
|
127
qse/samples/cmn/oht.c
Normal file
127
qse/samples/cmn/oht.c
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include <qse/cmn/mem.h>
|
||||||
|
#include <qse/cmn/str.h>
|
||||||
|
#include <qse/cmn/oht.h>
|
||||||
|
#include <qse/cmn/stdio.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_oht_walk_t walk1 (qse_oht_t* oht, void* data, void* ctx)
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("[%ld]\n"), *(long*)data);
|
||||||
|
return QSE_OHT_WALK_FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qse_oht_walk_t walk2 (qse_oht_t* oht, 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_OHT_WALK_FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qse_size_t hash (qse_oht_t* oht, void* data)
|
||||||
|
{
|
||||||
|
item_t* item = (item_t*)data;
|
||||||
|
return item->a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int comp (qse_oht_t* oht, void* data1, void* data2)
|
||||||
|
{
|
||||||
|
return ((item_t*)data1)->a != ((item_t*)data2)->a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test1 ()
|
||||||
|
{
|
||||||
|
long x;
|
||||||
|
qse_oht_t* oht;
|
||||||
|
|
||||||
|
oht = qse_oht_open (QSE_NULL, 0, QSE_SIZEOF(x), 10, 5);
|
||||||
|
if (oht == QSE_NULL)
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("failed to open a table\n"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 9; x < 20; x++)
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("inserting %ld => %lu\n"),
|
||||||
|
x, (unsigned long)qse_oht_insert (oht, &x));
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 10;
|
||||||
|
qse_printf (QSE_T("searching for %ld => %lu\n"),
|
||||||
|
x, (unsigned long)qse_oht_search (oht, &x));
|
||||||
|
|
||||||
|
x = 10;
|
||||||
|
qse_printf (QSE_T("deleting %ld => %lu\n"),
|
||||||
|
x, (unsigned long)qse_oht_delete (oht, &x));
|
||||||
|
|
||||||
|
x = 10;
|
||||||
|
qse_printf (QSE_T("searching for %ld => %lu\n"),
|
||||||
|
x, (unsigned long)qse_oht_search (oht, &x));
|
||||||
|
|
||||||
|
|
||||||
|
qse_oht_walk (oht, walk1, QSE_NULL);
|
||||||
|
qse_oht_close (oht);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test2 ()
|
||||||
|
{
|
||||||
|
item_t x;
|
||||||
|
qse_oht_t* oht;
|
||||||
|
|
||||||
|
oht = qse_oht_open (QSE_NULL, 0, QSE_SIZEOF(x), 10, 5);
|
||||||
|
if (oht == QSE_NULL)
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("failed to open a table\n"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_oht_sethasher (oht, hash);
|
||||||
|
qse_oht_setcomper (oht, comp);
|
||||||
|
|
||||||
|
for (x.a = 9; x.a < 20; x.a++)
|
||||||
|
{
|
||||||
|
x.x = x.a * 10;
|
||||||
|
x.y = x.a * 100;
|
||||||
|
qse_printf (QSE_T("inserting %ld => %lu\n"),
|
||||||
|
x.a, (unsigned long)qse_oht_insert (oht, &x));
|
||||||
|
}
|
||||||
|
|
||||||
|
x.a = 10;
|
||||||
|
qse_printf (QSE_T("searching for %ld => %lu\n"),
|
||||||
|
x.a, (unsigned long)qse_oht_search (oht, &x));
|
||||||
|
|
||||||
|
x.a = 10;
|
||||||
|
qse_printf (QSE_T("deleting %ld => %lu\n"),
|
||||||
|
x.a, (unsigned long)qse_oht_delete (oht, &x));
|
||||||
|
|
||||||
|
x.a = 10;
|
||||||
|
qse_printf (QSE_T("searching for %ld => %lu\n"),
|
||||||
|
x.a, (unsigned long)qse_oht_search (oht, &x));
|
||||||
|
|
||||||
|
|
||||||
|
qse_oht_walk (oht, walk2, QSE_NULL);
|
||||||
|
qse_oht_close (oht);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
R (test1);
|
||||||
|
R (test2);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -27,10 +27,10 @@ static int test1 ()
|
|||||||
//qse_xma_free (xma, ptr[2]);
|
//qse_xma_free (xma, ptr[2]);
|
||||||
//qse_xma_free (xma, ptr[3]);
|
//qse_xma_free (xma, ptr[3]);
|
||||||
|
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
qse_xma_realloc (xma, ptr[0], 500);
|
qse_xma_realloc (xma, ptr[0], 500);
|
||||||
qse_xma_realloc (xma, ptr[3], 500);
|
qse_xma_realloc (xma, ptr[3], 500);
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
|
|
||||||
qse_xma_close (xma);
|
qse_xma_close (xma);
|
||||||
return 0;
|
return 0;
|
||||||
@ -51,13 +51,13 @@ static int test2 ()
|
|||||||
ptr[1] = qse_xma_alloc (xma, 1000);
|
ptr[1] = qse_xma_alloc (xma, 1000);
|
||||||
ptr[2] = qse_xma_alloc (xma, 3000);
|
ptr[2] = qse_xma_alloc (xma, 3000);
|
||||||
ptr[3] = qse_xma_alloc (xma, 1000);
|
ptr[3] = qse_xma_alloc (xma, 1000);
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
qse_xma_free (xma, ptr[0]);
|
qse_xma_free (xma, ptr[0]);
|
||||||
qse_xma_free (xma, ptr[2]);
|
qse_xma_free (xma, ptr[2]);
|
||||||
|
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
qse_xma_realloc (xma, ptr[1], 500);
|
qse_xma_realloc (xma, ptr[1], 500);
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
|
|
||||||
qse_xma_close (xma);
|
qse_xma_close (xma);
|
||||||
return 0;
|
return 0;
|
||||||
@ -78,15 +78,15 @@ static int test3 ()
|
|||||||
ptr[1] = qse_xma_alloc (xma, 1000);
|
ptr[1] = qse_xma_alloc (xma, 1000);
|
||||||
ptr[2] = qse_xma_alloc (xma, 3000);
|
ptr[2] = qse_xma_alloc (xma, 3000);
|
||||||
ptr[3] = qse_xma_alloc (xma, 1000);
|
ptr[3] = qse_xma_alloc (xma, 1000);
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
qse_xma_free (xma, ptr[0]);
|
qse_xma_free (xma, ptr[0]);
|
||||||
qse_xma_free (xma, ptr[2]);
|
qse_xma_free (xma, ptr[2]);
|
||||||
|
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
ptr[1] = qse_xma_realloc (xma, ptr[1], 3000);
|
ptr[1] = qse_xma_realloc (xma, ptr[1], 3000);
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
qse_xma_free (xma, ptr[1]);
|
qse_xma_free (xma, ptr[1]);
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
|
|
||||||
qse_xma_close (xma);
|
qse_xma_close (xma);
|
||||||
return 0;
|
return 0;
|
||||||
@ -140,20 +140,19 @@ static int test4 ()
|
|||||||
x = qse_xma_alloc (xma, 10);
|
x = qse_xma_alloc (xma, 10);
|
||||||
y = qse_xma_alloc (xma, 40);
|
y = qse_xma_alloc (xma, 40);
|
||||||
}
|
}
|
||||||
qse_xma_dump (xma, qse_printf);
|
qse_xma_dump (xma, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
|
|
||||||
qse_xma_close (xma);
|
qse_xma_close (xma);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int test5 ()
|
static int test5 ()
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
void* ptr[100];
|
void* ptr[100];
|
||||||
qse_mmgr_t xmammgr =
|
qse_mmgr_t xmammgr =
|
||||||
{
|
{
|
||||||
qse_xma_alloc,
|
(qse_mmgr_alloc_t)qse_xma_alloc,
|
||||||
qse_xma_realloc,
|
(qse_mmgr_realloc_t)qse_xma_realloc,
|
||||||
qse_xma_free,
|
(qse_mmgr_free_t)qse_xma_free,
|
||||||
QSE_NULL
|
QSE_NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -189,13 +188,15 @@ static int test5 ()
|
|||||||
qse_xma_alloc (xma3, 8);
|
qse_xma_alloc (xma3, 8);
|
||||||
qse_xma_realloc (xma3, ptr[0], 40000);
|
qse_xma_realloc (xma3, ptr[0], 40000);
|
||||||
|
|
||||||
qse_xma_dump (xma3, qse_printf);
|
qse_xma_dump (xma3, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
qse_xma_dump (xma2, qse_printf);
|
qse_xma_dump (xma2, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
qse_xma_dump (xma1, qse_printf);
|
qse_xma_dump (xma1, (qse_xma_dumper_t)qse_fprintf, QSE_STDOUT);
|
||||||
|
|
||||||
qse_xma_close (xma3);
|
qse_xma_close (xma3);
|
||||||
qse_xma_close (xma2);
|
qse_xma_close (xma2);
|
||||||
qse_xma_close (xma1);
|
qse_xma_close (xma1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main ()
|
int main ()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user