Derive-C
Loading...
Searching...
No Matches
template.h File Reference

Go to the source code of this file.

Data Structures

struct  value_t
struct  SLOT
struct  SELF
 An allocator that prints to stdout when it allocates or frees memory. More...
struct  ITER_CONST
struct  KV_PAIR_CONST
struct  ITER
struct  KV_PAIR

Macros

#define KEY   map_key_t
 A simple swiss table implementation. See the abseil docs for swss table here.
#define KEY_HASH   key_hash
#define KEY_EQ   DC_MEM_EQ
#define KEY_DELETE   DC_NO_DELETE
#define KEY_CLONE   DC_COPY_CLONE
#define KEY_DEBUG   DC_DEFAULT_DEBUG
#define VALUE   value_t
#define VALUE_DELETE   DC_NO_DELETE
#define VALUE_CLONE   DC_COPY_CLONE
#define VALUE_DEBUG   DC_DEFAULT_DEBUG
#define SLOT   NS(SELF, slot_t)
#define INVARIANT_CHECK(self)
#define ITER_CONST   NS(SELF, iter_const)
#define KV_PAIR_CONST   NS(ITER_CONST, item)
#define ITER   NS(SELF, iter)
#define KV_PAIR   NS(ITER, item)

Functions

static size_t KEY_HASH (KEY const *key)
static SELF PRIV new_with_exact_capacity (size_t capacity, ALLOC *alloc)
static SELF new_with_capacity_for (size_t for_items, ALLOC *alloc)
static SELF new (ALLOC *alloc)
static SELF clone (SELF const *self)
static VALUE *PRIV try_insert_no_extend_capacity (SELF *self, KEY key, VALUE value)
static void PRIV rehash (SELF *self, size_t new_capacity)
static void extend_capacity_for (SELF *self, size_t expected_items)
static VALUEtry_insert (SELF *self, KEY key, VALUE value)
static VALUEinsert (SELF *self, KEY key, VALUE value)
static VALUE const * try_read (SELF const *self, KEY key)
static VALUE const * read (SELF const *self, KEY key)
static VALUEtry_write (SELF *self, KEY key)
static VALUEwrite (SELF *self, KEY key)
static bool try_remove (SELF *self, KEY key, VALUE *destination)
static VALUE remove (SELF *self, KEY key)
static void delete_entry (SELF *self, KEY key)
static size_t size (SELF const *self)
static void PRIV next_populated_index (SELF const *self, dc_swiss_optional_index *index)
static void delete (SELF *self)
static bool empty_item (KV_PAIR_CONST const *item)
static KV_PAIR_CONST next (ITER_CONST *iter)
static ITER_CONST get_iter_const (SELF const *self)
static void debug (SELF const *self, dc_debug_fmt fmt, FILE *stream)
static bool empty_item (KV_PAIR const *item)
static KV_PAIR next (ITER *iter)
static ITER get_iter (SELF *self)
 DC_TRAIT_MAP (SELF)

Macro Definition Documentation

◆ INVARIANT_CHECK

#define INVARIANT_CHECK ( self)
Value:
DC_ASSUME(self); \
DC_ASSUME(DC_MATH_IS_POWER_OF_2((self)->capacity)); \
DC_ASSUME((self)->slots); \
DC_ASSUME((self)->ctrl); \
DC_ASSUME((self)->alloc); \
DC_ASSUME((self)->count + (self)->tombstones <= (self)->capacity);
static size_t capacity()
Definition template.h:66
#define DC_MATH_IS_POWER_OF_2(x)
Definition math.h:12
#define DC_ASSUME(expr,...)
Definition panic.h:56

Definition at line 93 of file template.h.

93#define INVARIANT_CHECK(self) \
94 DC_ASSUME(self); \
95 DC_ASSUME(DC_MATH_IS_POWER_OF_2((self)->capacity)); \
96 DC_ASSUME((self)->slots); \
97 DC_ASSUME((self)->ctrl); \
98 DC_ASSUME((self)->alloc); \
99 DC_ASSUME((self)->count + (self)->tombstones <= (self)->capacity);

◆ ITER

