/* ** OSSP act - Abstract Container Types ** Copyright (c) 1999-2003 Ralf S. Engelschall ** Copyright (c) 1999-2003 The OSSP Project ** ** This file is part of OSSP act, an abstract container type library ** which can be found at http://www.ossp.org/pkg/lib/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_ds.c: data structure low-level API (implementation) */ #include "act_p.h" #include "act_ds.h" /* the generic top-level data structure for a ds */ struct act_ds_st { act_ctx_t *ds_ctx; /* the attached ACT context */ act_ds_method_t *ds_method; /* the dsing method which is actually used */ void *ds_data; /* the data structure */ }; /* convinience macro for calling a method */ #define method(ds,name) ds->ds_method->m_##name /* global initialization at library startup time */ intern int act_ds_init(void) { act_ctx_set(act_ctx_default, ACT_HASH_METHOD, act_ds_mth(lh)); act_ctx_set(act_ctx_default, ACT_HASH_FUNC, act_ds_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_ds_kill(void) { return TRUE; } /* create a new ds */ act_ds_t *act_ds_new(act_ctx_t *ctx) { act_ds_t *h; act_ds_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 ds */ data = method->m_new(ctx); insist(data != NULL, NULL); /* allocate a top-level data structure */ if ((h = (act_ds_t *)act_mem_alloc_ctx(ctx, sizeof(act_ds_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_ds_ctx(act_ds_t *h) { insist(h != NULL, NULL); return h->h_ctx; } /* destroy the ds */ int act_ds_free(act_ds_t *h) { insist(h != NULL, NULL); /* destroy real ds 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 ds */ int act_ds_insert(act_ds_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 ds */ int act_ds_lookup(act_ds_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 ds */ int act_ds_delete(act_ds_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 ds */ int act_ds_size(act_ds_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_ds_status(act_ds_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); }