Index: ossp-pkg/act/Makefile.in RCS File: /v/ossp/cvs/ossp-pkg/act/Makefile.in,v co -q -kk -p'1.3' '/v/ossp/cvs/ossp-pkg/act/Makefile.in,v' | diff -u /dev/null - -L'ossp-pkg/act/Makefile.in' 2>/dev/null --- ossp-pkg/act/Makefile.in +++ - 2024-04-24 02:45:08.467754970 +0200 @@ -0,0 +1,76 @@ +## +## ACT Makefile +## + +CC = @CC@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +AR = @AR@ +RANLIB = @RANLIB@ +RM = rm -f +SHTOOL = ./shtool +SED = sed + +PRE = act_p.h +LIB = libact.a +SRC = act_mem.c act_ctx.c act_lib.c act_hash.c act_hash_fct.c act_hash_oh.c act_hash_lh.c +OBJ = act_mem.o act_ctx.o act_lib.o act_hash.o act_hash_fct.o act_hash_oh.o act_hash_lh.o +TST = act_test + +_VERSION_FILE = \ + $(S)act_vers.c + +_VERSION = \ + $(SHTOOL) version -l c -n 'Act' -p act_int_ $$OPT $(_VERSION_FILE);\ + V=`$(SHTOOL) version -l c -d long $(_VERSION_FILE)`;\ + $(SED) -e "s/Version .*(.*)/Version $$V/g" README.n && mv README.n README + +all: $(PRE) $(LIB) $(TST) + +.c.o: + $(CC) $(CFLAGS) -c $< + +$(PRE): $(PRE).in + $(SHTOOL) scpp -o $(PRE) -t $(PRE).in -Dcpp -Cintern -M '==#==' $(SRC) + +$(LIB): $(OBJ) + $(AR) rc $(LIB) $(OBJ) + $(RANLIB) $(LIB) + +$(TST): $(TST).o $(LIB) + $(CC) $(LDFLAGS) -o $(TST) $(TST).o $(LIB) + +test-hash-fct: + $(CC) -DACT_TEST -oact_hash_fct act_hash_fct.c -lm + ./act_hash_fct + +# increase or update version information +new-version: + @V="$(VERSION)"; \ + if [ ".$$V" != . ]; then \ + OPT="-s$$V"; \ + else \ + OPT="-e"; \ + fi; \ + $(_VERSION) +update-version: + OPT="-s`$(SHTOOL) version -lc -dshort $(_VERSION_FILE)`" && $(_VERSION) + +clean: + $(RM) $(PRE) + $(RM) $(LIB) + $(RM) $(OBJ) + $(RM) $(TST).o $(TST) + $(RM) core *.core *.aux *.log + $(RM) act_hash_fct + +distclean: + @$(MAKE) $(MFLAGS) clean + $(RM) config.log config.cache config.status + $(RM) act_cfg.h act_p.h act.h + $(RM) Makefile + +check: test +test: + time ./act_test + Index: ossp-pkg/act/README RCS File: /v/ossp/cvs/ossp-pkg/act/README,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/README,v' | diff -u /dev/null - -L'ossp-pkg/act/README' 2>/dev/null --- ossp-pkg/act/README +++ - 2024-04-24 02:45:08.470442438 +0200 @@ -0,0 +1,18 @@ + _ _ + / \ ___| |_ + / _ \ / __| __| + / ___ \ (__| |_ + /_/ \_\___|\__| + + Act -- Abstract Container Types + + A lower level data structure library for abstract container types. + Copyright (c) 1999-2000 Ralf S. Engelschall, All Rights Reserved. + + Design Goals: + o allows low-level adjustments of data structures + o uses a general contexts concept (shared memory support, user attachments) + o is thread-safe + reentrant ? + o allows the use of arbitrary user key/values + o allows key/values to be loans or gifts + Index: ossp-pkg/act/act.h.in RCS File: /v/ossp/cvs/ossp-pkg/act/act.h.in,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act.h.in,v' | diff -u /dev/null - -L'ossp-pkg/act/act.h.in' 2>/dev/null --- ossp-pkg/act/act.h.in +++ - 2024-04-24 02:45:08.473077506 +0200 @@ -0,0 +1,189 @@ +/* +** act.h -- ACT API header +** +** ==================================================================== +** Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY +** EXPRESSED 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 RALF S. ENGELSCHALL OR +** ITS CONTRIBUTORS 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 _ACT_H_ +#define _ACT_H_ + + /* the library version */ +#ifndef ACT_VERSION +#define ACT_VERSION @ACT_VERSION_HEX@ +#endif + + /* essential headers */ +#include /* for ssize_t, off_t */ + + /* essential typedefs */ +@HAVE_ACT_UINT8_T@ +@HAVE_ACT_UINT16_T@ +@HAVE_ACT_UINT32_T@ +@HAVE_ACT_UINT64_T@ +@HAVE_ACT_SIZE_T@ +typedef @ACT_UINT8_T@ act_uint8_t; +typedef @ACT_UINT16_T@ act_uint16_t; +typedef @ACT_UINT32_T@ act_uint32_t; +typedef @ACT_UINT64_T@ act_uint64_t; +typedef @ACT_SIZE_T@ act_size_t; + + /* C++ support */ +#ifdef __cplusplus +#define BEGIN_DECLARATION extern "C" { +#define END_DECLARATION } +#else +#define BEGIN_DECLARATION /*nop*/ +#define END_DECLARATION /*nop*/ +#endif + +/* true and false boolean values */ +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +/* Do not depend on the exact TRUE value, i.e. never do: x == TRUE. + Use TRUE only for return or assignment. */ +#define TRUE !FALSE +#endif + +/* null values for pointers and characters */ +#ifndef NULL +#define NULL ((void *)0) +#endif +#ifndef NUL +#define NUL '\0' +#endif + +/* + * Internal Bitmask Calculation Macros + * (Notice: bit positions are counted n...0, i.e. lowest bit is position 0) + */ + +/* generate a bitmask consisting of 1 bits from (and including) + bit position `l' (left) to (and including) bit position `r' */ +#define _BM_MASK(l,r) (((1<<((l)-(r)+1))-1)<<(r)) + +/* extract a value v from a word w at position `l' to `r' and return value */ +#define _BM_GET(w,l,r) (((w)>>(r))&_BM_MASK((l)-(r),0)) + +/* insert a value v into a word w at position `l' to `r' and return word */ +#define _BM_SET(w,l,r,v) ((w)|(((v)&_BM_MASK((l)-(r),0))<<(r))) + +/* generate a single bit `b' (0 or 1) at bit position `n' */ +#define _BM_BIT(n,b) ((b)<<(n)) + +/* generate a quad word octet of bits (a half byte, i.e. bit positions 3 to 0) */ +#define _BM_QUAD(b3,b2,b1,b0) (_BM_BIT(3,(b3))|_BM_BIT(2,(b2))|_BM_BIT(1,(b1))|_BM_BIT(0,(b0))) + +/* generate an octet word of bits (a byte, i.e. bit positions 7 to 0) */ +#define _BM_OCTET(b7,b6,b5,b4,b3,b2,b1,b0) ((_BM_QUAD(b7,b6,b5,b4)<<4)|_BM_QUAD(b3,b2,b1,b0)) + +/* generate the value 2^n */ +#define _BM_POW2(n) _BM_BIT(1,n) + +/* shift word w k bits to the left or to the right */ +#define _BM_SHL(w,k) ((w)<<(k)) +#define _BM_SHR(w,k) ((w)>>(k)) + +/* rotate word w (of bits n..0) k bits to the left or to the right */ +#define _BM_ROL(w,n,k) (_BM_SHL((w),(k))&_BM_MASK(n,0))|_BM_SHR(((w)&_BM_MASK(n,0)),(n)-(k)) +#define _BM_ROR(w,n,k) (_BM_SHR(((w)&_BM_MASK(n,0)),(k)))|_BM_SHL(((w),(n)-(k))&_BM_MASK(n,0)) + +/* + * Some math functions + */ +#ifndef _M_MIN +#define _M_MIN(a,b) (((a)<(b)) ? (a) : (b)) +#endif +#ifndef _M_MAX +#define _M_MAX(a,b) (((a)>(b)) ? (a) : (b)) +#endif +#ifndef _M_ABS +#define _M_ABS(a) (((a)>0) ? (a) : -(a)) +#endif +#ifndef _M_ALIGN +#define _M_ALIGN(a) (((unsigned long int)(a)+(sizeof((void *)-1)))&(~(sizeof((void *)-1)))) +#endif + +/* + * A hacker macro for finding the offset of a `field' + * in a structure of type `type'. + */ +#define _OffsetOf(type,s_field) \ + ((unsigned int)(((char *)(&(((type *)0)->field)))-((char *)0))) + +/* + * ACT data types + */ + +enum act_type_en { + act_type_ptr, + act_type_int, + act_type_long, + act_type_double +}; +typedef enum act_type_en act_type_t; + +/* + * ??? + */ + +/* additional errno values */ +#define ACT_E_NOMEM 0 +#define ACT_E_INVAL 0 +#define ACT_E_INTERN 0 + +/* positions */ +#define ACT_POS_ABOVE 0 +#define ACT_POS_BELOW 0 +#define ACT_POS_BEFORE 0 +#define ACT_POS_AFTER 0 + +/* walking */ +#define ACT_MOV_PARENT 0 +#define ACT_MOV_CHILD(n) 0 +#define ACT_MOV_PREV 0 +#define ACT_MOV_NEXT 0 + +/* boolean type */ +typedef unsigned short int act_bool_t; + +#define ACT_CTX_KEY_SIZE ACT_CTX_ID(int,COMMON,0) +#define ACT_CTX_KEY_LOAN ACT_CTX_ID(int,COMMON,1) +#define ACT_CTX_KEY_ISPTR ACT_CTX_ID(int,COMMON,2) +#define ACT_CTX_VAL_SIZE ACT_CTX_ID(int,COMMON,3) +#define ACT_CTX_VAL_LOAN ACT_CTX_ID(int,COMMON,4) +#define ACT_CTX_VAL_ISPTR ACT_CTX_ID(int,COMMON,5) +#define ACT_CTX_VAL_EXPECT ACT_CTX_ID(int,COMMON,6) + +#include "act_lib.h" +#include "act_ctx.h" + +#endif /* _ACT_H_ */ Index: ossp-pkg/act/act_ctx.c RCS File: /v/ossp/cvs/ossp-pkg/act/act_ctx.c,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_ctx.c,v' | diff -u /dev/null - -L'ossp-pkg/act/act_ctx.c' 2>/dev/null --- ossp-pkg/act/act_ctx.c +++ - 2024-04-24 02:45:08.475768725 +0200 @@ -0,0 +1,256 @@ +/* +** act_ctx.c -- ACT Context Handling +** +** ==================================================================== +** Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY +** EXPRESSED 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 RALF S. ENGELSCHALL OR +** ITS CONTRIBUTORS 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. +** ==================================================================== +*/ + +#include "act_p.h" + +/* the value of a context entry */ +union act_ctx_value_un { + void *v_ptr; + int v_int; + long v_long; + double v_double; +}; +typedef union act_ctx_value_un act_ctx_value_t; + +/* the context entry */ +struct act_ctx_entry_st { + unsigned int e_id; + act_ctx_value_t e_value; +}; +typedef struct act_ctx_entry_st act_ctx_entry_t; + +/* the context */ +struct act_ctx_st { + act_ctx_entry_t c_entry[ACT_CTX_ENTRY_MAX+1]; +}; + +/* the default context */ +act_ctx_t *act_ctx_default = NULL; + +/* initialize the context module */ +intern int act_ctx_init(void) +{ + if (act_ctx_default != NULL) + act_ctx_free(act_ctx_default); + act_ctx_default = act_ctx_new(); + return TRUE; +} + +/* kill the context module */ +intern int act_ctx_kill(void) +{ + if (act_ctx_default != NULL) { + act_ctx_free(act_ctx_default); + act_ctx_default = NULL; + } + return TRUE; +} + +/* allocate a new context structure */ +act_ctx_t *act_ctx_new(void) +{ + act_ctx_t *ctx; + int i; + + if ((ctx = (act_ctx_t *)act_mem_alloc(sizeof(struct act_ctx_st))) == NULL) + return NULL; + for (i = 0; i < ACT_CTX_ENTRY_MAX; i++) { + ctx->c_entry[i].e_id = ACT_CTX_ID_NULL; + ctx->c_entry[i].e_value.v_long = 0; + } + return ctx; +} + +/* duplicate a new context structure (optionally with the help of a template) */ +act_ctx_t *act_ctx_dup(act_ctx_t *ctx, act_ctx_t *ctx_template) +{ + act_ctx_t *ctx_new; + act_ctx_t *ctx_from; + int i; + int sp,lk,ty,no; + + if (ctx == NULL) + return NULL; + if (ctx_template != NULL) + ctx_from = ctx_template; + else + ctx_from = ctx; + if ((ctx_new = (act_ctx_t *)act_mem_alloc(sizeof(struct act_ctx_st))) == NULL) + return NULL; + act_mem_move(ctx_new->c_entry, ctx_from->c_entry, + sizeof(act_ctx_entry_t)*(ACT_CTX_ENTRY_MAX+1)); + if (ctx_template != NULL) { + for (i = 0; i <= ACT_CTX_ENTRY_MAX; i++) { + ACT_CTX_ID_SPLIT(sp, lk, ty, no, ctx_new->c_entry[i].e_id); + if (!lk) { + ctx_new->c_entry[i].e_id = ctx->c_entry[i].e_id; + act_mem_move(&(ctx_new->c_entry[i].e_value), &(ctx->c_entry[i].e_value), + sizeof(act_ctx_value_t)); + } + } + } + return ctx_new; +} + +/* common function for both set and get context entries */ +static int act_ctx_setget(act_ctx_t *ctx, int set, unsigned int id, va_list ap) +{ + int sp,lk,ty,no; + int csp,clk,cty,cno; + + ACT_CTX_ID_SPLIT(sp, lk, ty, no, id); + ACT_CTX_ID_SPLIT(csp, clk, cty, cno, ctx->c_entry[no].e_id); + if (set && clk) + return FALSE; + switch (ty) { + case act_type_ptr: + if (set) + ctx->c_entry[no].e_value.v_ptr = va_arg(ap, void *); + else { + void **v = va_arg(ap, void **); + *v = ctx->c_entry[no].e_value.v_ptr; + } + break; + case act_type_int: + if (set) + ctx->c_entry[no].e_value.v_int = va_arg(ap, int); + else { + int *v = va_arg(ap, int *); + *v = ctx->c_entry[no].e_value.v_int; + } + break; + case act_type_long: + if (set) + ctx->c_entry[no].e_value.v_long = va_arg(ap, long); + else { + long *v = va_arg(ap, long *); + *v = ctx->c_entry[no].e_value.v_long; + } + break; + case act_type_double: + if (set) + ctx->c_entry[no].e_value.v_double = va_arg(ap, double); + else { + double *v = va_arg(ap, double *); + *v = ctx->c_entry[no].e_value.v_double; + } + break; + default: + return FALSE; + break; + } + ctx->c_entry[no].e_id = id; + return TRUE; +} + +/* set an entry in a context structure */ +int act_ctx_set(act_ctx_t *ctx, unsigned int id, ...) +{ + va_list ap; + int rc; + + if (ctx == NULL) + return FALSE; + va_start(ap, id); + rc = act_ctx_setget(ctx, TRUE, id, ap); + va_end(ap); + return rc; +} + +/* get an entry from a context structure */ +int act_ctx_get(act_ctx_t *ctx, unsigned int id, ...) +{ + va_list ap; + int rc; + + if (ctx == NULL) + return FALSE; + va_start(ap, id); + rc = act_ctx_setget(ctx, FALSE, id, ap); + va_end(ap); + return rc; +} + +/* get the address of an entry from a context structure */ +void *act_ctx_var(act_ctx_t *ctx, unsigned int id) +{ + int sp,lk,ty,no; + + if (ctx == NULL) + return FALSE; + ACT_CTX_ID_SPLIT(sp, lk, ty, no, id); + return &(ctx->c_entry[no].e_value); +} + +/* lock an entry of the context structure */ +int act_ctx_lock(act_ctx_t *ctx, unsigned int id) +{ + int rsp,rlk,rty,rno; + int csp,clk,cty,cno; + + if (ctx == NULL) + return FALSE; + ACT_CTX_ID_SPLIT(rsp,rlk,rty,rno,id); + ACT_CTX_ID_SPLIT(csp,clk,cty,cno,ctx->c_entry[rno].e_id); + ctx->c_entry[rno].e_id = ACT_CTX_ID_CONS(csp,1,cty,cno); + return TRUE; +} + +/* unlock an entry of the context structure */ +int act_ctx_unlock(act_ctx_t *ctx, unsigned int id) +{ + int rsp,rlk,rty,rno; + int csp,clk,cty,cno; + + if (ctx == NULL) + return FALSE; + ACT_CTX_ID_SPLIT(rsp,rlk,rty,rno,id); + ACT_CTX_ID_SPLIT(csp,clk,cty,cno,ctx->c_entry[rno].e_id); + ctx->c_entry[rno].e_id = ACT_CTX_ID_CONS(csp,0,cty,cno); + return TRUE; +} + +/* free a context structure */ +int act_ctx_free(act_ctx_t *ctx) +{ + void *ptr; + + if (ctx == NULL) + return FALSE; + if (act_ctx_get(ctx, ACT_CTX_CTX_BINDING, &ptr)) + if (ptr != NULL) + return FALSE; + act_mem_free(ctx); + return TRUE; +} + Index: ossp-pkg/act/act_ctx.h RCS File: /v/ossp/cvs/ossp-pkg/act/act_ctx.h,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_ctx.h,v' | diff -u /dev/null - -L'ossp-pkg/act/act_ctx.h' 2>/dev/null --- ossp-pkg/act/act_ctx.h +++ - 2024-04-24 02:45:08.478462435 +0200 @@ -0,0 +1,111 @@ +/* +** act_ctx.h -- ACT context header +** +** ==================================================================== +** Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY +** EXPRESSED 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 RALF S. ENGELSCHALL OR +** ITS CONTRIBUTORS 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 _ACT_CTX_H_ +#define _ACT_CTX_H_ + +#include "act.h" + +/* context limits */ +#define ACT_CTX_ENTRY_MAX 63 + +/* the special null context id */ +#define ACT_CTX_ID_NULL 0 + +/* high level context id constructor */ +#define ACT_CTX_ID(type,base,indx) \ + ACT_CTX_ID_CONS(0,0,act_type_##type,ACT_CTX_BASE_##base+(indx)) + +/* generate a context id from ingredients */ +#define ACT_CTX_ID_CONS(spec,lock,type,indx) \ + (__ACT_CTX_ID_SETSPEC(spec)|\ + __ACT_CTX_ID_SETLOCK(lock)|\ + __ACT_CTX_ID_SETTYPE(type)|\ + __ACT_CTX_ID_SETINDX(indx)) + +/* split a context id into ingredients */ +#define ACT_CTX_ID_SPLIT(spec,lock,type,indx,id) \ + (spec) = __ACT_CTX_ID_GETSPEC(id);\ + (lock) = __ACT_CTX_ID_GETLOCK(id);\ + (type) = __ACT_CTX_ID_GETTYPE(id);\ + (indx) = __ACT_CTX_ID_GETINDX(id); + +/* split out the index of a context id only */ +#define ACT_CTX_ID_INDEX(id) \ + __ACT_CTX_ID_GETINDX(id) + +/* internal macros */ +#define __ACT_CTX_ID_SETSPEC(val) _BM_SET(0,10,10,(val)) +#define __ACT_CTX_ID_GETSPEC(id) _BM_GET((id),10,10) +#define __ACT_CTX_ID_SETLOCK(val) _BM_SET(0,9,9,(val)) +#define __ACT_CTX_ID_GETLOCK(id) _BM_GET((id),9,9) +#define __ACT_CTX_ID_SETTYPE(val) _BM_SET(0,8,6,(val)) +#define __ACT_CTX_ID_GETTYPE(id) _BM_GET((id),8,6) +#define __ACT_CTX_ID_SETINDX(val) _BM_SET(0,5,0,(val)) +#define __ACT_CTX_ID_GETINDX(id) _BM_GET((id),5,0) + +/* pre-defined base numbers for context ids of sub-libraries */ +#define ACT_CTX_BASE_CTX 0 +#define ACT_CTX_BASE_MEM 10 +#define ACT_CTX_BASE_COMMON 15 +#define ACT_CTX_BASE_BITS 25 +#define ACT_CTX_BASE_ARRAY 30 +#define ACT_CTX_BASE_LIST 35 +#define ACT_CTX_BASE_BUFFER 40 +#define ACT_CTX_BASE_TREE 45 +#define ACT_CTX_BASE_HASH 50 +#define ACT_CTX_BASE_USER 55 + +/* the context ids of the ctx sub-library itself */ +#define ACT_CTX_CTX_LOCKING ACT_CTX_ID_CONS(1,0,act_type_ptr,ACT_CTX_BASE_CTX+0) +#define ACT_CTX_CTX_BINDING ACT_CTX_ID_CONS(1,0,act_type_ptr,ACT_CTX_BASE_CTX+1) +#define ACT_CTX_CTX_CALLBACK ACT_CTX_ID_CONS(1,0,act_type_ptr,ACT_CTX_BASE_CTX+2) + +/* the opaque context data structure */ +struct act_ctx_st; +typedef struct act_ctx_st act_ctx_t; + +/* the global default context */ +act_ctx_t *act_ctx_default; + +/* the context API */ +extern act_ctx_t *act_ctx_new (void); +extern act_ctx_t *act_ctx_dup (act_ctx_t *, act_ctx_t *); +extern int act_ctx_set (act_ctx_t *, unsigned int, ...); +extern int act_ctx_get (act_ctx_t *, unsigned int, ...); +extern void *act_ctx_var (act_ctx_t *, unsigned int); +extern int act_ctx_lock (act_ctx_t *, unsigned int); +extern int act_ctx_unlock (act_ctx_t *, unsigned int); +extern int act_ctx_free (act_ctx_t *); + +#endif /* _ACT_CTX_H_ */ Index: ossp-pkg/act/act_hash.c RCS File: /v/ossp/cvs/ossp-pkg/act/act_hash.c,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_hash.c,v' | diff -u /dev/null - -L'ossp-pkg/act/act_hash.c' 2>/dev/null --- ossp-pkg/act/act_hash.c +++ - 2024-04-24 02:45:08.481066153 +0200 @@ -0,0 +1,141 @@ +/* ==================================================================== + * Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY + * EXPRESSED 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 RALF S. ENGELSCHALL OR + * ITS CONTRIBUTORS 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. + * ==================================================================== + */ + +#include "act_p.h" + +/* the generic top-level data structure for a hash */ +struct act_hash_st { + act_ctx_t *h_ctx; /* the attached ACT context */ + act_hash_method_t *h_method; /* the hashing method which is actually used */ + void *h_data; /* the data structure of the hasing method */ +}; + +/* convinience macro for calling a method */ +#define method(h,name) h->h_method->m_##name + +/* global initialization at library startup time */ +intern int act_hash_init(void) +{ + act_ctx_set(act_ctx_default, ACT_HASH_METHOD, act_hash_mth(lh)); + act_ctx_set(act_ctx_default, ACT_HASH_FUNC, act_hash_fct(djbx33a)); + act_ctx_set(act_ctx_default, ACT_HASH_TABLESIZE, 128); + act_ctx_set(act_ctx_default, ACT_HASH_MINLOADFCTR, 1); + act_ctx_set(act_ctx_default, ACT_HASH_MAXLOADFCTR, 2); + return TRUE; +} + +/* global destruction at library startup time */ +intern int act_hash_kill(void) +{ + return TRUE; +} + +/* create a new hash */ +act_hash_t *act_hash_new(act_ctx_t *ctx) +{ + act_hash_t *h; + act_hash_method_t *method; + void *data; + + insist(ctx != NULL, NULL); + + /* fetch the implementation method */ + insist(act_ctx_get(ctx, ACT_HASH_METHOD, &method), NULL); + insist(method != NULL, NULL); + insist(method->m_tag == ACT_HASH_METHOD_TAG, NULL); + + /* create a new hash */ + data = method->m_new(ctx); + insist(data != NULL, NULL); + + /* allocate a top-level data structure */ + if ((h = (act_hash_t *)act_mem_alloc(sizeof(act_hash_t))) == NULL) { + method->m_free(ctx, data); + return NULL; + } + + /* stash ingredients into top-level data structure */ + h->h_ctx = act_ctx_dup(ctx, NULL); + h->h_method = method; + h->h_data = data; + + return h; +} + +/* return the attached context */ +act_ctx_t *act_hash_ctx(act_hash_t *h) +{ + insist(h != NULL, NULL); + return h->h_ctx; +} + +/* destroy the hash */ +int act_hash_free(act_hash_t *h) +{ + insist(h != NULL, NULL); + + /* destroy real hash table */ + if (!method(h, free)(h->h_ctx, h->h_data)) + return FALSE; + + /* destroy top-level structure */ + act_mem_free(h); + + return TRUE; +} + +/* insert an element into the hash */ +int act_hash_insert(act_hash_t *h, void *kp, int ks, void *dp, int ds, int ov) +{ + insist(h != NULL, NULL); + return method(h, insert)(h->h_ctx, h->h_data, kp, ks, dp, ds, ov); +} + +/* lookup an element from the hash */ +int act_hash_lookup(act_hash_t *h, void *kp, int ks, void **dp, int *ds) +{ + insist(h != NULL, NULL); + return method(h, lookup)(h->h_ctx, h->h_data, kp, ks, dp, ds); +} + +/* delete an element in the hash */ +int act_hash_delete(act_hash_t *h, void *kp, int ks) +{ + insist(h != NULL, NULL); + return method(h, delete)(h->h_ctx, h->h_data, kp, ks); +} + +/* determine byte and element size of the hash */ +int act_hash_size(act_hash_t *h, long *pb, long *pe) +{ + insist(h != NULL, NULL); + return method(h, size)(h->h_ctx, h->h_data, pb, pe); +} + Index: ossp-pkg/act/act_hash.h RCS File: /v/ossp/cvs/ossp-pkg/act/act_hash.h,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_hash.h,v' | diff -u /dev/null - -L'ossp-pkg/act/act_hash.h' 2>/dev/null --- ossp-pkg/act/act_hash.h +++ - 2024-04-24 02:45:08.483679498 +0200 @@ -0,0 +1,113 @@ +/* ==================================================================== + * Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY + * EXPRESSED 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 RALF S. ENGELSCHALL OR + * ITS CONTRIBUTORS 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. + * ==================================================================== + */ + +/* +** act_hash.c -- Dynamic Hash Table +*/ + +#ifndef _ACT_HASH_H_ +#define _ACT_HASH_H_ + +/* the opaque hashing data structure */ +struct act_hash_st; +typedef struct act_hash_st act_hash_t; + +/* context entries for hashing */ +#define ACT_HASH_METHOD ACT_CTX_ID(ptr,HASH,0) +#define ACT_HASH_FUNC ACT_CTX_ID(ptr,HASH,1) +#define ACT_HASH_TABLESIZE ACT_CTX_ID(int,HASH,2) +#define ACT_HASH_MAXLOADFCTR ACT_CTX_ID(int,HASH,3) +#define ACT_HASH_MINLOADFCTR ACT_CTX_ID(int,HASH,4) + +/* types corresponding to the dispatch functions */ +typedef void *(*act_hash_new_t) (act_ctx_t *); +typedef int (*act_hash_insert_t) (act_ctx_t *, void *, void *, int, void *, int, int); +typedef int (*act_hash_lookup_t) (act_ctx_t *, void *, void *, int, void **, int *); +typedef int (*act_hash_delete_t) (act_ctx_t *, void *, void *, int); +typedef int (*act_hash_size_t) (act_ctx_t *, void *, long *, long *); +typedef int (*act_hash_free_t) (act_ctx_t *, void *); + +/* the dispatch structure for the hash implementation method */ +typedef struct act_hash_method_st { + unsigned int m_tag; + act_hash_new_t m_new; + act_hash_insert_t m_insert; + act_hash_lookup_t m_lookup; + act_hash_delete_t m_delete; + act_hash_size_t m_size; + act_hash_free_t m_free; +} act_hash_method_t; + +/* the magic cookie which identifies a method structure */ +#define ACT_HASH_METHOD_TAG 0xBEEF + +/* the hashing API functions */ +act_hash_t *act_hash_new(act_ctx_t *); +act_ctx_t *act_hash_ctx(act_hash_t *); +int act_hash_insert(act_hash_t *, void *, int, void *, int, int); +int act_hash_lookup(act_hash_t *, void *, int, void **, int *); +int act_hash_delete(act_hash_t *, void *, int); +int act_hash_size(act_hash_t *, long *, long *); +int act_hash_free(act_hash_t *); + +#define act_hash_mth(name) \ + &(act_hash_##name) + +#define __act_hash_mth_proto(name) \ + extern act_hash_method_t act_hash_##name + +__act_hash_mth_proto(oh); +__act_hash_mth_proto(lh); + +typedef unsigned long (*act_hash_fct_t)(unsigned char *, unsigned int); + +#define act_hash_fct(name) \ + __act_hash_fct_##name + +#define __act_hash_fct_proto(name) \ + extern unsigned long __act_hash_fct_##name(unsigned char *, unsigned int) + +__act_hash_fct_proto(djbx33a); +__act_hash_fct_proto(djbx33x); +__act_hash_fct_proto(vocong); +__act_hash_fct_proto(bjddj); +__act_hash_fct_proto(crc32); +__act_hash_fct_proto(cpoaat); +__act_hash_fct_proto(ozsdbm); +__act_hash_fct_proto(fonovo); +__act_hash_fct_proto(kazlib); +__act_hash_fct_proto(buzhash); +__act_hash_fct_proto(pearson); +__act_hash_fct_proto(jotcl); +__act_hash_fct_proto(cbu); +__act_hash_fct_proto(cvs); + +#endif /* _ACT_HASH_H_ */ + Index: ossp-pkg/act/act_hash_fct.c RCS File: /v/ossp/cvs/ossp-pkg/act/act_hash_fct.c,v rcsdiff -q -kk '-r1.18' '-r1.19' -u '/v/ossp/cvs/ossp-pkg/act/act_hash_fct.c,v' 2>/dev/null --- act_hash_fct.c 2000/07/19 06:34:28 1.18 +++ act_hash_fct.c 2000/08/18 15:35:57 1.19 @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 1999 Ralf S. Engelschall. All rights reserved. + * Copyright (c) 1999-2000 Ralf S. Engelschall. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Index: ossp-pkg/act/act_hash_lh.c RCS File: /v/ossp/cvs/ossp-pkg/act/act_hash_lh.c,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_hash_lh.c,v' | diff -u /dev/null - -L'ossp-pkg/act/act_hash_lh.c' 2>/dev/null --- ossp-pkg/act/act_hash_lh.c +++ - 2024-04-24 02:45:08.492119806 +0200 @@ -0,0 +1,491 @@ +/* ==================================================================== + * Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY + * EXPRESSED 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 RALF S. ENGELSCHALL OR + * ITS CONTRIBUTORS 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. + * ==================================================================== + */ + +/* +** act_hash_lh.c -- Linear Hashing (dynamic) +** +** This module implements a Dynamic Hash Table, based on WITOLD LITWIN +** and PER-AKE LARSON's ``Linear Hashing'' algorithm (1980/1988), +** implemented on top of a two-level virtual array with separate +** collision chains as the backend data structure. Some ideas were +** taken over from MIKAEL PETTERSON's Linear Hashing enhancements +** (1993). +*/ + +#include "act_p.h" + +/* fixed size (number of pointers) of the directory and of each segment */ +#define INITDIRSIZE 256 /* can be an arbitrary value */ +#define SEGMENTSIZE 512 /* = 2^9, must be a power of 2 */ + +/* calculate index in directory and segments from virtual array index */ +#define DIRINDEX(addr) ((addr) >> 9) /* == ((addr) / SEGMENTSIZE) */ +#define SEGINDEX(addr) ((addr) & (512-1)) /* == ((addr) % SEGMENTSIZE) */ + +/* load of hash table (maximum should be between 2 and 4) */ +#define MINLOADFCTR 1 +#define MAXLOADFCTR 2 + +/* the per-element structure (keep this as small as possible!) */ +typedef struct element_st element_t; +struct element_st { + element_t *e_next; /* pointer to next element in collision chain */ + unsigned long e_hash; /* cached hash value of element (rehashing optimization) */ + void *e_keyptr; /* pointer to key (= also pointer to key+data memory chunk) */ + void *e_datptr; /* pointer to data in key+data memory chunk */ + void *e_endptr; /* pointer to end of key+data memory chunk */ +}; + +/* on-the-fly calculate lengths of key and data to reduce memory in element_t */ +#define el_keylen(el) ((char *)((el)->e_datptr)-(char *)((el)->e_keyptr)) +#define el_datlen(el) ((char *)((el)->e_endptr)-(char *)((el)->e_datptr)) + +/* the hash table segments */ +typedef struct segment_st segment_t; +struct segment_st { + element_t *s_element[SEGMENTSIZE]; /* array of pointers to elements */ +}; + +/* the top-level hash table structure */ +typedef struct act_hash_lh_st act_hash_lh_t; +struct act_hash_lh_st { + act_ctx_t *h_ctx; /* context structure */ + act_hash_fct_t h_func; /* hash function (copied from context) */ + unsigned int h_p; /* pointer to start of unsplit region */ + unsigned int h_pmax; /* pointer to end of unsplit region */ + int h_slack; /* grow/shrink indicator */ + unsigned h_dirsize; /* current size of directory */ + segment_t **h_dir; /* pointer to directory */ +}; + +/* create the hash table structure */ +static act_hash_lh_t *act_hash_lh_new(act_ctx_t *ctx) +{ + act_hash_lh_t *h; + + /* allocate hash structure */ + if ((h = (act_hash_lh_t *)act_mem_alloc_ctx(ctx, sizeof(struct act_hash_lh_st))) == NULL) + return NULL; + h->h_ctx = ctx; + + /* allocate and clear hash table directory */ + h->h_dirsize = INITDIRSIZE; + if ((h->h_dir = (segment_t **)act_mem_alloc_ctx(ctx, h->h_dirsize * sizeof(segment_t *))) == NULL) { + errno_safe( act_mem_free_ctx(ctx, h) ); + return NULL; + } + act_mem_set(h->h_dir, 0, h->h_dirsize * sizeof(segment_t *)); + + /* allocate and clear first segment of hash table array */ + if ((h->h_dir[0] = (segment_t *)act_mem_alloc_ctx(ctx, sizeof(segment_t))) == NULL) { + errno_safe( act_mem_free_ctx(ctx, h->h_dir); act_mem_free_ctx(ctx, h) ); + return NULL; + } + act_mem_set(h->h_dir[0], 0, sizeof(segment_t)); + + /* initialize hash table control attributes */ + h->h_p = 0; + h->h_pmax = SEGMENTSIZE; + h->h_slack = SEGMENTSIZE * MAXLOADFCTR; + + /* inline values from context (for performance reasons only) */ + if (!act_ctx_get(ctx, ACT_HASH_FUNC, &h->h_func)) + h->h_func = act_hash_fct(djbx33a); + + return h; +} + +/* expand the hash table */ +static void act_hash_lh_expand(act_ctx_t *ctx, act_hash_lh_t *h) +{ + unsigned int pmax0; + unsigned int newaddr; + segment_t *seg; + element_t **pelold; + element_t *el, *headofold, *headofnew, *next; + unsigned int n; + + /* calculate next new address */ + pmax0 = h->h_pmax; + newaddr = pmax0 + h->h_p; + + /* have to enlarge directory? */ + if (h->h_dirsize <= DIRINDEX(newaddr)) { + n = h->h_dirsize * sizeof(segment_t *); + h->h_dirsize *= 2; + if ((h->h_dir = (segment_t **)act_mem_realloc_ctx(ctx, + h->h_dir, h->h_dirsize*sizeof(segment_t *))) == NULL) + return; + act_mem_set((char *)h->h_dir+n, 0, n); + } + + /* have to create a new table segment? */ + if (SEGINDEX(newaddr) == 0) { + if ((seg = (segment_t *)act_mem_alloc_ctx(ctx, sizeof(segment_t))) == NULL) + return; + act_mem_set(seg, 0, sizeof(segment_t)); + h->h_dir[DIRINDEX(newaddr)] = seg; + } + + /* locate P-element */ + pelold = &h->h_dir[DIRINDEX(h->h_p)]->s_element[SEGINDEX(h->h_p)]; + + /* adjust the state variables */ + if (++(h->h_p) >= h->h_pmax) { + h->h_pmax = (h->h_pmax << 1); /* == h->h_pmax * 2 */ + h->h_p = 0; + } + h->h_slack += MAXLOADFCTR; + + /* relocate and split between P-element new element */ + headofold = NULL; + headofnew = NULL; + for (el = *pelold; el != NULL; el = next) { + next = el->e_next; + if (el->e_hash & pmax0) { + el->e_next = headofnew; + headofnew = el; + } else { + el->e_next = headofold; + headofold = el; + } + } + *pelold = headofold; + h->h_dir[DIRINDEX(newaddr)]->s_element[SEGINDEX(newaddr)] = headofnew; + + return; +} + +/* shrink hash table */ +static void act_hash_lh_shrink(act_ctx_t *ctx, act_hash_lh_t *h) +{ + segment_t *lastseg; + element_t **pel; + unsigned int oldlast; + unsigned int dirsize; + void *dir; + + /* calculate old last element */ + oldlast = h->h_p + h->h_pmax - 1; + + /* we cannot shrink below one segment */ + if (oldlast == 0) + return; + + /* adjust the state variables */ + if (h->h_p == 0) { + h->h_pmax = (h->h_pmax >> 1); /* == h->h_pmax / 2 */; + h->h_p = h->h_pmax - 1; + } else + h->h_p--; + h->h_slack -= MAXLOADFCTR; + + /* relocate the lost old last element to the end of the P-element */ + pel = &h->h_dir[DIRINDEX(h->h_p)]->s_element[SEGINDEX(h->h_p)]; + while (*pel != NULL) + pel = &((*pel)->e_next); + lastseg = h->h_dir[DIRINDEX(oldlast)]; + *pel = lastseg->s_element[SEGINDEX(oldlast)]; + lastseg->s_element[SEGINDEX(oldlast)] = NULL; + + /* if possible, deallocate the last segment */ + if (SEGINDEX(oldlast) == 0) { + h->h_dir[DIRINDEX(oldlast)] = NULL; + free(lastseg); + } + + /* if possible, deallocate the end of the directory */ + if (h->h_dirsize > INITDIRSIZE && DIRINDEX(oldlast) < h->h_dirsize/2) { + dirsize = (h->h_dirsize >> 1); /* == h->h_dirsize / 2 */ + if ((dir = (segment_t **)act_mem_realloc_ctx(ctx, + h->h_dir, dirsize*sizeof(segment_t *))) != NULL) { + h->h_dirsize = dirsize; + h->h_dir = dir; + } + } + return; +} + +/* insert element into hash table */ +static int act_hash_lh_insert(act_ctx_t *ctx, act_hash_lh_t *h, void *keyptr, int keylen, + void *datptr, int datlen, int override) +{ + unsigned int hash, addr; + element_t *el, **pel; + int bFound; + void *vp; + + /* argument consistency check */ + if (h == NULL || keyptr == NULL || keylen <= 0) + return_errno(FALSE, EINVAL); + + /* calculate hash address */ + hash = h->h_func(keyptr, keylen); + addr = hash % h->h_pmax; /* unsplit region */ + if (addr < h->h_p) + addr = hash % (h->h_pmax << 1); /* split region */ + + /* locate hash element's collision list */ + pel = &h->h_dir[DIRINDEX(addr)]->s_element[SEGINDEX(addr)]; + + /* check whether element is already in the hash table */ + bFound = FALSE; + for (el = *pel; el != NULL; el = el->e_next) { + if ( el->e_hash == hash + && el_keylen(el) == keylen + && act_mem_cmp(el->e_keyptr, keyptr, el_keylen(el)) == 0) { + bFound = TRUE; + break; + } + } + + /* only override on request */ + if (bFound && !override) + return FALSE; + + /* create a duplicate of key and data */ + if ((vp = act_mem_alloc_ctx(ctx, keylen+datlen)) == NULL) + return FALSE; + act_mem_move(vp, keyptr, keylen); + act_mem_move((char *)vp+keylen, datptr, datlen); + keyptr = vp; + datptr = (char *)vp+keylen; + + if (bFound) { + /* reuse existing element by freeing old contents */ + if (el->e_keyptr != NULL) + act_mem_free_ctx(ctx, el->e_keyptr); + } + else { + /* allocate new element and chain into list */ + if ((el = (element_t *)act_mem_alloc_ctx(ctx, sizeof(element_t))) == 0) { + act_mem_free_ctx(ctx, vp); + return FALSE; + } + while (*pel != NULL) + pel = &((*pel)->e_next); + el->e_next = *pel; + *pel = el; + } + + /* insert contents into element structure */ + el->e_keyptr = keyptr; + el->e_datptr = datptr; + el->e_endptr = (char *)datptr+datlen; + el->e_hash = hash; + + /* do we need to expand the table now? */ + if (--(h->h_slack) < 0) + act_hash_lh_expand(ctx, h); + + return TRUE; +} + +/* lookup an element in hash table */ +static int act_hash_lh_lookup(act_ctx_t *ctx, act_hash_lh_t *h, + void *keyptr, int keylen, void **datptr, int *datlen) +{ + unsigned int hash, addr; + element_t *el, **pel; + + /* argument consistency check */ + if (h == NULL || keyptr == NULL || keylen <= 0) + return_errno(FALSE, EINVAL); + + /* calculate hash address */ + hash = h->h_func(keyptr, keylen); + addr = hash % h->h_pmax; /* unsplit region */ + if (addr < h->h_p) + addr = hash % (h->h_pmax << 1); /* split region */ + + /* locate hash element collision list */ + pel = &h->h_dir[DIRINDEX(addr)]->s_element[SEGINDEX(addr)]; + + /* search for element in collision list */ + for (el = *pel; el != NULL; el = el->e_next) { + if ( el->e_hash == hash + && el_keylen(el) == keylen + && act_mem_cmp(el->e_keyptr, keyptr, el_keylen(el)) == 0) { + /* provide results */ + if (datptr != NULL) + *datptr = el->e_datptr; + if (datlen != NULL) + *datlen = el_datlen(el); + return TRUE; + } + } + return FALSE; +} + +/* delete an element in hash table */ +static int act_hash_lh_delete(act_ctx_t *ctx, act_hash_lh_t *h, void *keyptr, int keylen) +{ + unsigned int hash, addr; + element_t *el, *lel, **pel; + int rv; + + /* argument consistency check */ + if (h == NULL || keyptr == NULL || keylen <= 0) + return_errno(FALSE, EINVAL); + + /* calculate hash address */ + hash = h->h_func(keyptr, keylen); + addr = hash % h->h_pmax; /* unsplit region */ + if (addr < h->h_p) + addr = hash % (h->h_pmax << 1); /* split region */ + + /* locate hash element collision chain */ + pel = &h->h_dir[DIRINDEX(addr)]->s_element[SEGINDEX(addr)]; + + /* search for element in collision chain */ + rv = FALSE; + for (lel = NULL, el = *pel; el != NULL; lel = el, el = el->e_next) { + if ( el->e_hash == hash + && el_keylen(el) == keylen + && act_mem_cmp(el->e_keyptr, keyptr, el_keylen(el)) == 0) { + /* free key+data memory chunk */ + if (el->e_keyptr != NULL) + act_mem_free_ctx(ctx, el->e_keyptr); + /* remove element from collision chain */ + if (lel == NULL) + *pel = el->e_next; + else + lel->e_next = el->e_next; + /* deallocate element structure */ + act_mem_free_ctx(ctx, el); + rv = TRUE; + break; + } + } + + /* do we need to shrink the table now? */ + if (++(h->h_slack) > ((h->h_pmax + h->h_p) * (MAXLOADFCTR-MINLOADFCTR))) + act_hash_lh_shrink(ctx, h); + + return rv; +} + +/* calculate total size of hash table */ +static int act_hash_lh_size(act_ctx_t *ctx, act_hash_lh_t *h, long *pbytes, long *pelements) +{ + long bytes, elements; + int i, j; + element_t *el; + + /* argument consistency check */ + if (h == NULL) + return_errno(FALSE, EINVAL); + + /* start with 0 bytes and elements */ + bytes = 0; + elements = 0; + + /* add bytes for top-level structure and directory */ + bytes += sizeof(struct act_hash_lh_st); + bytes += h->h_dirsize * sizeof(segment_t *); + + /* add size for segments */ + for (i = 0; i < h->h_dirsize; i++) { + if (h->h_dir[i] == NULL) + continue; + bytes += sizeof(segment_t); + /* add size of elements */ + for (j = 0; j < SEGMENTSIZE; j++) { + if (h->h_dir[i]->s_element[j] == NULL) + continue; + el = h->h_dir[i]->s_element[j]; + for (; el != NULL; el = el->e_next) { + elements++; + /* add size of key+data */ + bytes += sizeof(element_t); + bytes += el_keylen(el); + bytes += el_datlen(el); + } + } + } + + /* provide results */ + if (pbytes != NULL) + *pbytes = bytes; + if (pelements != NULL) + *pelements = elements; + + return TRUE; +} + +/* destroy the whole hash table */ +static int act_hash_lh_free(act_ctx_t *ctx, act_hash_lh_t *h) +{ + element_t *el, **pel; + unsigned int i, j; + + /* argument consistency check */ + if (h == NULL) + return_errno(FALSE, EINVAL); + + /* deallocate all segment's entries */ + for (i = 0; i < h->h_dirsize; i++) { + if (h->h_dir[i] == NULL) + continue; + /* deallocate all collision chains */ + for (j = 0; j < SEGMENTSIZE; j++) { + if (h->h_dir[i]->s_element[j] == NULL) + continue; + /* deallocate all elements in collision chain */ + pel = &h->h_dir[i]->s_element[j]; + for (el = *pel; el != NULL; el = el->e_next) { + /* deallocate key+data memory chunk */ + if (el->e_keyptr != NULL) + act_mem_free_ctx(ctx, el->e_keyptr); + } + } + act_mem_free_ctx(ctx, h->h_dir[i]); + } + + /* deallocate hash table directory */ + act_mem_free_ctx(ctx, h->h_dir); + + /* deallocate hash table top-level structure */ + act_mem_free_ctx(ctx, h); + + return TRUE; +} + +/* the ACT dispatch structure for the hashing API */ +intern act_hash_method_t act_hash_lh = { + ACT_HASH_METHOD_TAG, + (act_hash_new_t) act_hash_lh_new, + (act_hash_insert_t) act_hash_lh_insert, + (act_hash_lookup_t) act_hash_lh_lookup, + (act_hash_delete_t) act_hash_lh_delete, + (act_hash_size_t) act_hash_lh_size, + (act_hash_free_t) act_hash_lh_free +}; + Index: ossp-pkg/act/act_hash_oh.c RCS File: /v/ossp/cvs/ossp-pkg/act/act_hash_oh.c,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_hash_oh.c,v' | diff -u /dev/null - -L'ossp-pkg/act/act_hash_oh.c' 2>/dev/null --- ossp-pkg/act/act_hash_oh.c +++ - 2024-04-24 02:45:08.495045077 +0200 @@ -0,0 +1,177 @@ +/* ==================================================================== + * Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY + * EXPRESSED 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 RALF S. ENGELSCHALL OR + * ITS CONTRIBUTORS 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. + * ==================================================================== + */ + +/* +** act_hash_oh.c -- Open Hashing (static) +** +** This module implements a Static Hash Table, based on the Open +** Hashing algorithm with Double Hashing to solve collisions. That is, +** keys are hased into a static hash table and collisions are solved +** within the table itself. This limits the usage to a fixed set of +** elements, but uses less memory then the Linear Hashing method. +*/ + +#include +#include "act_p.h" + +/* the per-element structure */ +typedef struct element_st element_t; +struct element_st { + element_t *e_next; /* pointer to next element in collision chain */ + unsigned long e_hash; /* cached hash value of element (rehashing optimization) */ + void *e_keyptr; /* pointer to key (= also pointer to key+data memory chunk) */ + void *e_datptr; /* pointer to data in key+data memory chunk */ + void *e_endptr; /* pointer to end of key+data memory chunk */ +}; + +/* the top-level structure */ +typedef struct act_hash_oh_st act_hash_oh_t; +struct act_hash_oh_st { + act_ctx_t *h_ctx; /* context structure */ + act_hash_fct_t h_func; /* hash function (copied from context) */ + int h_size; /* hash table size */ + element_t *h_table; /* hash table */ +}; + +/* create a new hash table */ +static act_hash_oh_t * +act_hash_oh_new( + act_ctx_t *ctx) +{ + act_hash_oh_t *h; + + /* allocate hash structure */ + if ((h = (act_hash_oh_t *)act_mem_alloc_ctx(ctx, sizeof(struct act_hash_oh_st))) == NULL) + return NULL; + h->h_ctx = ctx; + + /* inline values from context (for performance reasons only) */ + if (!act_ctx_get(ctx, ACT_HASH_FUNC, &h->h_func)) + h->h_func = act_hash_fct(djbx33a); + if (!act_ctx_get(ctx, ACT_HASH_TABLESIZE, &h->h_size)) + h->h_size = 128; + + /* allocate and clear hash table */ + if ((h->h_table = (element_t *)act_mem_alloc_ctx(ctx, h->h_size * sizeof(element_t))) == NULL) { + errno_safe( act_mem_free_ctx(ctx, h) ); + return NULL; + } + act_mem_set(h->h_table, 0, h->h_size * sizeof(element_t)); + + return h; +} + +/* insert an element into hash table */ +static int +act_hash_oh_insert( + act_ctx_t *ctx, act_hash_oh_t *h, void *keyptr, int keylen, + void *datptr, int datlen, int override) +{ + return TRUE; +} + +/* lookup an element in hash table */ +static int +act_hash_oh_lookup( + act_ctx_t *ctx, act_hash_oh_t *h, + void *keyptr, int keylen, void **datptr, int *datlen) +{ + return FALSE; +} + +/* delete an element from hash table */ +static int +act_hash_oh_delete( + act_ctx_t *ctx, act_hash_oh_t *h, void *keyptr, int keylen) +{ + return TRUE; +} + +/* find out the size of the hash table */ +static int +act_hash_oh_size( + act_ctx_t *ctx, act_hash_oh_t *h, long *pbytes, long *pelements) +{ + long bytes, elements; + + /* argument consistency check */ + if (h == NULL) + return_errno(FALSE, EINVAL); + + /* start with 0 bytes and elements */ + bytes = 0; + elements = 0; + + /* add bytes for top-level structure and hash table */ + bytes += sizeof(struct act_hash_oh_st); + bytes += h->h_size * sizeof(element_t *); + + /* ...XXX... */ + return TRUE; +} + +/* free the hash table structure */ +static int +act_hash_oh_free( + act_ctx_t *ctx, act_hash_oh_t *h) +{ + unsigned int i; + + /* argument consistency check */ + if (h == NULL) + return_errno(FALSE, EINVAL); + + /* deallocate all segment's entries */ + for (i = 0; i < h->h_size; i++) { + if (h->h_table[i].e_keyptr == NULL) + continue; + act_mem_free_ctx(ctx, h->h_table[i].e_keyptr); + } + + /* deallocate hash table */ + act_mem_free_ctx(ctx, h->h_table); + + /* deallocate hash table top-level structure */ + act_mem_free_ctx(ctx, h); + + return TRUE; +} + +/* the ACT dispatch structure for the hashing API */ +intern act_hash_method_t act_hash_oh = { + ACT_HASH_METHOD_TAG, + (act_hash_new_t) act_hash_oh_new, + (act_hash_insert_t) act_hash_oh_insert, + (act_hash_lookup_t) act_hash_oh_lookup, + (act_hash_delete_t) act_hash_oh_delete, + (act_hash_size_t) act_hash_oh_size, + (act_hash_free_t) act_hash_oh_free +}; + Index: ossp-pkg/act/act_lib.c RCS File: /v/ossp/cvs/ossp-pkg/act/act_lib.c,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_lib.c,v' | diff -u /dev/null - -L'ossp-pkg/act/act_lib.c' 2>/dev/null --- ossp-pkg/act/act_lib.c +++ - 2024-04-24 02:45:08.497704917 +0200 @@ -0,0 +1,24 @@ + +#include "act_p.h" + +int act_init(void) +{ + act_mem_init(); + act_ctx_init(); + act_hash_init(); + return TRUE; +} + +int act_kill(void) +{ + act_hash_kill(); + act_ctx_kill(); + act_mem_kill(); + return TRUE; +} + +long act_version(void) +{ + return ACT_INT_VERSION; +} + Index: ossp-pkg/act/act_mem.c RCS File: /v/ossp/cvs/ossp-pkg/act/act_mem.c,v co -q -kk -p'1.5' '/v/ossp/cvs/ossp-pkg/act/act_mem.c,v' | diff -u /dev/null - -L'ossp-pkg/act/act_mem.c' 2>/dev/null --- ossp-pkg/act/act_mem.c +++ - 2024-04-24 02:45:08.500270057 +0200 @@ -0,0 +1,298 @@ +/* ==================================================================== + * Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY + * EXPRESSED 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 RALF S. ENGELSCHALL OR + * ITS CONTRIBUTORS 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. + * ==================================================================== + */ + +/* +** act_mem.c -- Memory Handling +*/ + +#include +#include + +#include "act_p.h" + +/* the API consists only of indirection pointers */ +void *(*act_mem_alloc)(size_t) = malloc; +void *(*act_mem_realloc)(void *, size_t) = realloc; +void (*act_mem_free)(void *) = free; +void *(*act_mem_dup)(void *, size_t) = _act_mem_dup; +void *(*act_mem_set)(void *, int, size_t) = _act_mem_set; +void *(*act_mem_move)(void *, const void *, size_t) = _act_mem_move; +void *(*act_mem_mem)(const void *, size_t, const void *, size_t) = _act_mem_mem; +void *(*act_mem_char)(const void *, unsigned char, size_t) = _act_mem_char; +int (*act_mem_cmp)(const void *, const void *, size_t) = _act_mem_cmp; + +/* the initialization function for the memory part */ +intern int act_mem_init(void) +{ +#ifdef HAVE_MEMSET + act_mem_set = memset; +#endif +#ifdef HAVE_MEMMOVE + act_mem_move = memmove; +#endif +#ifdef HAVE_MEMCMP + act_mem_cmp = memcmp; +#endif + return TRUE; +} + +/* the destruction function for the memory part */ +intern int act_mem_kill(void) +{ + act_mem_set = _act_mem_set; + act_mem_move = _act_mem_move; + act_mem_cmp = _act_mem_cmp; + return TRUE; +} + +/* local version of a memdup function */ +intern void *_act_mem_dup(void *mem, size_t bytes) +{ + void *dmem; + + if (mem == NULL) + return NULL; + if ((dmem = act_mem_alloc(bytes)) == NULL) + return NULL; + act_mem_move(dmem, mem, bytes); + return dmem; +} + +/* local fallback version of POSIX memset(3) */ +intern void *_act_mem_set(void *dst0, int c0, size_t bytes) +{ + register size_t t; + register unsigned int c; + register unsigned char *dst; + const int word_size = sizeof(unsigned int); + const int word_mask = (sizeof(unsigned int) - 1); + + dst = dst0; + + /* if not enough words for a reasonable speedup, just fill bytes */ + if (bytes < 3 * word_size) { + while (bytes != 0) { + *dst++ = c0; + --bytes; + } + return dst0; + } + + /* fill the whole stamping word */ + if ((c = (unsigned char)c0) != 0) { + c = c | (c << 8); +#if (SIZEOF_INT > 2) + c = c | (c << 16); +#endif +#if (SIZEOF_INT > 4) + c = c | (c << 32); +#endif + } + + /* align destination by filling in bytes */ + if ((t = (long)dst & word_mask) != 0) { + t = word_size - t; + bytes -= t; + do { + *dst++ = c0; + } while (--t != 0); + } + + /* now fill with words. length was >= 2*words so we know t >= 1 here */ + t = bytes / word_size; + do { + *(unsigned int *)dst = c; + dst += word_size; + } while (--t != 0); + + /* finish with trailing bytes, if there are bytes left */ + t = bytes & word_mask; + if (t != 0) { + do { + *dst++ = c0; + } while (--t != 0); + } + + return dst0; +} + +/* local fallback version of POSIX memmove(3) */ +intern void *_act_mem_move(void *dst, const void *src, size_t bytes) +{ + register unsigned char *dst_p; + register const unsigned char *src_p; + + if (src == NULL || dst == NULL) + return NULL; + src_p = src; + dst_p = dst; + if (dst > src) { + /* must go high to low */ + src_p += bytes; + dst_p += bytes; + while (bytes-- > 0) + *--dst_p = *--src_p; + } + else if (dst < src) { + /* must go low to high */ + while (bytes-- > 0) + *dst_p++ = *src_p++; + } + return dst; +} + +/* local fallback version of POSIX memchr(3) */ +intern void *_act_mem_char(const void *src, unsigned char c, size_t bytes) +{ + register const unsigned char *cp; + + if (bytes != 0) { + cp = src; + do { + if (*cp++ == c) + return ((void *)(cp - 1)); + } while (--bytes != 0); + } + return NULL; +} + +/* additional function: memmem(3) like */ +intern void * +_act_mem_mem( + const void *haystack, size_t haystack_len, + const void *needle, size_t needle_len) +{ + register const char *begin; + register const char *last_possible; + + if (needle_len == 0) + /* The first occurrence of the empty string is deemed to occur at + the end of the string. */ + return (void *)&((const char *)haystack)[haystack_len - 1]; + last_possible = (const char *)haystack + haystack_len - needle_len; + for (begin = (const char *)haystack; begin <= last_possible; begin++) + if (*begin == *((const char *)needle) && + act_mem_cmp(&begin[1], (const char *)needle + 1, needle_len - 1) == 0) + + return (void *)begin; + return NULL; +} + +/* local fallback version of POSIX memcmp(3) */ +intern int _act_mem_cmp(const void *src1, const void *src2, size_t bytes) +{ + register const unsigned char *cp1; + register const unsigned char *cp2; + + if (bytes != 0) { + cp1 = src1; + cp2 = src2; + do { + if (*cp1++ != *cp2++) + return (*--cp1 - *--cp2); + } while (--bytes != 0); + } + return 0; +} + +/* special utility function: a variant of act_mem_alloc() via a context */ +void *act_mem_alloc_ctx(act_ctx_t *ctx, size_t size) +{ + void *fct = NULL; + void *ctxarg = NULL; + int ctxuse = FALSE; + void *rv = NULL; + + if (ctx == NULL) + return NULL; + act_ctx_get(ctx, ACT_CTX_MEM_ALLOC, &fct); + if (fct == NULL) + fct = (void *)act_mem_alloc; + else { + act_ctx_get(ctx, ACT_CTX_MEM_CTXUSE, &ctxuse); + if (ctxuse) + act_ctx_get(ctx, ACT_CTX_MEM_CTXARG, &ctxarg); + } + if (ctxuse) + rv = ((act_mem_alloc_ctx_t)fct)(ctxarg, size); + else + rv = ((act_mem_alloc_t)fct)(size); + return rv; +} + +/* special utility function: a variant of act_mem_realloc() via a context */ +void *act_mem_realloc_ctx(act_ctx_t *ctx, void *ptr, size_t size) +{ + void *fct = NULL; + void *ctxarg = NULL; + int ctxuse = FALSE; + void *rv = NULL; + + if (ctx == NULL) + return NULL; + act_ctx_get(ctx, ACT_CTX_MEM_REALLOC, &fct); + if (fct == NULL) + fct = (void *)act_mem_realloc; + else { + act_ctx_get(ctx, ACT_CTX_MEM_CTXUSE, &ctxuse); + if (ctxuse) + act_ctx_get(ctx, ACT_CTX_MEM_CTXARG, &ctxarg); + } + if (ctxuse) + rv = ((act_mem_realloc_ctx_t)fct)(ctxarg, ptr, size); + else + rv = ((act_mem_realloc_t)fct)(ptr, size); + return rv; +} + +/* special utility function: a variant of act_mem_free() via a context */ +void act_mem_free_ctx(act_ctx_t *ctx, void *ptr) +{ + void *fct = NULL; + void *ctxarg = NULL; + int ctxuse = FALSE; + + if (ctx == NULL) + return; + act_ctx_get(ctx, ACT_CTX_MEM_FREE, &fct); + if (fct == NULL) + fct = (void *)act_mem_free; + else { + act_ctx_get(ctx, ACT_CTX_MEM_CTXUSE, &ctxuse); + if (ctxuse) + act_ctx_get(ctx, ACT_CTX_MEM_CTXARG, &ctxarg); + } + if (ctxuse) + ((act_mem_free_ctx_t)fct)(ctxarg, ptr); + else + ((act_mem_free_t)fct)(ptr); + return; +} + Index: ossp-pkg/act/act_mem.h RCS File: /v/ossp/cvs/ossp-pkg/act/act_mem.h,v co -q -kk -p'1.3' '/v/ossp/cvs/ossp-pkg/act/act_mem.h,v' | diff -u /dev/null - -L'ossp-pkg/act/act_mem.h' 2>/dev/null --- ossp-pkg/act/act_mem.h +++ - 2024-04-24 02:45:08.503003437 +0200 @@ -0,0 +1,67 @@ +/* ==================================================================== + * Copyright (c) 1999-2000 Ralf S. Engelschall. 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 RALF S. ENGELSCHALL ``AS IS'' AND ANY + * EXPRESSED 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 RALF S. ENGELSCHALL OR + * ITS CONTRIBUTORS 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. + * ==================================================================== + */ + +/* +** act_mem.h -- Memory Handling +*/ + +#ifndef _ACT_MEM_H_ +#define _ACT_MEM_H_ + +extern void *(*act_mem_alloc)(size_t); +extern void *(*act_mem_realloc)(void *, size_t); +extern void (*act_mem_free)(void *); + +extern void *(*act_mem_dup)(void *, size_t); +extern void *(*act_mem_set)(void *, int, size_t); +extern void *(*act_mem_move)(void *, const void *, size_t); +extern void *(*act_mem_char)(const void *, unsigned char, size_t); +extern void *(*act_mem_mem)(const void *, size_t, const void *, size_t); +extern int (*act_mem_cmp)(const void *, const void *, size_t); + +extern void *act_mem_alloc_ctx(act_ctx_t *, size_t); +extern void *act_mem_realloc_ctx(act_ctx_t *, void *, size_t); +extern void act_mem_free_ctx(act_ctx_t *, void *); + +typedef void *(*act_mem_alloc_t)(size_t); +typedef void *(*act_mem_realloc_t)(void *, size_t); +typedef void (*act_mem_free_t)(void *); +typedef void *(*act_mem_alloc_ctx_t)(void *, size_t); +typedef void *(*act_mem_realloc_ctx_t)(void *, void *, size_t); +typedef void (*act_mem_free_ctx_t)(void *, void *); + +#define ACT_CTX_MEM_ALLOC ACT_CTX_ID(ptr,MEM,0) +#define ACT_CTX_MEM_REALLOC ACT_CTX_ID(ptr,MEM,1) +#define ACT_CTX_MEM_FREE ACT_CTX_ID(ptr,MEM,2) +#define ACT_CTX_MEM_CTXARG ACT_CTX_ID(ptr,MEM,3) +#define ACT_CTX_MEM_CTXUSE ACT_CTX_ID(int,MEM,4) + +#endif /* _ACT_MEM_H_ */ + Index: ossp-pkg/act/act_p.h.in RCS File: /v/ossp/cvs/ossp-pkg/act/act_p.h.in,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/act_p.h.in,v' | diff -u /dev/null - -L'ossp-pkg/act/act_p.h.in' 2>/dev/null --- ossp-pkg/act/act_p.h.in +++ - 2024-04-24 02:45:08.505585913 +0200 @@ -0,0 +1,42 @@ +#ifndef _ACT_P_H_ +#define _ACT_P_H_ + +#include +#include +#include +#include +#include + +/* library version */ +#define _ACT_VERS_C_AS_HEADER_ +#include "act_vers.c" +#undef _ACT_VERS_C_AS_HEADER_ + +/* temporarily preserve and restore errno */ +#define errno_preserve \ + do { pth_errno_storage = errno; } while (0) +#define errno_restore \ + do { errno = pth_errno_storage; } while (0) +#define errno_safe(cmd) \ + do { int __local_errno = errno; cmd; errno = __local_errno; } while (0) +#define return_errno(return_val,errno_val) \ + do { errno = (errno_val); return (return_val); } while (0) + +#include "act_cfg.h" +#include "act_lib.h" +#include "act_ctx.h" +#include "act_mem.h" +#include "act_hash.h" + +#define insist(expr,false) if (!(expr)) return false + +/* compiler happyness: avoid ``empty compilation unit'' problem */ +#define COMPILER_HAPPYNESS(name) \ + int __##name##_unit = 0; + +/* generated contents */ +BEGIN_DECLARATION +==#== +END_DECLARATION + +#endif /* _ACT_P_H_ */ Index: ossp-pkg/act/configure.in RCS File: /v/ossp/cvs/ossp-pkg/act/Attic/configure.in,v co -q -kk -p'1.2' '/v/ossp/cvs/ossp-pkg/act/Attic/configure.in,v' | diff -u /dev/null - -L'ossp-pkg/act/configure.in' 2>/dev/null --- ossp-pkg/act/configure.in +++ - 2024-04-24 02:45:08.508175971 +0200 @@ -0,0 +1,100 @@ +dnl ## +dnl ## Autoconf specification for ACT library +dnl ## + +AC_PREREQ(2.12)dnl +AC_REVISION($Revision$) + +AC_INIT(README) +AC_HEADLINE(dnl +ACT, Abstract Container Types, dnl +ACT_VERSION, act_vers.c, dnl +[Copyright (c) 1999-2000 Ralf S. Engelschall ]) +AC_PREFIX_DEFAULT(/usr/local) +AC_CONFIG_HEADER(act_cfg.h) + +AC_SET_MAKE +AC_PROG_CC +AC_PROG_CPP +AC_CHECK_PROG(AR, ar, ar) +AC_PROG_RANLIB + +AC_MSG_CHECKING(whether to build with debugging) +AC_ARG_ENABLE(debug,dnl +[ --enable-debug build with debugging (default=no)], +enable_debug="$enableval", +if test ".$enable_debug" = .; then + enable_debug=no +fi +)dnl +if test ".$enable_debug" = .yes; then + CFLAGS="$CFLAGS -ggdb3" + CFLAGS="$CFLAGS -pedantic" + CFLAGS="$CFLAGS -Wall -Wshadow -Wpointer-arith -Wcast-align" + CFLAGS="$CFLAGS -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline" + CFLAGS="$CFLAGS -Wno-long-long" +fi +AC_MSG_RESULT([$enable_debug]) + +AC_MSG_CHECKING(for compilation profile mode) +AC_ARG_ENABLE(profile,dnl +[ --enable-profile build for profiling (default=no)], +[dnl +if test ".$ac_cv_prog_gcc" = ".no"; then + AC_MSG_ERROR([profiling requires gcc and gprof]) +fi +CFLAGS=`echo "$CFLAGS" | sed -e 's/-O2//g'` +CFLAGS="$CFLAGS -O0 -pg" +LDFLAGS="$LDFLAGS -pg" +msg="enabled" +],[ +msg="disabled" +])dnl +AC_MSG_RESULT([$msg]) + +AC_HAVE_FUNCS(memset memmove memcmp) +AC_CHECK_SIZEOF(char, 1) +AC_CHECK_SIZEOF(short, 2) +AC_CHECK_SIZEOF(int, 4) +AC_CHECK_SIZEOF(long, 4) +AC_CHECK_SIZEOF(long long, 8) + +HAVE_ACT_UINT8_T="#define HAVE_ACT_UINT8_T"; +HAVE_ACT_UINT16_T="#define HAVE_ACT_UINT16_T"; +HAVE_ACT_UINT32_T="#define HAVE_ACT_UINT32_T"; +HAVE_ACT_UINT64_T="#define HAVE_ACT_UINT64_T"; +HAVE_ACT_SIZE_T="#define HAVE_ACT_SIZE_T"; +AC_SUBST(HAVE_ACT_UINT8_T) +AC_SUBST(HAVE_ACT_UINT16_T) +AC_SUBST(HAVE_ACT_UINT32_T) +AC_SUBST(HAVE_ACT_UINT64_T) +AC_SUBST(HAVE_ACT_SIZE_T) +ACT_UINT8_T="unsigned char"; +ACT_UINT16_T="unsigned short"; +ACT_UINT32_T="unsigned long"; +ACT_UINT64_T="unsigned long long"; +ACT_SIZE_T="unsigned int"; +AC_SUBST(ACT_UINT8_T) +AC_SUBST(ACT_UINT16_T) +AC_SUBST(ACT_UINT32_T) +AC_SUBST(ACT_UINT64_T) +AC_SUBST(ACT_SIZE_T) + +dnl AC_TRY_RUN([ +dnl #include +dnl #include +dnl #include +dnl main() +dnl { + dnl long long n = 1; + dnl if (sizeof(long long) >= 8) + dnl + dnl exit(0) +dnl } +dnl ], + +AC_OUTPUT(dnl +Makefile dnl +act.h dnl +)dnl +