hashtable.h

Go to the documentation of this file.
00001 
00057 /*#*
00058  *#* $Log$
00059  *#* Revision 1.8  2006/07/19 12:56:27  bernie
00060  *#* Convert to new Doxygen style.
00061  *#*
00062  *#* Revision 1.7  2006/06/01 12:27:39  marco
00063  *#* Added utilities for protocols
00064  *#*
00065  *#*/
00066 
00067 #ifndef MWARE_HASHTABLE_H
00068 #define MWARE_HASHTABLE_H
00069 
00070 #include <cfg/compiler.h>
00071 #include <cfg/macros.h>
00072 #include <cfg/debug.h>
00073 
00078 #define CONFIG_HT_OPTIONAL_INTERNAL_KEY      1
00079 
00081 #define INTERNAL_KEY_MAX_LENGTH     15
00082 
00087 typedef const void *(*hook_get_key)(const void *data, uint8_t *key_length);
00088 
00089 
00100 struct HashTable
00101 {
00102     const void **mem;            
00103     uint16_t max_elts_log2;      
00104     struct {
00105         bool key_internal : 1;   
00106     } flags;
00107     union {
00108         hook_get_key hook;       
00109         uint8_t *mem;            
00110     } key_data;
00111 };
00112 
00113 
00115 typedef struct
00116 {
00117     const void** pos;
00118     const void** end;
00119 } HashIterator;
00120 
00121 
00133 #define DECLARE_HASHTABLE(name, size, hook_gk) \
00134     static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
00135     struct HashTable name = { name##_nodes, UINT32_LOG2(size), { false }, hook_gk }
00136 
00138 #define DECLARE_HASHTABLE_STATIC(name, size, hook_gk) \
00139     static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
00140     static struct HashTable name = { name##_nodes, UINT32_LOG2(size), { false }, { hook_gk } }
00141 
00142 #if CONFIG_HT_OPTIONAL_INTERNAL_KEY
00143 
00148     #define DECLARE_HASHTABLE_INTERNALKEY(name, size) \
00149         static uint8_t name##_keys[(1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)]; \
00150         static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
00151         struct HashTable name = { name##_nodes, UINT32_LOG2(size), { true }, name##_keys }
00152 
00154     #define DECLARE_HASHTABLE_INTERNALKEY_STATIC(name, size) \
00155         static uint8_t name##_keys[(1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)]; \
00156         static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
00157         static struct HashTable name = { name##_nodes, UINT32_LOG2(size), { true }, name##_keys }
00158 #endif
00159 
00169 void ht_init(struct HashTable* ht);
00170 
00188 bool ht_insert(struct HashTable* ht, const void* data);
00189 
00209 bool ht_insert_with_key(struct HashTable* ht, const void* key, uint8_t key_length, const void* data);
00210 
00219 const void* ht_find(struct HashTable* ht, const void* key, uint8_t key_length);
00220 
00222 #define ht_insert_str(ht, key, data)         ht_insert_with_key(ht, key, strlen(key), data)
00223 
00225 #define ht_find_str(ht, key)                 ht_find(ht, key, strlen(key))
00226 
00228 INLINE HashIterator ht_iter_begin(struct HashTable* ht)
00229 {
00230     HashIterator h;
00231 
00232     h.pos = &ht->mem[0];
00233     h.end = &ht->mem[1 << ht->max_elts_log2];
00234 
00235     while (h.pos != h.end && !*h.pos)
00236         ++h.pos;
00237 
00238     return h;
00239 }
00240 
00248 INLINE HashIterator ht_iter_end(struct HashTable* ht)
00249 {
00250     HashIterator h;
00251 
00252     h.pos = h.end = &ht->mem[1 << ht->max_elts_log2];
00253 
00254     return h;
00255 }
00256 
00258 INLINE bool ht_iter_cmp(HashIterator it1, HashIterator it2)
00259 {
00260     ASSERT(it1.end == it2.end);
00261     return it1.pos == it2.pos;
00262 }
00263 
00265 INLINE const void* ht_iter_get(HashIterator iter)
00266 { return *iter.pos; }
00267 
00274 INLINE HashIterator ht_iter_next(HashIterator h)
00275 {
00276     ++h.pos;
00277     while (h.pos != h.end && !(*h.pos))
00278         ++h.pos;
00279 
00280     return h;
00281 }
00282 
00283 #endif /* MWARE_HASHTABLE_H */