Skip to content

Commit 8623ded

Browse files
committed
Add dn_simdhash_ght_try_insert
1 parent 696d338 commit 8623ded

File tree

4 files changed

+64
-15
lines changed

4 files changed

+64
-15
lines changed

src/native/containers/dn-simdhash-ght-compatible.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,46 @@ dn_simdhash_ght_insert_replace (
164164
}
165165
}
166166

167+
dn_simdhash_add_result
168+
dn_simdhash_ght_try_insert (
169+
dn_simdhash_ght_t *hash,
170+
void *key, void *value,
171+
dn_simdhash_insert_mode mode
172+
)
173+
{
174+
check_self(hash);
175+
uint32_t key_hash = DN_SIMDHASH_KEY_HASHER(DN_SIMDHASH_GET_DATA(hash), key);
176+
177+
dn_simdhash_insert_result ok = DN_SIMDHASH_TRY_INSERT_INTERNAL(hash, key, key_hash, value, mode);
178+
if (ok == DN_SIMDHASH_INSERT_NEED_TO_GROW) {
179+
uint8_t grow_ok;
180+
dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, dn_simdhash_capacity(hash) + 1, &grow_ok);
181+
// The ghashtable API doesn't have a way to signal failure, so just assert that we didn't fail to grow
182+
if (!grow_ok)
183+
return DN_SIMDHASH_OUT_OF_MEMORY;
184+
185+
if (old_buffers.buckets) {
186+
DN_SIMDHASH_REHASH_INTERNAL(hash, old_buffers);
187+
dn_simdhash_free_buffers(old_buffers);
188+
}
189+
ok = DN_SIMDHASH_TRY_INSERT_INTERNAL(hash, key, key_hash, value, mode);
190+
}
191+
192+
switch (ok) {
193+
case DN_SIMDHASH_INSERT_OK_ADDED_NEW:
194+
hash->count++;
195+
return DN_SIMDHASH_ADD_INSERTED;
196+
case DN_SIMDHASH_INSERT_OK_OVERWROTE_EXISTING:
197+
return DN_SIMDHASH_ADD_OVERWROTE;
198+
case DN_SIMDHASH_INSERT_KEY_ALREADY_PRESENT:
199+
return DN_SIMDHASH_ADD_FAILED;
200+
case DN_SIMDHASH_INSERT_NEED_TO_GROW:
201+
default:
202+
assert(!"Internal error in dn_simdhash_ght_insert_replace");
203+
return DN_SIMDHASH_OUT_OF_MEMORY;
204+
}
205+
}
206+
167207
void *
168208
dn_simdhash_ght_get_value_or_default (
169209
dn_simdhash_ght_t *hash, void * key

src/native/containers/dn-simdhash-ght-compatible.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ dn_simdhash_ght_get_value_or_default (
3434
dn_simdhash_ght_t *hash, void * key
3535
);
3636

37+
dn_simdhash_add_result
38+
dn_simdhash_ght_try_insert (
39+
dn_simdhash_ght_t *hash,
40+
void *key, void *value,
41+
dn_simdhash_insert_mode mode
42+
);
43+
3744
// compatibility shims for the g_hash_table_ versions in glib.h
3845
#define dn_simdhash_ght_insert(h,k,v) dn_simdhash_ght_insert_replace ((h),(k),(v),FALSE)
3946
#define dn_simdhash_ght_replace(h,k,v) dn_simdhash_ght_insert_replace ((h),(k),(v),TRUE)

src/native/containers/dn-simdhash-specialization.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,17 +305,6 @@ DN_SIMDHASH_FIND_VALUE_INTERNAL (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key,
305305
return NULL;
306306
}
307307

308-
typedef enum dn_simdhash_insert_mode {
309-
// Ensures that no matching key exists in the hash, then adds the key/value pair
310-
DN_SIMDHASH_INSERT_MODE_ENSURE_UNIQUE,
311-
// If a matching key exists in the hash, overwrite its value but leave the key alone
312-
DN_SIMDHASH_INSERT_MODE_OVERWRITE_VALUE,
313-
// If a matching key exists in the hash, overwrite both the key and the value
314-
DN_SIMDHASH_INSERT_MODE_OVERWRITE_KEY_AND_VALUE,
315-
// Do not scan for existing matches before adding the new key/value pair.
316-
DN_SIMDHASH_INSERT_MODE_REHASHING,
317-
} dn_simdhash_insert_mode;
318-
319308
static void
320309
do_overwrite (
321310
DN_SIMDHASH_T_PTR hash, uint32_t bucket_index, bucket_t *bucket_address, int index_in_bucket,

src/native/containers/dn-simdhash.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,29 @@ typedef struct dn_simdhash_t dn_simdhash_t;
4848

4949
typedef struct dn_simdhash_meta_t {
5050
// type metadata for generic implementation
51+
// NOTE: key_size and value_size are not used consistently by every part of the implementation,
52+
// a specialization is still strongly typed based on its KEY_T and VALUE_T. But they need to match.
5153
uint32_t bucket_capacity, bucket_size_bytes, key_size, value_size,
5254
// Allocate this many bytes of extra data inside the dn_simdhash_t
5355
data_size;
5456
} dn_simdhash_meta_t;
5557

58+
typedef enum dn_simdhash_insert_mode {
59+
// Ensures that no matching key exists in the hash, then adds the key/value pair
60+
DN_SIMDHASH_INSERT_MODE_ENSURE_UNIQUE,
61+
// If a matching key exists in the hash, overwrite its value but leave the key alone
62+
DN_SIMDHASH_INSERT_MODE_OVERWRITE_VALUE,
63+
// If a matching key exists in the hash, overwrite both the key and the value
64+
DN_SIMDHASH_INSERT_MODE_OVERWRITE_KEY_AND_VALUE,
65+
// Do not scan for existing matches before adding the new key/value pair.
66+
DN_SIMDHASH_INSERT_MODE_REHASHING,
67+
} dn_simdhash_insert_mode;
68+
5669
typedef enum dn_simdhash_add_result {
57-
DN_SIMDHASH_OUT_OF_MEMORY = -1,
58-
DN_SIMDHASH_ADD_FAILED = 0,
59-
DN_SIMDHASH_ADD_INSERTED = 1,
60-
DN_SIMDHASH_ADD_OVERWROTE = 2,
70+
DN_SIMDHASH_OUT_OF_MEMORY = -1,
71+
DN_SIMDHASH_ADD_FAILED = 0,
72+
DN_SIMDHASH_ADD_INSERTED = 1,
73+
DN_SIMDHASH_ADD_OVERWROTE = 2,
6174
} dn_simdhash_add_result;
6275

6376
typedef enum dn_simdhash_insert_result {

0 commit comments

Comments
 (0)