#ifndef HSHTB_H_ #define HSHTB_H_ #include #include #include #define HSHTB_FNV32_BASE 0x811c9dc5 static inline uint32_t hshtb_fnv32(char *s, size_t len) { uint32_t h = HSHTB_FNV32_BASE; for (size_t i = 0; i < len; i++) { h ^= s[i]; h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24); } return h >> 8; } #define HSHTB_ALLOC(tb, name, k, keyname, out) \ do { \ size_t len = sizeof((tb)->name) / sizeof((tb)->name[0]); \ size_t idx = hshtb_fnv32(k, hal_strlen(k)) % len; \ size_t i = idx; \ do { \ if (!(tb)->name[i].taken) { \ (out) = &((tb)->name[i]); \ hal_memset((out), 0, sizeof(*(out))); \ (out)->taken = true; \ hal_memcpy((out)->keyname, k, hal_strlen(k)); \ break; \ } \ i = (i + 1) % len; \ } while(i != idx); \ } while(0) #define HSHTB_GET(tb, name, k, keyname, out) \ do { \ size_t len = sizeof((tb)->name) / sizeof((tb)->name[0]); \ size_t idx = hshtb_fnv32(k, hal_strlen(k)) % len; \ size_t i = idx; \ do { \ if (hal_memcmp((tb)->name[i].keyname, k, hal_strlen(k)) == 0) { \ (out) = &((tb)->name[i]); \ break; \ } \ i = (i + 1) % len; \ } while(i != idx); \ } while(0) #endif // HSHTB_H_