6#if !defined(SKIP_INCLUDES)
14 #if !defined PLACEHOLDERS
22 #if !defined PLACEHOLDERS
26 #define KEY_HASH key_hash
31 #define KEY_EQ DC_MEM_EQ
34#if !defined KEY_DELETE
35 #define KEY_DELETE DC_NO_DELETE
39 #define KEY_CLONE DC_COPY_CLONE
43 #define KEY_DEBUG DC_DEFAULT_DEBUG
47 #if !defined PLACEHOLDERS
56#if !defined VALUE_DELETE
57 #define VALUE_DELETE DC_NO_DELETE
60#if !defined VALUE_CLONE
61 #define VALUE_CLONE DC_COPY_CLONE
64#if !defined VALUE_DEBUG
65 #define VALUE_DEBUG DC_DEFAULT_DEBUG
75#define SLOT NS(NAME, slot_t)
109#define SLOT_VECTOR NS(NAME, item_vectors)
111#pragma push_macro("ALLOC")
115#define ITEM_CLONE NS(SLOT, clone)
116#define ITEM_DEBUG NS(SLOT, debug)
117#define ITEM_CLONE NS(SLOT, clone)
118#define INTERNAL_NAME SLOT_VECTOR
121#pragma pop_macro("ALLOC")
123#if defined SMALL_BUCKETS
124 #define INDEX_KIND dc_ankerl_index_small
125 #define BUCKET_SIZE 4
128 #define INDEX_KIND dc_ankerl_index_large
129 #define BUCKET_SIZE 8
132#define BUCKET NS(SELF, bucket)
151#define INVARIANT_CHECK(self) \
153 DC_ASSUME(DC_MATH_IS_POWER_OF_2((self)->buckets_capacity)); \
154 DC_ASSUME((self)->buckets); \
155 DC_ASSUME((self)->alloc);
187 memcpy(new_buckets, self->buckets, self->buckets_capacity *
sizeof(
BUCKET));
190 .buckets_capacity = self->buckets_capacity,
191 .buckets = new_buckets,
193 .alloc = self->alloc,
201 const size_t mask = self->buckets_capacity - 1;
205 const size_t desired = hash & mask;
209 for (
size_t pos = desired;; pos = (pos + 1) & mask) {
210 BUCKET const* b = &self->buckets[pos];
225 if (b->mdata.fingerprint == fp) {
252 for (
size_t pos = desired;; pos = (pos + 1) & mask) {
253 BUCKET* b = &self->buckets[pos];
260 if (b->mdata.dfd < cur.mdata.dfd) {
277 const size_t new_mask = new_capacity - 1;
280 for (
size_t dense_index = 0; dense_index < n; ++dense_index) {
285 const size_t desired = hash & new_mask;
294 for (
size_t pos = desired;; pos = (pos + 1) & new_mask) {
295 BUCKET* b = &new_buckets[pos];
302 if (b->mdata.dfd < cur.mdata.dfd) {
313 self->buckets = new_buckets;
314 self->buckets_capacity = new_capacity;
321 if (required <= self->buckets_capacity) {
332 if (
size >= self->buckets_capacity) {
346 size_t* out_dense_index) {
352 const size_t mask = self->buckets_capacity - 1;
356 const size_t desired = hash & mask;
359 for (
size_t pos = desired;; pos = (pos + 1) & mask) {
360 BUCKET const* b = &self->buckets[pos];
371 if (b->mdata.fingerprint == fp) {
375 *out_bucket_pos = pos;
376 *out_dense_index = di;
417 size_t removed_dense_index;
429 *destination = slot->
value;
439 size_t hole = found_pos;
442 const size_t next = (hole + 1) & mask;
451 self->
buckets[hole].mdata.dfd =
460 const size_t last =
size - 1;
462 if (removed_dense_index != last) {
471 const size_t desired = moved_hash & mask;
474 for (
size_t pos = desired;; pos = (pos + 1) & mask) {
483 if (b->mdata.fingerprint == moved_fp) {
525#define ITER_CONST NS(SELF, iter_const)
526#define KV_PAIR_CONST NS(ITER_CONST, item)
538 return item->key == NULL &&
item->value == NULL;
550 .key = &next_item->
key,
551 .value = &next_item->
value,
583#define ITER NS(SELF, iter)
584#define KV_PAIR NS(ITER, item)
596 return item->key == NULL &&
item->value == NULL;
608 .key = &next_item->
key,
609 .value = &next_item->
value,
623#undef INVARIANT_CHECK
static void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
static void free(SELF *self, void *ptr)
static void * malloc(SELF *self, size_t size)
static void * calloc(SELF *self, size_t count, size_t size)
static INDEX insert(SELF *self, VALUE value)
static ITER_CONST get_iter_const(SELF const *self)
static ITER get_iter(SELF *self)
static IV_PAIR next(ITER *iter)
static INDEX_TYPE size(SELF const *self)
#define INVARIANT_CHECK(self)
static VALUE remove(SELF *self, INDEX index)
static bool empty_item(IV_PAIR const *item)
SLOT PRIV(block)[DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS)]
static VALUE * try_write(SELF *self, INDEX index)
static VALUE const * read(SELF const *self, INDEX index)
static VALUE * write(SELF *self, INDEX index)
static bool try_remove(SELF *self, INDEX index, VALUE *destination)
static SELF clone(SELF const *self)
static VALUE const * try_read(SELF const *self, INDEX index)
static SELF new_with_capacity_for(INDEX_TYPE items, ALLOC *alloc)
static VALUE *PRIV try_insert_no_extend_capacity(SELF *self, KEY key, VALUE value)
static VALUE * try_insert(SELF *self, KEY key, VALUE value)
#define KEY
A simple swiss table implementation. See the abseil docs for swss table here.
static void delete_entry(SELF *self, KEY key)
static SELF PRIV new_with_exact_capacity(size_t capacity, ALLOC *alloc)
static void extend_capacity_for(SELF *self, size_t expected_items)
static bool PRIV try_find(SELF const *self, KEY const *key, size_t *out_bucket_pos, size_t *out_dense_index)
static void PRIV rehash(SELF *self, size_t new_capacity)
#define KEY
A simple swiss table implementation. See the abseil docs for swss table here.
#define DC_TRAIT_MAP(SELF)
static SELF new_with_capacity(size_t front_and_back_capacity, ALLOC *alloc)
static ITEM * push(SELF *self, ITEM item)
static ITEM pop(SELF *self)
dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
static void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
static dc_gdb_marker dc_gdb_marker_new()
static uint8_t dc_ankerl_fingerprint_from_hash(size_t hash)
static const size_t dc_ankerl_initial_items
static bool dc_ankerl_mdata_present(dc_ankerl_mdata const *bucket)
static dc_ankerl_dfd dc_ankerl_dfd_new(uint8_t distance)
static const dc_ankerl_dfd dc_ankerl_dfd_none
static dc_ankerl_dfd dc_ankerl_dfd_decrement_for_backshift(dc_ankerl_dfd dfd)
static const dc_ankerl_dfd dc_ankerl_dfd_max
static dc_ankerl_dfd dc_ankerl_dfd_increment(dc_ankerl_dfd dfd)
static size_t dc_ankerl_buckets_capacity(size_t for_items)
#define DC_MATH_IS_POWER_OF_2(x)
#define EXPAND_STRING(NAME)
#define DC_ASSERT(expr,...)
#define DC_ASSUME(expr,...)
#define TEMPLATE_ERROR(...)
With the user provided name, even in nested templates.
dc_gdb_marker derive_c_hashmap
Debug format helpers for debug printin data structures.
static FILE * stream(SELF *self)
Opens a file for.