/* ** Act - Abstract Container Type Library ** Copyright (c) 1999-2001 Ralf S. Engelschall ** ** This file is part of Act, a library for dealing with Abstract ** Container Types which can be found at http://www.ossp.org/pkg/act/. ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``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 THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** 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 API (implementation) */ #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_ctx(ctx, 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); insist(pb != NULL, NULL); insist(pe != NULL, NULL); return method(h, size)(h->h_ctx, h->h_data, pb, pe); } /* return summary of current internal status */ int act_hash_status(act_hash_t *h, char *ps, int ns) { insist(h != NULL, NULL); insist(ps != NULL, NULL); insist(ns > 0, NULL); return method(h, status)(h->h_ctx, h->h_data, ps, ns); }