Skip to content

Commit 507ca36

Browse files
committed
add lookup or insert
1 parent c2b5c67 commit 507ca36

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/hash.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,30 @@ R_xlen_t hash_lookup(const hashtab * h, SEXP key, R_xlen_t ifnotfound) {
9595
return ifnotfound; // # nocov
9696
}
9797

98+
R_xlen_t hash_lookup_or_insert(hashtab *h, SEXP key, R_xlen_t value) {
99+
struct hash_pair *cell = h->tb + hash_index(key, h->multiplier) % h->size, *end = h->tb + h->size - 1;
100+
for (size_t i = 0; i < h->size; ++i, cell = (cell == end ? h->tb : cell + 1)) {
101+
if (cell->key == key) {
102+
cell->value = value;
103+
return cell->value;
104+
} else if (!cell->key) {
105+
if (!h->free) internal_error(
106+
__func__, "no free slots left (full size=%zu)", h->size
107+
);
108+
--h->free;
109+
*cell = (struct hash_pair){.key = key, .value = value};
110+
return value; // insert here
111+
}
112+
}
113+
114+
internal_error( // # nocov
115+
__func__, "did not find a free slot for key %p; size=%zu, free=%zu",
116+
(void*)key, h->size, h->free
117+
);
118+
// Should be impossible, but just in case:
119+
return value;
120+
}
121+
98122
typedef struct dhashtab_ {
99123
dhashtab public; // must be at offset 0
100124
size_t size, used, limit;

0 commit comments

Comments
 (0)