[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_svc/snap_svc_memmap_hash.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_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 } |