From 3474f82d3fa8c9a67de27b2d4194db0678581327 Mon Sep 17 00:00:00 2001 From: Varik Matevosyan Date: Fri, 13 Oct 2023 20:01:16 +0400 Subject: [PATCH] Revert to fa_cache for node retriever (#203) --- src/hnsw/external_index.c | 8 +++--- src/hnsw/external_index.h | 3 ++- src/hnsw/fa_cache.h | 51 +++++++++++++++++++++++++++++++++++++++ src/hnsw/retriever.c | 3 +-- 4 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/hnsw/fa_cache.h diff --git a/src/hnsw/external_index.c b/src/hnsw/external_index.c index 1ad8d700a..e6cc73063 100644 --- a/src/hnsw/external_index.c +++ b/src/hnsw/external_index.c @@ -6,6 +6,7 @@ #include // GenericXLog #include #include +#include #include // BLCKSZ #include // Buffer #include @@ -583,8 +584,7 @@ void *ldb_wal_index_node_retriever(void *ctxp, int id) OffsetNumber offset, max_offset; Buffer buf = InvalidBuffer; bool idx_page_prelocked = false; - void *cached_node = cache_get_item(&ctx->node_cache, &id); - + void *cached_node = fa_cache_get(&ctx->fa_cache, id); if(cached_node != NULL) { return cached_node; } @@ -629,7 +629,7 @@ void *ldb_wal_index_node_retriever(void *ctxp, int id) LockBuffer(buf, BUFFER_LOCK_UNLOCK); } - cache_set_item(&ctx->node_cache, &id, nodepage->node); + fa_cache_insert(&ctx->fa_cache, id, nodepage->node); return nodepage->node; #endif @@ -671,7 +671,7 @@ void *ldb_wal_index_node_retriever_mut(void *ctxp, int id) for(offset = FirstOffsetNumber; offset <= max_offset; offset = OffsetNumberNext(offset)) { nodepage = (HnswIndexTuple *)PageGetItem(page, PageGetItemId(page, offset)); if(nodepage->id == (uint32)id) { - cache_set_item(&ctx->node_cache, &id, nodepage->node); + fa_cache_insert(&ctx->fa_cache, id, nodepage->node); return nodepage->node; } diff --git a/src/hnsw/external_index.h b/src/hnsw/external_index.h index d2dba03ec..6ba94182f 100644 --- a/src/hnsw/external_index.h +++ b/src/hnsw/external_index.h @@ -10,6 +10,7 @@ #include // Relation #include "extra_dirtied.h" +#include "fa_cache.h" #include "hnsw.h" #include "htab_cache.h" #include "options.h" @@ -89,7 +90,7 @@ typedef struct ExtraDirtiedBufs *extra_dirted; - HTABCache node_cache; + FullyAssociativeCache fa_cache; dlist_head takenbuffers; } RetrieverCtx; diff --git a/src/hnsw/fa_cache.h b/src/hnsw/fa_cache.h new file mode 100644 index 000000000..a43765a2b --- /dev/null +++ b/src/hnsw/fa_cache.h @@ -0,0 +1,51 @@ +#ifndef LDB_HNSW_FA_CACHE_H +#define LDB_HNSW_FA_CACHE_H +#include + +/* A fixed-size fully associative FIFO cache meant to be embedded + * in other data structures for inline caching. + * Currently a naive loop is used for lookup, but we could use + * intrinsics to speed this up + * We could also experiment with better cache replacement policies here + * (CLOCK, 2 lists, etc) + */ + +#define FA_CACHE_SIZE 64 + +typedef struct +{ + int keys[ FA_CACHE_SIZE ]; + void* values[ FA_CACHE_SIZE ]; + int next; +} FullyAssociativeCache; + +// Initalize the cache so all lookups return NULL +static inline void fa_cache_init(FullyAssociativeCache* cache) +{ + // All values are set to NULL with the below + // so if key 0 is looked up before key 0 is inserted + // the data strucutre will returned the default value for key + // which will be NULL + MemSet(cache, 0, sizeof(FullyAssociativeCache)); +} + +// Insert the key value pair into an already initialized cache +static inline void fa_cache_insert(FullyAssociativeCache* cache, int key, void* value) +{ + cache->keys[ cache->next ] = key; + cache->values[ cache->next ] = value; + cache->next = (cache->next + 1) % FA_CACHE_SIZE; +} + +// Get the value associated with the key +static inline void* fa_cache_get(FullyAssociativeCache* cache, int key) +{ + for(int i = 0; i < FA_CACHE_SIZE; i++) { + if(cache->keys[ i ] == key) { + return cache->values[ i ]; + } + } + return NULL; +} + +#endif // LDB_HNSW_FA_CACHE_H diff --git a/src/hnsw/retriever.c b/src/hnsw/retriever.c index 71a42861c..1b6a5965d 100644 --- a/src/hnsw/retriever.c +++ b/src/hnsw/retriever.c @@ -20,7 +20,7 @@ RetrieverCtx *ldb_wal_retriever_area_init(Relation index_rel, HnswIndexHeaderPag ctx->header_page_under_wal = header_page_under_wal; ctx->extra_dirted = extra_dirtied_new(); - ctx->node_cache = cache_create("NodeCache"); + fa_cache_init(&ctx->fa_cache); dlist_init(&ctx->takenbuffers); @@ -55,7 +55,6 @@ void ldb_wal_retriever_area_reset(RetrieverCtx *ctx, HnswIndexHeaderPage *header void ldb_wal_retriever_area_fini(RetrieverCtx *ctx) { cache_destroy(&ctx->block_numbers_cache); - cache_destroy(&ctx->node_cache); dlist_mutable_iter miter; dlist_foreach_modify(miter, &ctx->takenbuffers) {