Add bulk_update for DICT OA
This commit is contained in:
1 parent
22d62f94bb
commit
ea5c993ff0
1 file changed
+63
@@ -2125,6 +2125,69 @@ M_F(name, _bulk_set)(dict_t dict, unsigned n, value_type const val[M_VLA(n)], ke
|
||||
} \
|
||||
M_D1CT_OA_CONTRACT (dict); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
M_INLINE void \
|
||||
M_F(name, _bulk_update)(dict_t dict, unsigned n, value_type val[M_VLA(n)], key_type const key[M_VLA(n)], value_type def, \
|
||||
void (*update)(dict_t dict, key_type const key, value_type *storeval, value_type *newval)) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT (dict); \
|
||||
size_t h[M_USE_MAX_PREFETCH]; \
|
||||
const unsigned num = M_MIN(M_USE_MAX_PREFETCH, n); \
|
||||
for(unsigned i = 0 ; i < num; i++) { \
|
||||
h[i] = M_CALL_HASH(key_oplist, key[i]); \
|
||||
M_PREFETCH(&dict->data[h[i] & dict->mask]); \
|
||||
} \
|
||||
\
|
||||
for (unsigned i = 0; i < n; i++) { \
|
||||
size_t p = h[i % M_USE_MAX_PREFETCH] & dict->mask; \
|
||||
if (i < n-M_USE_MAX_PREFETCH) { \
|
||||
h[i % M_USE_MAX_PREFETCH] = M_CALL_HASH(key_oplist, key[i+M_USE_MAX_PREFETCH]); \
|
||||
M_PREFETCH(&dict->data[h[i % M_USE_MAX_PREFETCH] & dict->mask]); \
|
||||
} \
|
||||
if (M_UNLIKELY (M_CALL_EQUAL(key_oplist, dict->data[p].key, key[i]))) { \
|
||||
update (dict, key[i], &dict->data[p].value, &val[i]); \
|
||||
continue; \
|
||||
} \
|
||||
/* Search loop for insertion */ \
|
||||
size_t s = 1; \
|
||||
size_t delPos = SIZE_MAX; \
|
||||
while (M_UNLIKELY (!M_CALL_OOR_EQUAL (key_oplist, dict->data[p].key, M_D1CT_OA_EMPTY)) ) { \
|
||||
if (M_CALL_EQUAL(key_oplist, dict->data[p].key, key[i])) { \
|
||||
update (dict, key[i], &dict->data[p].value, &val[i]); \
|
||||
goto next; \
|
||||
} \
|
||||
if (M_CALL_OOR_EQUAL (key_oplist, dict->data[p].key, M_D1CT_OA_DELETED) \
|
||||
&& (delPos == SIZE_MAX)) \
|
||||
delPos = p; \
|
||||
p = (p + M_D1CT_OA_PROBING(s)) & dict->mask; \
|
||||
} \
|
||||
/* Add new item */ \
|
||||
if (delPos != SIZE_MAX) { \
|
||||
p = delPos; \
|
||||
dict->count_delete --; \
|
||||
} \
|
||||
M_CALL_INIT_SET(key_oplist, dict->data[p].key, key[i]); \
|
||||
M_CALL_INIT_SET(value_oplist, dict->data[p].value, def); \
|
||||
update (dict, key[i], &dict->data[p].value, &val[i]); \
|
||||
dict->count++; \
|
||||
dict->count_delete ++; \
|
||||
\
|
||||
if (M_UNLIKELY (dict->count_delete >= dict->upper_limit)) { \
|
||||
size_t newSize = dict->mask+1; \
|
||||
if (dict->count > (dict->mask / 2)) { \
|
||||
newSize += newSize; \
|
||||
if (M_UNLIKELY_NOMEM (newSize <= dict->mask+1)) { \
|
||||
M_MEMORY_FULL((size_t)-1); \
|
||||
} \
|
||||
} \
|
||||
M_C3(m_d1ct_,name,_resize_up)(dict, newSize, true); \
|
||||
} \
|
||||
next: \
|
||||
(void)0; \
|
||||
} \
|
||||
M_D1CT_OA_CONTRACT (dict); \
|
||||
} \
|
||||
|
||||
/******************************** INTERNAL ***********************************/
|
||||
|
||||
|
||||
Reference in new issue
Block a user