/* ==================================================================== * 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); }