9#define OA_HASH_API static
11#define OA_HASH_API extern
33#define __OA_HASH_ATTRS_const \
34 const size_t length; \
35 const size_t capacity; \
36 const struct oa_hash_entry *buckets
37#define __OA_HASH_ATTRS_mut \
40 struct oa_hash_entry *buckets
42#define OA_HASH_ATTRS(_qualifier) __OA_HASH_ATTRS_##_qualifier
58 const size_t capacity);
76 const struct oa_hash *ht,
const char key[],
const size_t len);
143 const size_t new_capacity);
145#ifndef OA_HASH_HEADER
153 const size_t capacity)
172_oa_hash_genhash(
const char key[],
size_t len,
const size_t capacity)
174 const unsigned char *str = (
const unsigned char *)
key;
175 unsigned long hash = 5381;
177 if (!
key || !capacity)
return 0;
180 hash = ((hash & 0x7fffffff) << 5) + hash + *str++;
182 return hash % capacity;
188 const size_t start_slot = _oa_hash_genhash(
key, len, ht->
capacity);
189 size_t slot = start_slot;
191 if (!len || !ht->
capacity)
return NULL;
201 && 0 == memcmp(entry->
key.
buf,
key, len))
207 }
while (slot != start_slot);
216 return entry ? entry->
value : NULL;
225 const size_t start_slot = _oa_hash_genhash(
key, len, ht->
capacity);
226 size_t slot = start_slot;
227 size_t first_deleted = SIZE_MAX;
229 if (!len || !ht->
capacity)
return NULL;
235 if (first_deleted == SIZE_MAX
238 first_deleted = slot;
241 slot = (first_deleted != SIZE_MAX) ? first_deleted : slot;
253 && 0 == memcmp(entry->
key.
buf,
key, len))
260 }
while (slot != start_slot);
272 return entry ? entry->
value : NULL;
278 const size_t start_slot = _oa_hash_genhash(
key, len, ht->
capacity);
279 size_t slot = start_slot;
281 if (!len || !ht->
capacity)
return 0;
291 && 0 == memcmp(entry->
key.
buf,
key, len))
299 }
while (slot != start_slot);
307 const size_t new_capacity)
310 const size_t old_capacity = ht->
capacity;
311 const size_t old_length = ht->
length;
314 if (!new_buckets || new_capacity <= old_capacity)
return 0;
316 memset(new_buckets, 0,
sizeof(
struct oa_hash_entry) * new_capacity);
323 for (i = 0; i < old_capacity; ++i) {
327 old_buckets[i].
value))
const struct oa_hash_entry * oa_hash_set_entry(struct oa_hash *ht, const char key[], const size_t len, void *value)
Insert or update entry.
Definition: oa_hash.h:220
struct oa_hash_entry * oa_hash_rehash(struct oa_hash *ht, struct oa_hash_entry new_buckets[], const size_t new_capacity)
Rehash table to new buckets array.
Definition: oa_hash.h:305
void * oa_hash_set(struct oa_hash *ht, const char key[], const size_t len, void *value)
Insert or update entry (wrapper around oa_hash_set_entry)
Definition: oa_hash.h:266
void * oa_hash_get(const struct oa_hash *ht, const char key[], const size_t len)
Retrieve value by key (wrapper around oa_hash_get_entry)
Definition: oa_hash.h:213
void oa_hash_cleanup(struct oa_hash *ht)
Clean up hash table entries and struct.
Definition: oa_hash.h:162
oa_hash_entry_state
Hash table entry state.
Definition: oa_hash.h:17
@ OA_HASH_ENTRY_EMPTY
Definition: oa_hash.h:18
@ OA_HASH_ENTRY_OCCUPIED
Definition: oa_hash.h:19
@ OA_HASH_ENTRY_DELETED
Definition: oa_hash.h:20
#define OA_HASH_ATTRS(_qualifier)
can be used to cast to struct oa_hash
Definition: oa_hash.h:42
#define OA_HASH_API
Definition: oa_hash.h:11
int oa_hash_remove(struct oa_hash *ht, const char key[], const size_t len)
Remove entry by key.
Definition: oa_hash.h:276
void oa_hash_init(struct oa_hash *ht, struct oa_hash_entry buckets[], const size_t capacity)
Initialize hash table with given buckets array.
Definition: oa_hash.h:151
const struct oa_hash_entry * oa_hash_get_entry(const struct oa_hash *ht, const char key[], const size_t len)
Retrieve entry by key.
Definition: oa_hash.h:186
Entry holding key-value pair in hash table.
Definition: oa_hash.h:24
void * value
Definition: oa_hash.h:30
size_t length
Definition: oa_hash.h:28
enum oa_hash_entry_state state
Definition: oa_hash.h:25
struct oa_hash_entry::@14 key
const char * buf
Definition: oa_hash.h:27
Open addressing hash table.
Definition: oa_hash.h:45
struct oa_hash_entry * buckets
Definition: oa_hash.h:46
size_t length
Definition: oa_hash.h:46
size_t capacity
Definition: oa_hash.h:46