#define ITER   NS(SELF, iter)

Definition at line 528 of file template.h.

◆ ITER_CONST

#define ITER_CONST   NS(SELF, iter_const)

Definition at line 435 of file template.h.

◆ KEY

#define KEY   map_key_t

A simple swiss table implementation. See the abseil docs for swss table here.

Definition at line 18 of file template.h.

◆ KEY_CLONE

#define KEY_CLONE   DC_COPY_CLONE

Definition at line 40 of file template.h.

◆ KEY_DEBUG

#define KEY_DEBUG   DC_DEFAULT_DEBUG

Definition at line 44 of file template.h.

◆ KEY_DELETE

#define KEY_DELETE   DC_NO_DELETE

Definition at line 36 of file template.h.

◆ KEY_EQ

#define KEY_EQ   DC_MEM_EQ

Definition at line 32 of file template.h.

◆ KEY_HASH

#define KEY_HASH   key_hash

Definition at line 27 of file template.h.

◆ KV_PAIR

#define KV_PAIR   NS(ITER, item)

Definition at line 529 of file template.h.

◆ KV_PAIR_CONST

#define KV_PAIR_CONST   NS(ITER_CONST, item)

Definition at line 436 of file template.h.

◆ SLOT

#define SLOT   NS(SELF, slot_t)

Definition at line 73 of file template.h.

◆ VALUE

#define VALUE   value_t

Definition at line 54 of file template.h.

◆ VALUE_CLONE

#define VALUE_CLONE   DC_COPY_CLONE

Definition at line 62 of file template.h.

◆ VALUE_DEBUG

#define VALUE_DEBUG   DC_DEFAULT_DEBUG

Definition at line 66 of file template.h.

◆ VALUE_DELETE

#define VALUE_DELETE   DC_NO_DELETE

Definition at line 58 of file template.h.

Function Documentation

◆ clone()

SELF clone ( SELF const * self)
static

Definition at line 141 of file template.h.

141 {
142 INVARIANT_CHECK(self);
143
144 size_t ctrl_capacity = self->capacity + DC_SWISS_SIMD_PROBE_SIZE;
145
146 dc_swiss_ctrl* ctrl =
147 (dc_swiss_ctrl*)NS(ALLOC, malloc)(self->alloc, sizeof(dc_swiss_ctrl) * ctrl_capacity);
148 SLOT* slots = (SLOT*)NS(ALLOC, malloc)(self->alloc, sizeof(SLOT) * self->capacity);
149 DC_ASSERT(ctrl && slots);
150
151 memcpy(ctrl, self->ctrl, sizeof(dc_swiss_ctrl) * ctrl_capacity);
152
153 for (size_t i = 0; i < self->capacity; i++) {
154 if (dc_swiss_is_present(self->ctrl[i])) {
155 slots[i].key = KEY_CLONE(&self->slots[i].key);
156 slots[i].value = VALUE_CLONE(&self->slots[i].value);
157 }
158 }
159
160 return (SELF){
161 .capacity = self->capacity,
162 .count = self->count,
163 .tombstones = self->tombstones,
164 .ctrl = ctrl,
165 .slots = slots,
166 .alloc = self->alloc,
167 .derive_c_hashmap = dc_gdb_marker_new(),
168 .iterator_invalidation_tracker = mutation_tracker_new(),
169 };
170}
static void * malloc(SELF *self, size_t size)
Definition template.h:23
#define ALLOC
Definition template.h:64
#define SLOT
Definition template.h:63
#define INVARIANT_CHECK(self)
Definition template.h:88
#define VALUE_CLONE
Definition template.h:37
#define KEY_CLONE
Definition template.h:39
static dc_gdb_marker dc_gdb_marker_new()
Definition gdb_marker.h:7
static bool dc_swiss_is_present(dc_swiss_ctrl ctrl)
Definition utils.h:24
#define DC_SWISS_SIMD_PROBE_SIZE
Definition utils.h:8
uint8_t dc_swiss_ctrl
Definition utils.h:22
static mutation_tracker mutation_tracker_new()
#define NS(pre, post)
Definition namespace.h:4
#define DC_ASSERT(expr,...)
Definition panic.h:36
#define SELF
Definition def.h:52
VALUE value
Definition template.h:78
KEY key
Definition template.h:77

