ossp-pkg/act/act_hash.c
/*
** OSSP act - Abstract Container Types
** Copyright (c) 1999-2003 Ralf S. Engelschall <rse@engelschall.com>
** Copyright (c) 1999-2003 The OSSP Project <http://www.ossp.org/>
**
** 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_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);
}