hashtable.h
Go to the documentation of this file.00001
00061 #ifndef STRUCT_HASHTABLE_H
00062 #define STRUCT_HASHTABLE_H
00063
00064 #include "cfg/cfg_hashtable.h"
00065
00066 #include <cfg/compiler.h>
00067 #include <cfg/macros.h>
00068 #include <cfg/debug.h>
00069
00071 #define INTERNAL_KEY_MAX_LENGTH 15
00072
00077 typedef const void *(*hook_get_key)(const void *data, uint8_t *key_length);
00078
00079
00090 struct HashTable
00091 {
00092 const void **mem;
00093 uint16_t max_elts_log2;
00094 struct {
00095 bool key_internal : 1;
00096 } flags;
00097 union {
00098 hook_get_key hook;
00099 uint8_t *mem;
00100 } key_data;
00101 };
00102
00103
00105 typedef struct
00106 {
00107 const void** pos;
00108 const void** end;
00109 } HashIterator;
00110
00111
00123 #define DECLARE_HASHTABLE(name, size, hook_gk) \
00124 static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
00125 struct HashTable name = \
00126 { \
00127 .mem = name##_nodes, \
00128 .max_elts_log2 = UINT32_LOG2(size), \
00129 .flags = { .key_internal = false }, \
00130 .key_data.hook = hook_gk \
00131 }
00132
00133
00135 #define DECLARE_HASHTABLE_STATIC(name, size, hook_gk) \
00136 enum { name##_SIZE = (1 << UINT32_LOG2(size)), }; \
00137 static const void* name##_nodes[name##_SIZE]; \
00138 static struct HashTable name = \
00139 { \
00140 .mem = name##_nodes, \
00141 .max_elts_log2 = UINT32_LOG2(size), \
00142 .flags = { .key_internal = false }, \
00143 .key_data.hook = hook_gk \
00144 }
00145
00146 #if CONFIG_HT_OPTIONAL_INTERNAL_KEY
00147
00152 #define DECLARE_HASHTABLE_INTERNALKEY(name, size) \
00153 static uint8_t name##_keys[(1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)]; \
00154 static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
00155 struct HashTable name = { name##_nodes, UINT32_LOG2(size), { true }, name##_keys }
00156
00158 #define DECLARE_HASHTABLE_INTERNALKEY_STATIC(name, size) \
00159 enum { name##_KEYS = ((1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)), \
00160 name##_SIZE = (1 << UINT32_LOG2(size)), }; \
00161 static uint8_t name##_keys[name##_KEYS]; \
00162 static const void* name##_nodes[name##_SIZE]; \
00163 static struct HashTable name = \
00164 { \
00165 .mem = name##_nodes, \
00166 .max_elts_log2 = UINT32_LOG2(size), \
00167 .flags = { .key_internal = true }, \
00168 .key_data.mem = name##_keys \
00169 }
00170 #endif
00171
00181 void ht_init(struct HashTable* ht);
00182
00200 bool ht_insert(struct HashTable* ht, const void* data);
00201
00221 bool ht_insert_with_key(struct HashTable* ht, const void* key, uint8_t key_length, const void* data);
00222
00231 const void* ht_find(struct HashTable* ht, const void* key, uint8_t key_length);
00232
00234 #define ht_insert_str(ht, key, data) ht_insert_with_key(ht, key, strlen(key), data)
00235
00237 #define ht_find_str(ht, key) ht_find(ht, key, strlen(key))
00238
00240 INLINE HashIterator ht_iter_begin(struct HashTable* ht)
00241 {
00242 HashIterator h;
00243
00244 h.pos = &ht->mem[0];
00245 h.end = &ht->mem[1 << ht->max_elts_log2];
00246
00247 while (h.pos != h.end && !*h.pos)
00248 ++h.pos;
00249
00250 return h;
00251 }
00252
00260 INLINE HashIterator ht_iter_end(struct HashTable* ht)
00261 {
00262 HashIterator h;
00263
00264 h.pos = h.end = &ht->mem[1 << ht->max_elts_log2];
00265
00266 return h;
00267 }
00268
00270 INLINE bool ht_iter_cmp(HashIterator it1, HashIterator it2)
00271 {
00272 ASSERT(it1.end == it2.end);
00273 return it1.pos == it2.pos;
00274 }
00275
00277 INLINE const void* ht_iter_get(HashIterator iter)
00278 { return *iter.pos; }
00279
00286 INLINE HashIterator ht_iter_next(HashIterator h)
00287 {
00288 ++h.pos;
00289 while (h.pos != h.end && !(*h.pos))
00290 ++h.pos;
00291
00292 return h;
00293 }
00294
00295 int hashtable_testSetup(void);
00296 int hashtable_testRun(void);
00297 int hashtable_testTearDown(void);
00298
00300
00301 #endif