hashtab.h

Go to the documentation of this file.
00001 /* TinyaML
00002  * Copyright (C) 2007 Damien Leroux
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017  */
00018 
00019 #ifndef _HASH_H
00020 #define _HASH_H
00021 
00022 #include <stdlib.h>
00023 
00029 #define HASH_SIZE 137
00030 
00031 typedef struct _htab_entry_struct *htab_entry_t;
00032 
00033 typedef struct _htab_iterator *htab_iterator_t;
00034 
00035 typedef struct _hashtab_t* hashtab_t;
00036 
00037 typedef void* hash_elem;
00038 typedef void* hash_key;
00039 
00040 typedef word_t (*hash_func)(hash_key);
00041 typedef int (*compare_func)(hash_key,hash_key);
00042 
00043 struct _htab_entry_struct {
00044         hash_key key;
00045         hash_elem e;
00046         htab_entry_t next;
00047         word_t __pad;
00048 };
00049 
00050 
00051 
00052 struct _hashtab_t {
00053         htab_entry_t table[HASH_SIZE];
00054         hash_func hash;
00055         compare_func keycmp;
00056 };
00057 
00058 
00059 #define HASH_NOVAL ((hash_elem)0)
00060 
00061 
00062 word_t default_hash_func(const char*);
00063 
00064 word_t hash_str(char*);
00065 /*int strcmp(const char*,const char*);*/
00066 word_t hash_ptr(void*);
00067 int cmp_ptr(void*,void*);
00068 
00074 struct _htab_iterator {
00075         hashtab_t tab;
00076         word_t row;
00077         struct _htab_entry_struct*entry;
00078 };
00079 
00081 static __inline int hi_incr(htab_iterator_t hi) {
00082         if(hi->entry&&hi->entry->next)
00083                 hi->entry=hi->entry->next;
00084         do {
00085                 ++hi->row;
00086                 if(hi->row>=HASH_SIZE) {
00087                         hi->entry=NULL;
00088                         return 0;
00089                 }
00090         } while(!hi->tab->table[hi->row]);
00091         hi->entry = hi->tab->table[hi->row];
00092         return 1;
00093 }
00094 
00095 
00097 static __inline void hi_init(htab_iterator_t hi,hashtab_t t) {
00098         hi->tab=t;
00099         hi->row=(word_t)-1;
00100         hi->entry=NULL;
00101         hi_incr(hi);
00102 }
00103 
00104 
00106 static __inline int hi_is_valid(htab_iterator_t hi) { return hi->entry!=NULL; }
00107 
00109 static __inline hash_key hi_key(htab_iterator_t hi) { return hi->entry->key; }
00110 
00112 static __inline hash_elem hi_value(htab_iterator_t hi) { return hi->entry->e; }
00113 
00115 static __inline htab_entry_t hi_entry(htab_iterator_t hi) { return hi->entry; }
00116 
00127 static __inline void init_hashtab(hashtab_t tab,hash_func hash,compare_func cmp) {
00128         int i;
00129         for(i=0;i<HASH_SIZE;i++)
00130                 tab->table[i]=(htab_entry_t) HASH_NOVAL;
00131         tab->hash=hash;
00132         tab->keycmp=cmp;
00133 }
00134 
00135 
00136 
00138 static __inline void hash_addelem(hashtab_t tab,hash_key key,hash_elem elem) {
00139         word_t i=tab->hash(key);
00140 /*      TRACE(&quot;HASH_ADDELEM [%X]`%s' [%X] hashed as %u\n&quot;,key,key,elem,i); */
00141         /*htab_entry e=(htab_entry )alloc_node(1);*/
00142         htab_entry_t e=(htab_entry_t)malloc(sizeof(struct _htab_entry_struct));
00143 /*      TRACE(&quot;  %ssuccessfully alloc'ed node\n&quot;,e?&quot;&quot;:&quot;un&quot;); */
00144         if(!e) return;
00145         e->next=tab->table[i];
00146         e->key=key;
00147         e->e=elem;
00148         tab->table[i]=e;
00149 }
00150 
00151 
00152 
00154 static __inline htab_entry_t hash_find_e(hashtab_t tab,hash_key key) {
00155         int i=tab->hash(key);
00156         htab_entry_t s=tab->table[i];
00157 /*      TRACE(&quot;      HASH_FINDELEM [%X]`%s' hashed as %u [%X]\n&quot;,key,key,i,s); */
00158         if(s) while(tab->keycmp(s->key,key)&&(s=s->next));
00159         return s;
00160 }
00161 
00163 static __inline hash_elem hash_find(hashtab_t tab,hash_key key) {
00164         htab_entry_t s;
00165 /*      TRACE(&quot;   calling hash_find with [%X]`%s'\n&quot;,key,key); */
00166         s=hash_find_e(tab,key);
00167         if(s) return s->e;
00168         return HASH_NOVAL;
00169 }
00170 
00171 
00173 static __inline void hash_delelem(hashtab_t tab,hash_key key) {
00174         htab_entry_t p=NULL;
00175         word_t i=tab->hash(key);
00176 /*      TRACE(&quot;CALLING HASH_DELELEM !!\n&quot;); */
00177         htab_entry_t s=tab->table[i];
00178         while(s&&tab->keycmp(s->key,key)) {
00179                 p=s;
00180                 s=s->next;
00181         }
00182         if(s) {
00183                 if(p) p->next=s->next;
00184                 else tab->table[i]=s->next;
00185                 /*free_node((nep_mem_node*)s,1);*/
00186                 free(s);
00187         }
00188 }
00189 
00191 static __inline void clean_hashtab(hashtab_t tab,void(*callback)(htab_entry_t)) {
00192         int i;
00193         htab_entry_t s,p;
00194         for(i=0;i<HASH_SIZE;i++) {
00195                 s=tab->table[i];
00196                 while(s) {
00197                         p=s;
00198                         s=s->next;
00199                         /*free_node((nep_mem_node*)p,1);*/
00200                         if(callback) callback(p);
00201                         free(p);
00202                 }
00203                 tab->table[i]=(htab_entry_t)HASH_NOVAL;
00204         }
00205 }
00206 
00209 #endif
00210 

Generated on Wed Feb 6 14:46:04 2008 for TinyaML by  doxygen 1.5.3