*/
#if defined(__GNUC__) || defined(__CLANG__)
#define PREFETCH_NEIGHBORHOOD(x) __builtin_prefetch(x.entries)
+#define PREFETCH(x) __builtin_prefetch(x)
#else
#define PREFETCH_NEIGHBORHOOD(x)
+#define PREFETCH(x)
#endif
static ossl_unused uint64_t fnv1a_hash(uint8_t *key, size_t len)
* keys match if they are both present, the same size
* and compare equal in memory
*/
- if (a != NULL && b != NULL && a->keysize == b->keysize)
+ PREFETCH(a->keybuf);
+ PREFETCH(b->keybuf);
+ if (a->keybuf != NULL && b->keybuf != NULL && a->keysize == b->keysize)
return !memcmp(a->keybuf, b->keybuf, a->keysize);
return 1;
if (ival == NULL)
empty_idx = j;
- if (compare_hash(hash, ihash)) {
+ if (compare_hash(hash, ihash) && match_key(&newval->value.key,
+ &ival->key)) {
/* Its the same hash, lets make sure its not a collision */
- if (match_key(&newval->value.key, &ival->key)) {
- if (olddata == NULL) {
- /* invalid */
- return 0;
- }
+ if (olddata == NULL) {
+ /* invalid */
+ return 0;
}
/* Do a replacement */
if (!CRYPTO_atomic_store(&md->neighborhoods[neigh_idx].entries[j].hash,
int ossl_ht_delete(HT *h, HT_KEY *key)
{
- struct ht_mutable_data_st *md = ossl_rcu_deref(&h->md);
uint64_t hash;
uint64_t neigh_idx;
size_t j;
PREFETCH_NEIGHBORHOOD(h->md->neighborhoods[neigh_idx]);
for (j = 0; j < NEIGHBORHOOD_LEN; j++) {
v = (struct ht_internal_value_st *)h->md->neighborhoods[neigh_idx].entries[j].value;
- if (compare_hash(hash, h->md->neighborhoods[neigh_idx].entries[j].hash)) {
- if (!match_key(key, &v->value.key))
- continue;
+ if (compare_hash(hash, h->md->neighborhoods[neigh_idx].entries[j].hash)
+ && match_key(key, &v->value.key)) {
if (!CRYPTO_atomic_store(&h->md->neighborhoods[neigh_idx].entries[j].hash,
0, h->atomic_lock))
break;