◆ DC_TRAIT_MAP()

DC_TRAIT_MAP ( SELF )

◆ debug()

void debug ( SELF const * self,
dc_debug_fmt fmt,
FILE * stream )
static

Definition at line 485 of file template.h.

485 {
486 fprintf(stream, EXPAND_STRING(SELF) "@%p {\n", self);
487 fmt = dc_debug_fmt_scope_begin(fmt);
488
489 dc_debug_fmt_print(fmt, stream, "capacity: %lu,\n", self->capacity);
490 dc_debug_fmt_print(fmt, stream, "tombstones: %lu,\n", self->tombstones);
491 dc_debug_fmt_print(fmt, stream, "count: %lu,\n", self->count);
492
493 dc_debug_fmt_print(fmt, stream, "ctrl: @%p[%lu + simd probe size additional %lu],\n",
494 self->ctrl, self->capacity, DC_SWISS_SIMD_PROBE_SIZE);
495 dc_debug_fmt_print(fmt, stream, "slots: @%p[%lu],\n", self->slots, self->capacity);
496
497 dc_debug_fmt_print(fmt, stream, "alloc: ");
498 NS(ALLOC, debug)(self->alloc, fmt, stream);
499 fprintf(stream, ",\n");
500
501 ITER_CONST iter = NS(SELF, get_iter_const)(self);
503
505 item = NS(ITER_CONST, next)(&iter)) {
506 dc_debug_fmt_print(fmt, stream, "{\n");
507 fmt = dc_debug_fmt_scope_begin(fmt);
508
509 dc_debug_fmt_print(fmt, stream, "key: ");
510 KEY_DEBUG(item.key, fmt, stream);
511 fprintf(stream, ",\n");
512
513 dc_debug_fmt_print(fmt, stream, "value: ");
514 VALUE_DEBUG(item.value, fmt, stream);
515 fprintf(stream, ",\n");
516
517 fmt = dc_debug_fmt_scope_end(fmt);
518 dc_debug_fmt_print(fmt, stream, "},\n");
519 }
520
521 fmt = dc_debug_fmt_scope_end(fmt);
522 dc_debug_fmt_print(fmt, stream, "}");
523}
static void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
Definition template.h:62
static ITER_CONST get_iter_const(SELF const *self)
Definition template.h:449
#define VALUE_DEBUG
Definition template.h:39
static IV_PAIR next(ITER *iter)
Definition template.h:352
static bool empty_item(IV_PAIR const *item)
Definition template.h:344
#define ITER_CONST
Definition template.h:398
IV_PAIR item
Definition template.h:283
#define KEY_DEBUG
Definition template.h:43
#define KV_PAIR_CONST
Definition template.h:526
dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:39
dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:33
static void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:22
#define EXPAND_STRING(NAME)
Definition namespace.h:8
static FILE * stream(SELF *self)
Opens a file for.
Definition template.h:107

◆ delete()

void delete ( SELF * self)
static

Definition at line 423 of file template.h.

423 {
424
425 for (size_t i = 0; i < self->capacity; i++) {
426 if (dc_swiss_is_present(self->ctrl[i])) {
427 KEY_DELETE(&self->slots[i].key);
428 VALUE_DELETE(&self->slots[i].value);
429 }
430 }
431 NS(ALLOC, free)(self->alloc, self->ctrl);
432 NS(ALLOC, free)(self->alloc, self->slots);
433}
static void free(SELF *self, void *ptr)
Definition template.h:56
#define VALUE_DELETE
Definition template.h:35
#define KEY_DELETE
Definition template.h:35
dc_swiss_ctrl * ctrl
Definition template.h:85
size_t capacity
Definition template.h:72
SLOT * slots
Definition template.h:71
ALLOC * alloc
Definition template.h:71

◆ delete_entry()

void delete_entry ( SELF * self,
KEY key )
static

Definition at line 405 of file template.h.

