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