#ifndef _KERNEL_LIBK_HASH_H #define _KERNEL_LIBK_HASH_H #include struct hash_node_link { struct hash_node_link* next; uint32_t hash; }; #define hash_entry(ptr, type, member) ((type*)((char*)(ptr) - offsetof (type, member))) static inline uint32_t hash_fnv32 (const void* data, size_t len) { uint32_t hash = 2166136261U; const uint8_t* bp = (const uint8_t*)data; const uint8_t* be = bp + len; while (bp < be) { hash ^= (uint32_t)*bp++; hash *= 16777619U; } return hash; } #define hash_insert(table, new_link, hash_val, table_size, buckets_name) \ do { \ uint32_t __idx = (hash_val) % (table_size); \ (new_link)->hash = (hash_val); \ (new_link)->next = (table)->buckets_name[__idx]; \ (table)->buckets_name[__idx] = (new_link); \ } while (0) #define hash_find(table, key_ptr, key_size, hash_val, table_size, buckets_name, type, member, \ key_field, out_link) \ do { \ uint32_t __idx = (hash_val) % (table_size); \ struct hash_node_link* __curr = (table)->buckets_name[__idx]; \ (out_link) = NULL; \ while (__curr) { \ if (__curr->hash == (hash_val)) { \ type* __entry = hash_entry (__curr, type, member); \ if (memcmp (__entry->key_field, (key_ptr), (key_size)) == 0) { \ (out_link) = __curr; \ break; \ } \ } \ __curr = __curr->next; \ } \ } while (0) #endif // _KERNEL_LIBK_HASH_H