405 {
406 VALUE value = NS(SELF, remove)(self, key);
407 VALUE_DELETE(&value);
408}
static VALUE remove(SELF *self, INDEX index)
Definition template.h:292
#define VALUE
Definition template.h:31

◆ empty_item() [1/2]

bool empty_item ( KV_PAIR const * item)
static

Definition at line 542 of file template.h.

542 {
543 return item->key == NULL && item->value == NULL;
544}

◆ empty_item() [2/2]

bool empty_item ( KV_PAIR_CONST const * item)
static

Definition at line 449 of file template.h.

449 {
450 return item->key == NULL && item->value == NULL;
451}

◆ extend_capacity_for()

void extend_capacity_for ( SELF * self,
size_t expected_items )
static

Definition at line 261 of file template.h.

261 {
262 INVARIANT_CHECK(self);
264
265 size_t new_capacity = dc_swiss_capacity(expected_items);
266 if (new_capacity > self->capacity) {
267 PRIV(NS(SELF, rehash))(self, new_capacity);
268 }
269}
SLOT PRIV(block)[DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS)]
Definition template.h:73
static void PRIV rehash(SELF *self, size_t new_capacity)
Definition template.h:270
static size_t dc_swiss_capacity(size_t for_items)
Definition utils.h:44
static void mutation_tracker_mutate(mutation_tracker *self)
mutation_tracker iterator_invalidation_tracker
Definition template.h:85

◆ get_iter()

ITER get_iter ( SELF * self)
static

Definition at line 565 of file template.h.

565 {
566 INVARIANT_CHECK(self);
567
568 dc_swiss_optional_index index = 0;
569 PRIV(NS(SELF, next_populated_index))(self, &index);
570
571 return (ITER){
572 .map = self,
573 .next_index = index,
575 };
576}
#define ITER
Definition template.h:320
static void PRIV next_populated_index(SELF const *self, dc_swiss_optional_index *index)
Definition template.h:415
size_t dc_swiss_optional_index
Definition utils.h:82
static mutation_version mutation_tracker_get(mutation_tracker const *self)

◆ get_iter_const()

ITER_CONST get_iter_const ( SELF const * self)
static

Definition at line 472 of file template.h.

472 {
473 INVARIANT_CHECK(self);
474
475 dc_swiss_optional_index index = 0;
476 PRIV(NS(SELF, next_populated_index))(self, &index);
477
478 return (ITER_CONST){
479 .map = self,
480 .next_index = index,
481 .version = mutation_tracker_get(&self->iterator_invalidation_tracker),
482 };
483}

◆ insert()

VALUE * insert ( SELF * self,
KEY key,
VALUE value )
static

Definition at line 288 of file template.h.

288 {
289 VALUE* value_ptr = NS(SELF, try_insert)(self, key, value);
290 DC_ASSERT(value_ptr);
291 return value_ptr;
292}
static VALUE * try_insert(SELF *self, KEY key, VALUE value)
Definition template.h:328

◆ KEY_HASH()

size_t KEY_HASH ( KEY const * key)
static

◆ new()

SELF new ( ALLOC * alloc)
static

Definition at line 137 of file template.h.

137 {
139}
static SELF new_with_capacity_for(INDEX_TYPE items, ALLOC *alloc)
Definition template.h:96
#define DC_SWISS_INITIAL_CAPACITY
Definition utils.h:7

◆ new_with_capacity_for()

SELF new_with_capacity_for ( size_t for_items,
ALLOC * alloc )
static

Definition at line 131 of file template.h.

131 {
132 DC_ASSERT(for_items > 0);
133
134 return PRIV(NS(SELF, new_with_exact_capacity))(dc_swiss_capacity(for_items), alloc);
135}
static SELF PRIV new_with_exact_capacity(size_t capacity, ALLOC *alloc)
Definition template.h:157

◆ new_with_exact_capacity()

SELF PRIV new_with_exact_capacity ( size_t capacity,
ALLOC * alloc )
static

Definition at line 101 of file template.h.

