From 1c7433b46d4546ae5d387c82e72fac21eb587a2d Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Mon, 5 Oct 2026 19:40:05 -0700 Subject: [PATCH] Added index [skip ci] --- src/hnsw.h | 5 +++-- src/hnswscan.c | 10 +++++----- src/hnswutils.c | 13 ++++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/hnsw.h b/src/hnsw.h index adc5466..36114a6 100644 --- a/src/hnsw.h +++ b/src/hnsw.h @@ -410,6 +410,7 @@ typedef union typedef struct HnswSearchState { HnswQuery q; + Relation index; HnswSupport *support; } HnswSearchState; @@ -469,14 +470,14 @@ bool HnswCheckNorm(HnswSupport * support, Datum value); Buffer HnswNewBuffer(Relation index, ForkNumber forkNum); void HnswInitPage(Buffer buf, Page page); void HnswInit(void); -List *HnswSearchLayer(char *base, HnswSearchState * searchState, List *ep, int ef, int lc, Relation index, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples); +List *HnswSearchLayer(char *base, HnswSearchState * searchState, List *ep, int ef, int lc, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples); HnswElement HnswGetEntryPoint(Relation index); void HnswGetMetaPageInfo(Relation index, int *m, int *dimensions, HnswElement * entryPoint); void *HnswAlloc(HnswAllocator * allocator, Size size); HnswElement HnswInitElement(char *base, ItemPointer tid, int m, double ml, int maxLevel, HnswAllocator * alloc); HnswElement HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno); void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, HnswSupport * support, int m, int efConstruction, bool existing); -HnswSearchCandidate *HnswEntryCandidate(char *base, HnswElement entryPoint, HnswSearchState * searchState, Relation index, bool loadVec); +HnswSearchCandidate *HnswEntryCandidate(char *base, HnswElement entryPoint, HnswSearchState * searchState, bool loadVec); void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum, bool building); void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m); void HnswAddHeapTid(HnswElement element, ItemPointer heaptid); diff --git a/src/hnswscan.c b/src/hnswscan.c index 42cfa12..d486f98 100644 --- a/src/hnswscan.c +++ b/src/hnswscan.c @@ -44,21 +44,22 @@ GetScanItems(IndexScanDesc scan, Datum value) HnswCheckDim(dimensions, so->typeInfo, support->collation, value); searchState->q.value = value; + searchState->index = index; searchState->support = support; so->m = m; if (entryPoint == NULL) return NIL; - ep = list_make1(HnswEntryCandidate(base, entryPoint, searchState, index, false)); + ep = list_make1(HnswEntryCandidate(base, entryPoint, searchState, false)); for (int lc = entryPoint->level; lc >= 1; lc--) { - w = HnswSearchLayer(base, searchState, ep, 1, lc, index, m, false, NULL, NULL, NULL, true, NULL); + w = HnswSearchLayer(base, searchState, ep, 1, lc, m, false, NULL, NULL, NULL, true, NULL); ep = w; } - return HnswSearchLayer(base, searchState, ep, hnsw_ef_search, 0, index, m, false, NULL, &so->v, hnsw_iterative_scan != HNSW_ITERATIVE_SCAN_OFF ? &so->discarded : NULL, true, &so->tuples); + return HnswSearchLayer(base, searchState, ep, hnsw_ef_search, 0, m, false, NULL, &so->v, hnsw_iterative_scan != HNSW_ITERATIVE_SCAN_OFF ? &so->discarded : NULL, true, &so->tuples); } /* @@ -68,7 +69,6 @@ static List * ResumeScanItems(IndexScanDesc scan) { HnswScanOpaque so = (HnswScanOpaque) scan->opaque; - Relation index = scan->indexRelation; List *ep = NIL; char *base = NULL; int batch_size = hnsw_ef_search; @@ -89,7 +89,7 @@ ResumeScanItems(IndexScanDesc scan) ep = lappend(ep, sc); } - return HnswSearchLayer(base, &so->searchState, ep, batch_size, 0, index, so->m, false, NULL, &so->v, &so->discarded, false, &so->tuples); + return HnswSearchLayer(base, &so->searchState, ep, batch_size, 0, so->m, false, NULL, &so->v, &so->discarded, false, &so->tuples); } /* diff --git a/src/hnswutils.c b/src/hnswutils.c index f4b5168..a3ea719 100644 --- a/src/hnswutils.c +++ b/src/hnswutils.c @@ -612,8 +612,9 @@ HnswInitSearchCandidate(char *base, HnswElement element, double distance) * Create a candidate for the entry point */ HnswSearchCandidate * -HnswEntryCandidate(char *base, HnswElement entryPoint, HnswSearchState * searchState, Relation index, bool loadVec) +HnswEntryCandidate(char *base, HnswElement entryPoint, HnswSearchState * searchState, bool loadVec) { + Relation index = searchState->index; bool inMemory = index == NULL; double distance; @@ -825,8 +826,9 @@ HnswLoadUnvisitedFromDisk(HnswElement element, HnswUnvisited * unvisited, int *u * Algorithm 2 from paper */ List * -HnswSearchLayer(char *base, HnswSearchState * searchState, List *ep, int ef, int lc, Relation index, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples) +HnswSearchLayer(char *base, HnswSearchState * searchState, List *ep, int ef, int lc, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples) { + Relation index = searchState->index; List *w = NIL; pairingheap *C = pairingheap_allocate(CompareNearestCandidates, NULL); pairingheap *W = pairingheap_allocate(CompareFurthestCandidates, NULL); @@ -1292,6 +1294,7 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint bool inMemory = index == NULL; searchState.q.value = HnswGetValue(base, element); + searchState.index = index; searchState.support = support; /* Precompute hash */ @@ -1303,13 +1306,13 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint return; /* Get entry point and level */ - ep = list_make1(HnswEntryCandidate(base, entryPoint, &searchState, index, true)); + ep = list_make1(HnswEntryCandidate(base, entryPoint, &searchState, true)); entryLevel = entryPoint->level; /* 1st phase: greedy search to insert level */ for (int lc = entryLevel; lc >= level + 1; lc--) { - w = HnswSearchLayer(base, &searchState, ep, 1, lc, index, m, true, skipElement, NULL, NULL, true, NULL); + w = HnswSearchLayer(base, &searchState, ep, 1, lc, m, true, skipElement, NULL, NULL, true, NULL); ep = w; } @@ -1328,7 +1331,7 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint List *lw = NIL; ListCell *lc2; - w = HnswSearchLayer(base, &searchState, ep, efConstruction, lc, index, m, true, skipElement, NULL, NULL, true, NULL); + w = HnswSearchLayer(base, &searchState, ep, efConstruction, lc, m, true, skipElement, NULL, NULL, true, NULL); /* Convert search candidates to candidates */ foreach(lc2, w)