16#ifndef IMPL_HANDLE_REALTIME_ORDERED_MAP_H
17#define IMPL_HANDLE_REALTIME_ORDERED_MAP_H
26#include "impl_types.h"
122 struct ccc_hromap_elem *nodes;
146struct ccc_hrtree_handle
149 struct ccc_hromap *hrm;
155 ccc_entry_status stats;
162 struct ccc_hrtree_handle impl;
168void *ccc_impl_hrm_data_at(
struct ccc_hromap
const *hrm,
size_t slot);
170void *ccc_impl_hrm_key_at(
struct ccc_hromap
const *hrm,
size_t slot);
172struct ccc_hromap_elem *ccc_impl_hrm_elem_at(
struct ccc_hromap
const *hrm,
175struct ccc_hrtree_handle ccc_impl_hrm_handle(struct ccc_hromap const *hrm,
178void ccc_impl_hrm_insert(
struct ccc_hromap *hrm,
size_t parent_i,
181size_t ccc_impl_hrm_alloc_slot(
struct ccc_hromap *hrm);
188#define ccc_impl_hrm_blocks(impl_cap) \
189 (((impl_cap) + ((sizeof(*(struct ccc_hromap){}.parity) * CHAR_BIT) - 1)) \
190 / (sizeof(*(struct ccc_hromap){}.parity) * CHAR_BIT))
195#define ccc_impl_hrm_declare_fixed_map(impl_fixed_map_type_name, \
196 impl_key_val_type_name, impl_capacity) \
197 static_assert((impl_capacity) > 1, \
198 "fixed size map must have capacity greater than 1"); \
201 impl_key_val_type_name data[(impl_capacity)]; \
202 struct ccc_hromap_elem nodes[(impl_capacity)]; \
203 typeof(*(struct ccc_hromap){} \
204 .parity) parity[ccc_impl_hrm_blocks((impl_capacity))]; \
205 }(impl_fixed_map_type_name)
209#define ccc_impl_hrm_fixed_capacity(fixed_map_type_name) \
210 (sizeof((fixed_map_type_name){}.nodes) / sizeof(struct ccc_hromap_elem))
217#define ccc_impl_hrm_init(impl_memory_ptr, impl_type_name, \
218 impl_key_elem_field, impl_key_cmp_fn, impl_alloc_fn, \
219 impl_aux_data, impl_capacity) \
221 .data = (impl_memory_ptr), \
224 .capacity = (impl_capacity), \
228 .sizeof_type = sizeof(impl_type_name), \
229 .key_offset = offsetof(impl_type_name, impl_key_elem_field), \
230 .cmp = (impl_key_cmp_fn), \
231 .alloc = (impl_alloc_fn), \
232 .aux = (impl_aux_data), \
236#define ccc_impl_hrm_as(handle_realtime_ordered_map_ptr, type_name, handle...) \
237 ((type_name *)ccc_impl_hrm_data_at((handle_realtime_ordered_map_ptr), \
243#define ccc_impl_hrm_and_modify_w(handle_realtime_ordered_map_handle_ptr, \
244 type_name, closure_over_T...) \
246 __auto_type impl_hrm_hndl_ptr \
247 = (handle_realtime_ordered_map_handle_ptr); \
248 struct ccc_hrtree_handle impl_hrm_mod_hndl \
249 = {.stats = CCC_ENTRY_ARG_ERROR}; \
250 if (impl_hrm_hndl_ptr) \
252 impl_hrm_mod_hndl = impl_hrm_hndl_ptr->impl; \
253 if (impl_hrm_mod_hndl.stats & CCC_ENTRY_OCCUPIED) \
255 type_name *const T = ccc_impl_hrm_data_at( \
256 impl_hrm_mod_hndl.hrm, impl_hrm_mod_hndl.i); \
267#define ccc_impl_hrm_or_insert_w(handle_realtime_ordered_map_handle_ptr, \
270 __auto_type impl_or_ins_handle_ptr \
271 = (handle_realtime_ordered_map_handle_ptr); \
272 ccc_handle_i impl_hrm_or_ins_ret = 0; \
273 if (impl_or_ins_handle_ptr) \
275 if (impl_or_ins_handle_ptr->impl.stats == CCC_ENTRY_OCCUPIED) \
277 impl_hrm_or_ins_ret = impl_or_ins_handle_ptr->impl.i; \
281 impl_hrm_or_ins_ret = ccc_impl_hrm_alloc_slot( \
282 impl_or_ins_handle_ptr->impl.hrm); \
283 if (impl_hrm_or_ins_ret) \
285 *((typeof(lazy_key_value) *)ccc_impl_hrm_data_at( \
286 impl_or_ins_handle_ptr->impl.hrm, \
287 impl_hrm_or_ins_ret)) \
289 ccc_impl_hrm_insert(impl_or_ins_handle_ptr->impl.hrm, \
290 impl_or_ins_handle_ptr->impl.i, \
291 impl_or_ins_handle_ptr->impl.last_cmp, \
292 impl_hrm_or_ins_ret); \
296 impl_hrm_or_ins_ret; \
300#define ccc_impl_hrm_insert_handle_w(handle_realtime_ordered_map_handle_ptr, \
303 __auto_type impl_ins_handle_ptr \
304 = (handle_realtime_ordered_map_handle_ptr); \
305 ccc_handle_i impl_hrm_ins_hndl_ret = 0; \
306 if (impl_ins_handle_ptr) \
308 if (!(impl_ins_handle_ptr->impl.stats & CCC_ENTRY_OCCUPIED)) \
310 impl_hrm_ins_hndl_ret \
311 = ccc_impl_hrm_alloc_slot(impl_ins_handle_ptr->impl.hrm); \
312 if (impl_hrm_ins_hndl_ret) \
314 *((typeof(lazy_key_value) *)ccc_impl_hrm_data_at( \
315 impl_ins_handle_ptr->impl.hrm, impl_hrm_ins_hndl_ret)) \
317 ccc_impl_hrm_insert(impl_ins_handle_ptr->impl.hrm, \
318 impl_ins_handle_ptr->impl.i, \
319 impl_ins_handle_ptr->impl.last_cmp, \
320 impl_hrm_ins_hndl_ret); \
323 else if (impl_ins_handle_ptr->impl.stats == CCC_ENTRY_OCCUPIED) \
325 impl_hrm_ins_hndl_ret = impl_ins_handle_ptr->impl.i; \
326 *((typeof(lazy_key_value) *)ccc_impl_hrm_data_at( \
327 impl_ins_handle_ptr->impl.hrm, impl_hrm_ins_hndl_ret)) \
331 impl_hrm_ins_hndl_ret; \
335#define ccc_impl_hrm_try_insert_w(handle_realtime_ordered_map_ptr, key, \
338 __auto_type impl_try_ins_map_ptr = (handle_realtime_ordered_map_ptr); \
339 struct ccc_handl impl_hrm_try_ins_hndl_ret \
340 = {.stats = CCC_ENTRY_ARG_ERROR}; \
341 if (impl_try_ins_map_ptr) \
343 __auto_type impl_hrm_key = (key); \
344 struct ccc_hrtree_handle impl_hrm_try_ins_hndl \
345 = ccc_impl_hrm_handle(impl_try_ins_map_ptr, \
346 (void *)&impl_hrm_key); \
347 if (!(impl_hrm_try_ins_hndl.stats & CCC_ENTRY_OCCUPIED)) \
349 impl_hrm_try_ins_hndl_ret = (struct ccc_handl){ \
350 .i = ccc_impl_hrm_alloc_slot(impl_hrm_try_ins_hndl.hrm), \
351 .stats = CCC_ENTRY_INSERT_ERROR, \
353 if (impl_hrm_try_ins_hndl_ret.i) \
355 *((typeof(lazy_value) *)ccc_impl_hrm_data_at( \
356 impl_try_ins_map_ptr, impl_hrm_try_ins_hndl_ret.i)) \
358 *((typeof(impl_hrm_key) *)ccc_impl_hrm_key_at( \
359 impl_try_ins_map_ptr, impl_hrm_try_ins_hndl_ret.i)) \
361 ccc_impl_hrm_insert(impl_hrm_try_ins_hndl.hrm, \
362 impl_hrm_try_ins_hndl.i, \
363 impl_hrm_try_ins_hndl.last_cmp, \
364 impl_hrm_try_ins_hndl_ret.i); \
365 impl_hrm_try_ins_hndl_ret.stats = CCC_ENTRY_VACANT; \
368 else if (impl_hrm_try_ins_hndl.stats == CCC_ENTRY_OCCUPIED) \
370 impl_hrm_try_ins_hndl_ret = (struct ccc_handl){ \
371 .i = impl_hrm_try_ins_hndl.i, \
372 .stats = impl_hrm_try_ins_hndl.stats, \
376 impl_hrm_try_ins_hndl_ret; \
380#define ccc_impl_hrm_insert_or_assign_w(handle_realtime_ordered_map_ptr, key, \
383 __auto_type impl_ins_or_assign_map_ptr \
384 = (handle_realtime_ordered_map_ptr); \
385 struct ccc_handl impl_hrm_ins_or_assign_hndl_ret \
386 = {.stats = CCC_ENTRY_ARG_ERROR}; \
387 if (impl_ins_or_assign_map_ptr) \
389 __auto_type impl_hrm_key = (key); \
390 struct ccc_hrtree_handle impl_hrm_ins_or_assign_hndl \
391 = ccc_impl_hrm_handle(impl_ins_or_assign_map_ptr, \
392 (void *)&impl_hrm_key); \
393 if (!(impl_hrm_ins_or_assign_hndl.stats & CCC_ENTRY_OCCUPIED)) \
395 impl_hrm_ins_or_assign_hndl_ret = (struct ccc_handl){ \
396 .i = ccc_impl_hrm_alloc_slot( \
397 impl_hrm_ins_or_assign_hndl.hrm), \
398 .stats = CCC_ENTRY_INSERT_ERROR, \
400 if (impl_hrm_ins_or_assign_hndl_ret.i) \
402 *((typeof(lazy_value) *)ccc_impl_hrm_data_at( \
403 impl_hrm_ins_or_assign_hndl.hrm, \
404 impl_hrm_ins_or_assign_hndl_ret.i)) \
406 *((typeof(impl_hrm_key) *)ccc_impl_hrm_key_at( \
407 impl_hrm_ins_or_assign_hndl.hrm, \
408 impl_hrm_ins_or_assign_hndl_ret.i)) \
410 ccc_impl_hrm_insert(impl_hrm_ins_or_assign_hndl.hrm, \
411 impl_hrm_ins_or_assign_hndl.i, \
412 impl_hrm_ins_or_assign_hndl.last_cmp, \
413 impl_hrm_ins_or_assign_hndl_ret.i); \
414 impl_hrm_ins_or_assign_hndl_ret.stats = CCC_ENTRY_VACANT; \
417 else if (impl_hrm_ins_or_assign_hndl.stats == CCC_ENTRY_OCCUPIED) \
419 *((typeof(lazy_value) *)ccc_impl_hrm_data_at( \
420 impl_hrm_ins_or_assign_hndl.hrm, \
421 impl_hrm_ins_or_assign_hndl.i)) \
423 impl_hrm_ins_or_assign_hndl_ret = (struct ccc_handl){ \
424 .i = impl_hrm_ins_or_assign_hndl.i, \
425 .stats = impl_hrm_ins_or_assign_hndl.stats, \
427 *((typeof(impl_hrm_key) *)ccc_impl_hrm_key_at( \
428 impl_hrm_ins_or_assign_hndl.hrm, \
429 impl_hrm_ins_or_assign_hndl.i)) \
433 impl_hrm_ins_or_assign_hndl_ret; \
union ccc_hromap_handle ccc_hromap_handle
A container specific handle used to implement the Handle Interface.
Definition: handle_realtime_ordered_map.h:82
void * ccc_any_alloc_fn(void *ptr, size_t size, void *aux)
An allocation function at the core of all containers.
Definition: types.h:312
ccc_threeway_cmp ccc_any_key_cmp_fn(ccc_any_key_cmp)
A callback function for three-way comparing two stored keys.
Definition: types.h:362
ccc_threeway_cmp
A three-way comparison for comparison functions.
Definition: types.h:153