101 {
104 size_t ctrl_capacity = capacity + DC_SWISS_SIMD_PROBE_SIZE;
105
106 dc_swiss_ctrl* ctrl =
107 (dc_swiss_ctrl*)NS(ALLOC, calloc)(alloc, sizeof(dc_swiss_ctrl), ctrl_capacity);
108 SLOT* slots = (SLOT*)NS(ALLOC, malloc)(alloc, sizeof(SLOT) * capacity);
109 DC_ASSERT(ctrl && slots);
110
111 for (size_t i = 0; i < capacity; i++) {
112 ctrl[i] = DC_SWISS_VAL_EMPTY;
113 }
115 for (size_t i = 1; i < DC_SWISS_SIMD_PROBE_SIZE; i++) {
116 ctrl[capacity + i] = ctrl[i - 1]; // currently empty
117 }
118
119 return (SELF){
120 .capacity = capacity,
121 .count = 0,
122 .tombstones = 0,
123 .ctrl = ctrl,
124 .slots = slots,
125 .alloc = alloc,
126 .derive_c_hashmap = dc_gdb_marker_new(),
127 .iterator_invalidation_tracker = mutation_tracker_new(),
128 };
129}
static void * calloc(SELF *self, size_t count, size_t size)
Definition template.h:34
#define DC_SWISS_VAL_EMPTY
Definition utils.h:18
#define DC_SWISS_VAL_SENTINEL
Definition utils.h:16

◆ next() [1/2]

KV_PAIR next ( ITER * iter)
static

Definition at line 546 of file template.h.

546 {
548
550 if (index == DC_SWISS_NO_INDEX) {
551 return (KV_PAIR){
552 .key = NULL,
553 .value = NULL,
554 };
555 }
556
557 iter->next_index++;
558 PRIV(NS(SELF, next_populated_index))(iter->map, &iter->next_index);
559 return (KV_PAIR){
560 .key = &iter->map->slots[index].key,
561 .value = &iter->map->slots[index].value,
562 };
563}
#define KV_PAIR
Definition template.h:584
#define DC_SWISS_NO_INDEX
Definition utils.h:81
static void mutation_version_check(mutation_version const *self)
INDEX_TYPE next_index
Definition template.h:325
mutation_version version
Definition template.h:326
SELF * map
Definition template.h:400

◆ next() [2/2]

KV_PAIR_CONST next ( ITER_CONST * iter)
static

Definition at line 453 of file template.h.

453 {
455
457 if (index == DC_SWISS_NO_INDEX) {
458 return (KV_PAIR_CONST){
459 .key = NULL,
460 .value = NULL,
461 };
462 }
463
464 iter->next_index++;
465 PRIV(NS(SELF, next_populated_index))(iter->map, &iter->next_index);
466 return (KV_PAIR_CONST){
467 .key = &iter->map->slots[index].key,
468 .value = &iter->map->slots[index].value,
469 };
470}
INDEX_TYPE next_index
Definition template.h:403
SELF const * map
Definition template.h:473
mutation_version version
Definition template.h:404

◆ next_populated_index()

void PRIV next_populated_index ( SELF const * self,
dc_swiss_optional_index * index )
static

Definition at line 415 of file template.h.

415 {
416 size_t i = *index;
417 while (i < self->capacity && !dc_swiss_is_present(self->ctrl[i])) {
418 ++i;
419 }
420 *index = (i == self->capacity) ? DC_SWISS_NO_INDEX : i;
421}

◆ read()

VALUE const * read ( SELF const * self,
KEY key )
static

Definition at line 330 of file template.h.

330 {
331 VALUE const* value = NS(SELF, try_read)(self, key);
332 DC_ASSERT(value);
333 return value;
334}
static VALUE const * try_read(SELF const *self, INDEX index)
Definition template.h:180

◆ rehash()

void PRIV rehash ( SELF * self,
size_t new_capacity )
static

Definition at line 235 of file template.h.

