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 // \defgroup hashtable 00300 00301 #endif /* STRUCT_HASHTABLE_H */
![(please configure the [header_logo] section in trac.ini)](/chrome/site/bertos_logo.png)