From 4de5b1ae4e6e8defe3f481a940ed60bd9ff975dc Mon Sep 17 00:00:00 2001 From: Nadav Gigi Date: Sat, 14 Dec 2024 22:04:29 +0000 Subject: [PATCH] Improving iterator using prefetch Signed-off-by: NadavGigi --- src/hashtable.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/hashtable.c b/src/hashtable.c index 11ba360800..60d0ef34b8 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -934,6 +934,32 @@ static inline incrementalFind *incrementalFindFromOpaque(hashtableIncrementalFin return (incrementalFind *)(void *)state; } +static void prefetchBucketEntries(bucket *b) { + if (b->chained) { + valkey_prefetch(bucketNext(b)); + } + for (int pos = 0; pos < numBucketPositions(b); pos++) { + if (isPositionFilled(b, pos)) { + valkey_prefetch(b->entries[pos]); + } + } +} + +static void prefetchNextFilledBucket(iter *iter, bucket *current_bucket) { + if (current_bucket->chained) { + prefetchBucketEntries(bucketNext(current_bucket)); + } else { + size_t table_size = numBuckets(iter->hashtable->bucket_exp[iter->table]); + for (size_t bucket_index = (size_t)iter->index + 1; bucket_index < table_size; bucket_index++) { + bucket *b = &iter->hashtable->tables[iter->table][bucket_index]; + if (b->presence) { + prefetchBucketEntries(b); + break; + } + } + } +} + /* --- API functions --- */ /* Allocates and initializes a new hashtable specified by the given type. */ @@ -1890,6 +1916,9 @@ int hashtableNext(hashtableIterator *iterator, void **elemptr) { } } bucket *b = iter->bucket; + if (iter->pos_in_bucket == 0 && b->presence) { + prefetchNextFilledBucket(iter, b); + } if (!isPositionFilled(b, iter->pos_in_bucket)) { /* No entry here. */ continue;