235 {
236 INVARIANT_CHECK(self);
237
238 // NOTE: This code also works for shrinking the hashmap
239 // - we never expect to do this, so are defensive.
240 // - We do expect to rehash with the same capacity (tombstone cleanup)
241 DC_ASSUME(new_capacity >= self->capacity);
243
244 SELF new_map = PRIV(NS(SELF, new_with_exact_capacity))(new_capacity, self->alloc);
245
246 for (size_t i = 0; i < self->capacity; i++) {
247 if (dc_swiss_is_present(self->ctrl[i])) {
248 (void)PRIV(NS(SELF, try_insert_no_extend_capacity))(&new_map, self->slots[i].key,
249 self->slots[i].value);
250 }
251 }
252
254
255 NS(ALLOC, free)(self->alloc, self->ctrl);
256 NS(ALLOC, free)(self->alloc, self->slots);
257
258 *self = new_map;
259}
static VALUE *PRIV try_insert_no_extend_capacity(SELF *self, KEY key, VALUE value)
Definition template.h:198

◆ remove()

VALUE remove ( SELF * self,
KEY key )
static

Definition at line 399 of file template.h.

399 {
400 VALUE value;
401 DC_ASSERT(NS(SELF, try_remove)(self, key, &value));
402 return value;
403}
static bool try_remove(SELF *self, INDEX index, VALUE *destination)
Definition template.h:264

◆ size()

size_t size ( SELF const * self)
static

Definition at line 410 of file template.h.

410 {
411 INVARIANT_CHECK(self);
412 return self->count;
413}

◆ try_insert()

VALUE * try_insert ( SELF * self,
KEY key,
VALUE value )
static

Definition at line 271 of file template.h.

271 {
272 INVARIANT_CHECK(self);
273
274 switch (dc_swiss_heuristic_should_extend(self->tombstones, self->count, self->capacity)) {
276 PRIV(NS(SELF, rehash))(self, self->capacity * 2);
277 break;
279 PRIV(NS(SELF, rehash))(self, self->capacity);
280 break;
282 break;
283 }
284
285 return PRIV(NS(SELF, try_insert_no_extend_capacity))(self, key, value);
286}
@ DC_SWISS_DO_NOTHING
Definition utils.h:62
@ DC_SWISS_DOUBLE_CAPACITY
Definition utils.h:60
@ DC_SWISS_CLEANUP_TOMBSONES
Definition utils.h:61
static dc_swiss_rehash_action dc_swiss_heuristic_should_extend(size_t tombstones, size_t count, size_t capacity)
Definition utils.h:65
size_t count
Definition template.h:76
size_t tombstones
Definition template.h:83

◆ try_insert_no_extend_capacity()

VALUE *PRIV try_insert_no_extend_capacity ( SELF * self,
KEY key,
VALUE value )
static

Definition at line 172 of file template.h.

172 {
173 INVARIANT_CHECK(self);
174 DC_ASSUME(self->count + self->tombstones < self->capacity);
176
177 const size_t mask = self->capacity - 1;
178
179 const size_t hash = KEY_HASH(&key);
180 const dc_swiss_id id = dc_swiss_id_from_hash(hash);
181
183
184 const size_t start = hash & mask;
185
186 for (size_t step = 0;; step += DC_SWISS_SIMD_PROBE_SIZE) {
187 const size_t group = (start + step) & mask;
188
189 // Scan the group once:
190 // - detect duplicates
191 // - remember first DELETED
192 // - stop at first EMPTY and insert (EMPTY terminates the probe)
193 for (size_t j = 0; j < DC_SWISS_SIMD_PROBE_SIZE; j++) {
194 const size_t i = (group + j) & mask;
195 const dc_swiss_ctrl c = self->ctrl[i];
196
197 switch (c) {
199 if (first_deleted == DC_SWISS_NO_INDEX) {
200 first_deleted = i;
201 }
202 break;
203
204 case DC_SWISS_VAL_EMPTY: {
205 bool const has_deleted = first_deleted != DC_SWISS_NO_INDEX;
206 const size_t ins = has_deleted ? first_deleted : i;
207 if (has_deleted) {
208 self->tombstones--;
209 }
210
211 self->slots[ins].key = key;
212 self->slots[ins].value = value;
213
214 dc_swiss_ctrl_set_at(self->ctrl, self->capacity, ins, (dc_swiss_ctrl)id);
215
216 self->count++;
217 return &self->slots[ins].value;
218 }
219
221 // Treat as not usable; keep scanning.
222 break;
223
224 default:
225 // Present slot: only a possible duplicate if the 7-bit id matches.
226 if (dc_swiss_ctrl_get_id(c) == id && KEY_EQ(&self->slots[i].key, &key)) {
227 return NULL; // duplicate exists
228 }
229 break;
230 }
231 }
232 }
233}
#define KEY_HASH
Definition template.h:26
#define KEY_EQ
Definition template.h:31
static void dc_swiss_ctrl_set_at(dc_swiss_ctrl *self, size_t capacity, size_t index, dc_swiss_ctrl val)
Definition utils.h:51
static dc_swiss_id dc_swiss_id_from_hash(size_t hash)
Definition utils.h:40
uint8_t dc_swiss_id
Definition utils.h:21
static uint8_t dc_swiss_ctrl_get_id(dc_swiss_ctrl ctrl)
Definition utils.h:35
#define DC_SWISS_VAL_DELETED
Definition utils.h:17

