[insert project logo here (125x200px max)]

Navigator

Mailinglists

Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums.

Copyright and Licensing Information

Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL).

All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License.

All sourcecode is made publicly available.

Acknowledgement

Splash and the Splash website are hosted by SourceForge.net

SourceForge.net Logo

osi-open source certified logo

Splash - Documentation

SNMP Plus a Lightweight API for SNAP Handling

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

snap_svc/snap_svc_memmap_hash.c

Go to the documentation of this file.
00001 /* snap-1.0. Copyright (C) 2000 by Jonathan T. Moore and Michael Hicks.
00002  *
00003  * hashtable.c : basic hash table library, used to manage the
00004  *   node-resident service namespace
00005  *
00006  * $Id: snap_svc_memmap_hash.c,v 1.1 2003/04/03 12:42:46 wdebruij Exp $
00007  */
00008 
00009 #include <string.h>
00010 #include <assert.h>
00011 
00012 #include "snap_svc_memmap_hash_list.h"
00013 #include "snap_svc_memmap_hash.h"
00014 #include "d_printf.h"
00015 
00016 /* hash function for the table */
00017 int hash_string(char *s) {
00018   int ans   = 0;
00019   int shift = 0;
00020   int i, sz;
00021 
00022   assert(s != NULL);
00023   sz = strlen(s);
00024 
00025   for(i=0; i < sz; ++i) {
00026     ans = ans ^ (s[i] << shift);
00027     shift += 8;
00028     if(shift == 32)
00029       shift = 0;
00030   }
00031   return ans;
00032 }
00033 
00034 int ht_errno = 0;
00035 static void resize(hash_table_t* t);
00036 
00037 hash_table_t *ht_create(int sz,
00038             int (*cmp)(const void *,const void *),
00039             int (*hash)(void *)) {
00040   hash_table_t *ht = NULL;
00041   list_t **tab = NULL;
00042   int tab_sizeb = sizeof(list_t *)*sz;
00043 
00044 #ifdef __KERNEL__
00045   ht = (hash_table_t *)kmalloc(sizeof(hash_table_t),GFP_ATOMIC);
00046   if (!ht) {
00047     printk(KERN_WARNING "%s:%d: kmalloc failed\n",__FILE__,__LINE__);
00048     return NULL;
00049   }
00050   tab = (list_t **)kmalloc(tab_sizeb,GFP_ATOMIC);
00051   if (!tab) {
00052     printk(KERN_WARNING "%s:%d: kmalloc failed\n",__FILE__,__LINE__);
00053     return NULL;
00054   }
00055   memset(tab,0,tab_sizeb);
00056 #else
00057   memalloc(ht,hash_table_t *,sizeof(hash_table_t));
00058   memalloc(tab,list_t **,tab_sizeb);
00059   bzero(tab,tab_sizeb);
00060 #endif /* __KERNEL__ */
00061   ht->cmp = cmp;
00062   ht->hash = hash;
00063   ht->tab = tab;
00064   ht->max_len = 3;
00065   ht->tab_sz = sz;
00066   return ht;
00067 }
00068 
00069 void ht_insert(hash_table_t *t, void *key, void *val) {
00070   list_t **tab;
00071   int bucket;
00072   pair_t *elem;
00073 
00074   assert(t != NULL);
00075 
00076   d_printf(110,"snap_hashtable : inserting key %s\n",(char*) key);
00077   tab = t->tab;
00078   bucket = t->hash(key) % t->tab_sz;
00079 
00080 #ifdef __KERNEL__
00081   elem = (pair_t *)kmalloc(sizeof(pair_t),GFP_ATOMIC);
00082   if (!elem) {
00083     printk(KERN_WARNING "%s:%d: kmalloc failed\n",__FILE__,__LINE__);
00084     return;
00085   }
00086 #else
00087   memalloc(elem,pair_t *,sizeof(pair_t));
00088 #endif /* __KERNEL__ */
00089   elem->key = key;
00090   elem->value = val;
00091 
00092   tab[bucket] = cons(elem,tab[bucket]);
00093   if (length_list (tab[bucket]) > t->max_len) 
00094     resize(t);
00095 }
00096 
00097 static void *assoc_cmp(int (*cmp)(const void *,const void *), 
00098                list_t *list, void *key) {
00099   list_t *iter = list;
00100 
00101   ht_errno = 0;
00102   while (iter != NULL) {
00103     pair_t *elem = (pair_t *)iter->v;
00104     if (!cmp(elem->key,key))
00105       return elem->value;
00106     iter = iter->next;
00107   }
00108   ht_errno = 1; /* didn't find it */
00109   return NULL;
00110 }
00111 
00112 void *ht_lookup(hash_table_t *t, void *key) {
00113   list_t **tab, *l;
00114 
00115   d_printf(110,"snap_hashtable : searching for key %s\n",(char*) key);
00116   
00117   assert(t != NULL);
00118 
00119   tab  = t->tab;
00120   l     = tab[t->hash(key) % t->tab_sz];
00121 
00122   return assoc_cmp(t->cmp, l, key);
00123 }
00124 
00125 void ht_remove(hash_table_t * t, void *key) {
00126   int     bucket;
00127   list_t *l, *prev;
00128   pair_t *elem;
00129 
00130   assert(t != NULL);
00131 
00132   bucket   = t->hash(key) % t->tab_sz;
00133   l        = t->tab[bucket];
00134   if(l == NULL)
00135     return;
00136 
00137   elem = (pair_t *)l->v;
00138   if(t->cmp(key,elem->key)==0) {
00139     t->tab[bucket] = l->next;
00140     free(elem->key);
00141     free(elem);
00142     return;
00143   }
00144   prev = l; l = l->next;
00145   for(; l->next != NULL; prev = l, l=l->next) {
00146     elem = (pair_t *)l->v;
00147     if(t->cmp(key,elem->key)==0) {
00148       prev->next = l->next;
00149       free(elem->key);
00150       free(elem);
00151       return;
00152     }
00153   }
00154 }
00155 
00156 /* For resizing */
00157 static void insert_bucket(list_t **tab, int tab_sz,
00158               int (*hash)(void *), list_t *elems) {
00159   pair_t *elem;
00160   int nidx;
00161 
00162   assert(tab != NULL);
00163   assert(tab_sz > 0);
00164 
00165   if (elems == NULL) return;
00166   insert_bucket(tab,tab_sz,hash,elems->next); // preserve the original order
00167 #ifdef __KERNEL__
00168   elem = (pair_t *)kmalloc(sizeof(pair_t),GFP_ATOMIC);
00169   if (!elem) {
00170     printk(KERN_WARNING "%s:%d: kmalloc failed\n",__FILE__,__LINE__);
00171     return;
00172   }
00173 #else
00174   memalloc(elem,pair_t *,sizeof(pair_t));
00175 #endif /* __KERNEL__ */
00176   elem->key = ((pair_t *)(elems->v))->key;
00177   elem->value = ((pair_t *)(elems->v))->value;
00178   nidx = hash(elem->key) % tab_sz;
00179   tab[nidx] = cons(elem,tab[nidx]);
00180 }
00181 
00182 static void resize(hash_table_t *t) {
00183   list_t **odata, **ndata;
00184   int osize, nsize, ndata_sizeb;
00185   int i;
00186 
00187   assert(t != NULL);
00188 
00189   odata  = t->tab;
00190   osize       = t->tab_sz;
00191   nsize       = 2 * osize + 1;
00192   ndata_sizeb = sizeof(list_t *)*nsize;
00193 
00194 #ifdef __KERNEL__
00195   ndata = (list_t **)kmalloc(ndata_sizeb,GFP_ATOMIC);
00196   if (!ndata) {
00197     printk(KERN_WARNING "%s:%d: kmalloc failed\n",__FILE__,__LINE__);
00198     return;
00199   }
00200   memset(ndata,0,ndata_sizeb);
00201 #else
00202   memalloc(ndata,list_t **,ndata_sizeb);
00203   bzero(ndata,ndata_sizeb);
00204 #endif /* __KERNEL__ */
00205 
00206   for (i = 0; i<osize; i++)
00207     insert_bucket(ndata,t->tab_sz,t->hash,odata[i]);
00208   t->tab = ndata;
00209   t->max_len = 2 * t->max_len;
00210 }