1#ifndef CCC_IMPL_FLAT_HASH_MAP_H
2#define CCC_IMPL_FLAT_HASH_MAP_H
13#include "impl_types.h"
36 size_t hash_elem_offset_;
40struct ccc_fhash_entry_
42 struct ccc_fhmap_ *h_;
44 struct ccc_ent_ entry_;
50 struct ccc_fhash_entry_ impl_;
56void ccc_impl_fhm_insert(
struct ccc_fhmap_ *h,
void const *e, uint64_t hash,
59struct ccc_fhash_entry_ ccc_impl_fhm_entry(struct ccc_fhmap_ *h,
62struct ccc_fhmap_elem_ *ccc_impl_fhm_in_slot(
struct ccc_fhmap_
const *h,
65void *ccc_impl_fhm_key_in_slot(
struct ccc_fhmap_
const *h,
void const *slot);
67uint64_t *ccc_impl_fhm_hash_at(
struct ccc_fhmap_
const *h,
size_t i);
69size_t ccc_impl_fhm_increment(
size_t capacity,
size_t i);
74#define ccc_impl_fhm_init(memory_ptr, fhash_elem_field, key_field, hash_fn, \
75 key_eq_fn, alloc_fn, aux, capacity) \
78 = (ccc_buffer)ccc_buf_init((memory_ptr), (alloc_fn), (aux), capacity), \
79 .hash_fn_ = (hash_fn), \
80 .eq_fn_ = (key_eq_fn), \
81 .key_offset_ = offsetof(typeof(*(memory_ptr)), key_field), \
83 = offsetof(typeof(*(memory_ptr)), fhash_elem_field), \
88#define ccc_impl_fhm_swaps(swap_entry, lazy_key_value...) \
91 = ccc_buf_i(&((swap_entry)->h_->buf_), (swap_entry)->entry_.e_) \
93 if (*ccc_impl_fhm_hash_at((swap_entry)->h_, fhm_i_) == CCC_FHM_EMPTY) \
95 *((typeof(lazy_key_value) *)ccc_buf_at(&((swap_entry)->h_->buf_), \
98 *ccc_impl_fhm_hash_at((swap_entry)->h_, fhm_i_) \
99 = (swap_entry)->hash_; \
100 (void)ccc_buf_size_plus(&(swap_entry)->h_->buf_, 1); \
104 typeof(lazy_key_value) fhm_cur_slot_ \
105 = *((typeof(fhm_cur_slot_) *)ccc_buf_at( \
106 &((swap_entry)->h_->buf_), fhm_i_)); \
107 *((typeof(fhm_cur_slot_) *)ccc_buf_at(&((swap_entry)->h_->buf_), \
110 *ccc_impl_fhm_hash_at((swap_entry)->h_, fhm_i_) \
111 = (swap_entry)->hash_; \
112 fhm_i_ = ccc_impl_fhm_increment( \
113 ccc_buf_capacity(&(swap_entry)->h_->buf_).count, fhm_i_); \
114 ccc_impl_fhm_insert( \
115 (swap_entry)->h_, &fhm_cur_slot_, \
116 ccc_impl_fhm_in_slot((swap_entry)->h_, &fhm_cur_slot_)->hash_, \
119 (swap_entry)->entry_.e_; \
125#define ccc_impl_fhm_and_modify_w(flat_hash_map_entry_ptr, type_name, \
128 __auto_type fhm_mod_ent_ptr_ = (flat_hash_map_entry_ptr); \
129 struct ccc_fhash_entry_ fhm_mod_with_ent_ \
130 = {.entry_ = {.stats_ = CCC_ENTRY_ARG_ERROR}}; \
131 if (fhm_mod_ent_ptr_) \
133 fhm_mod_with_ent_ = fhm_mod_ent_ptr_->impl_; \
134 if (fhm_mod_with_ent_.entry_.stats_ == CCC_ENTRY_OCCUPIED) \
136 type_name *const T = fhm_mod_with_ent_.entry_.e_; \
147#define ccc_impl_fhm_or_insert_w(flat_hash_map_entry_ptr, lazy_key_value...) \
149 __auto_type fhm_or_ins_ent_ptr_ = (flat_hash_map_entry_ptr); \
150 typeof(lazy_key_value) *fhm_or_ins_res_ = NULL; \
151 if (fhm_or_ins_ent_ptr_) \
153 struct ccc_fhash_entry_ *fhm_or_ins_entry_ \
154 = &fhm_or_ins_ent_ptr_->impl_; \
155 if (!(fhm_or_ins_entry_->entry_.stats_ & CCC_ENTRY_INSERT_ERROR)) \
157 if (fhm_or_ins_entry_->entry_.stats_ & CCC_ENTRY_OCCUPIED) \
159 fhm_or_ins_res_ = fhm_or_ins_entry_->entry_.e_; \
163 fhm_or_ins_res_ = ccc_impl_fhm_swaps(fhm_or_ins_entry_, \
172#define ccc_impl_fhm_insert_entry_w(flat_hash_map_entry_ptr, \
175 __auto_type fhm_ins_ent_ptr_ = (flat_hash_map_entry_ptr); \
176 typeof(lazy_key_value) *fhm_res_ = NULL; \
177 if (fhm_ins_ent_ptr_) \
179 struct ccc_fhash_entry_ *fhm_ins_ent_ = &fhm_ins_ent_ptr_->impl_; \
180 if (!(fhm_ins_ent_->entry_.stats_ & CCC_ENTRY_INSERT_ERROR)) \
182 if (fhm_ins_ent_->entry_.stats_ & CCC_ENTRY_OCCUPIED) \
184 fhm_ins_ent_->entry_.stats_ = CCC_ENTRY_OCCUPIED; \
185 *((typeof(fhm_res_))fhm_ins_ent_->entry_.e_) \
187 ccc_impl_fhm_in_slot(fhm_ins_ent_->h_, \
188 fhm_ins_ent_->entry_.e_) \
190 = fhm_ins_ent_->hash_; \
191 fhm_res_ = fhm_ins_ent_->entry_.e_; \
196 = ccc_impl_fhm_swaps(fhm_ins_ent_, lazy_key_value); \
204#define ccc_impl_fhm_try_insert_w(flat_hash_map_ptr, key, lazy_value...) \
206 struct ccc_fhmap_ *flat_hash_map_ptr_ = (flat_hash_map_ptr); \
207 struct ccc_ent_ fhm_try_insert_res_ = {.stats_ = CCC_ENTRY_ARG_ERROR}; \
208 if (flat_hash_map_ptr_) \
210 __auto_type fhm_key_ = key; \
211 struct ccc_fhash_entry_ fhm_try_ins_ent_ \
212 = ccc_impl_fhm_entry(flat_hash_map_ptr_, (void *)&fhm_key_); \
213 if ((fhm_try_ins_ent_.entry_.stats_ & CCC_ENTRY_OCCUPIED) \
214 || (fhm_try_ins_ent_.entry_.stats_ & CCC_ENTRY_INSERT_ERROR)) \
216 fhm_try_insert_res_ = fhm_try_ins_ent_.entry_; \
220 fhm_try_insert_res_ = (struct ccc_ent_){ \
221 ccc_impl_fhm_swaps((&fhm_try_ins_ent_), lazy_value), \
224 *((typeof(fhm_key_) *)ccc_impl_fhm_key_in_slot( \
225 flat_hash_map_ptr_, fhm_try_insert_res_.e_)) \
229 fhm_try_insert_res_; \
233#define ccc_impl_fhm_insert_or_assign_w(flat_hash_map_ptr, key, lazy_value...) \
235 struct ccc_fhmap_ *flat_hash_map_ptr_ = (flat_hash_map_ptr); \
236 struct ccc_ent_ fhm_ins_or_assign_res_ \
237 = {.stats_ = CCC_ENTRY_ARG_ERROR}; \
238 if (flat_hash_map_ptr_) \
240 __auto_type fhm_key_ = key; \
241 struct ccc_fhash_entry_ fhm_ins_or_assign_ent_ \
242 = ccc_impl_fhm_entry(flat_hash_map_ptr_, (void *)&fhm_key_); \
243 if (fhm_ins_or_assign_ent_.entry_.stats_ & CCC_ENTRY_OCCUPIED) \
245 fhm_ins_or_assign_res_ = fhm_ins_or_assign_ent_.entry_; \
246 *((typeof(lazy_value) *)fhm_ins_or_assign_res_.e_) \
248 *((typeof(fhm_key_) *)ccc_impl_fhm_key_in_slot( \
249 flat_hash_map_ptr_, fhm_ins_or_assign_res_.e_)) \
251 ccc_impl_fhm_in_slot(fhm_ins_or_assign_ent_.h_, \
252 fhm_ins_or_assign_ent_.entry_.e_) \
254 = fhm_ins_or_assign_ent_.hash_; \
256 else if (fhm_ins_or_assign_ent_.entry_.stats_ \
257 & CCC_ENTRY_INSERT_ERROR) \
259 fhm_ins_or_assign_res_.e_ = NULL; \
260 fhm_ins_or_assign_res_.stats_ = CCC_ENTRY_INSERT_ERROR; \
264 fhm_ins_or_assign_res_ = (struct ccc_ent_){ \
265 ccc_impl_fhm_swaps((&fhm_ins_or_assign_ent_), lazy_value), \
268 *((typeof(fhm_key_) *)ccc_impl_fhm_key_in_slot( \
269 flat_hash_map_ptr_, fhm_ins_or_assign_res_.e_)) \
273 fhm_ins_or_assign_res_; \
struct ccc_buf_ ccc_buffer
A contiguous block of storage for elements of the same type.
Definition: buffer.h:50
uint64_t ccc_hash_fn(ccc_user_key to_hash)
A callback function to hash the key type used in a container.
Definition: types.h:339
ccc_tribool ccc_key_eq_fn(ccc_key_cmp)
A callback function to determining equality between two stored keys.
Definition: types.h:326