◆ try_read()

VALUE const * try_read ( SELF const * self,
KEY key )
static

Definition at line 294 of file template.h.

294 {
295 const size_t mask = self->capacity - 1;
296
297 const size_t hash = KEY_HASH(&key);
298 const dc_swiss_id id = dc_swiss_id_from_hash(hash);
299
300 const size_t start = hash & mask;
301
302 for (size_t step = 0;; step += DC_SWISS_SIMD_PROBE_SIZE) {
303 const size_t group = (start + step) & mask;
304
305 for (size_t j = 0; j < DC_SWISS_SIMD_PROBE_SIZE; j++) {
306 const size_t i = (group + j) & mask;
307 const dc_swiss_ctrl c = self->ctrl[i];
308
309 switch (c) {
311 // EMPTY terminates the probe: key does not exist
312 return NULL;
313
316 // Keep probing
317 break;
318
319 default:
320 // Present slot: check fingerprint, then full key
321 if (dc_swiss_ctrl_get_id(c) == id && KEY_EQ(&self->slots[i].key, &key)) {
322 return &self->slots[i].value;
323 }
324 break;
325 }
326 }
327 }
328}

◆ try_remove()

bool try_remove ( SELF * self,
KEY key,
VALUE * destination )
static

Definition at line 347 of file template.h.

347 {
348 INVARIANT_CHECK(self);
349
350 const size_t mask = self->capacity - 1;
351
352 const size_t hash = KEY_HASH(&key);
353 const dc_swiss_id id = dc_swiss_id_from_hash(hash);
354
355 const size_t start = hash & mask;
356
357 for (size_t step = 0;; step += DC_SWISS_SIMD_PROBE_SIZE) {
358 const size_t group = (start + step) & mask;
359
360 for (size_t j = 0; j < DC_SWISS_SIMD_PROBE_SIZE; j++) {
361 const size_t i = (group + j) & mask;
362 const dc_swiss_ctrl c = self->ctrl[i];
363
364 switch (c) {
366 // EMPTY terminates probe: key not present
367 return false;
368
371 // keep probing
372 break;
373
374 default:
375 // Present slot: check fingerprint, then full key
376 if (dc_swiss_ctrl_get_id(c) != id) {
377 break;
378 }
379 if (!KEY_EQ(&self->slots[i].key, &key)) {
380 break;
381 }
382
383 // Found
384 if (destination != NULL) {
385 *destination = self->slots[i].value;
386 }
387
388 // Mark tombstone (must NOT become EMPTY)
390
391 self->count--;
392 self->tombstones++;
393 return true;
394 }
395 }
396 }
397}

◆ try_write()

VALUE * try_write ( SELF * self,
KEY key )
static

Definition at line 336 of file template.h.

336 {
337 INVARIANT_CHECK(self);
338 return (VALUE*)NS(SELF, try_read)((SELF const*)self, key);
339}

◆ write()

VALUE * write ( SELF * self,
KEY key )
static

Definition at line 341 of file template.h.

341 {
342 VALUE* value = NS(SELF, try_write)(self, key);
343 DC_ASSERT(value);
344 return value;
345}
static VALUE * try_write(SELF *self, INDEX index)
Definition template.h:205