mirror of
https://github.com/pgvector/pgvector.git
synced 2026-10-23 10:48:54 +03:00
Added index [skip ci]
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user