mirror of
https://github.com/pgvector/pgvector.git
synced 2026-06-29 17:21:16 +08:00
Fixed duplicate connections when repairing graph
This commit is contained in:
@@ -271,7 +271,7 @@ void HnswSetNeighborTuple(HnswNeighborTuple ntup, HnswElement e, int m);
|
||||
void HnswAddHeapTid(HnswElement element, ItemPointer heaptid);
|
||||
void HnswInitNeighbors(HnswElement element, int m);
|
||||
bool HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heapRel);
|
||||
void UpdateNeighborPages(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m);
|
||||
void UpdateNeighborPages(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting);
|
||||
void HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, Oid collation, bool loadVec);
|
||||
void HnswSetElementTuple(HnswElementTuple etup, HnswElement element);
|
||||
void HnswUpdateConnection(HnswElement element, HnswCandidate * hc, int m, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation);
|
||||
|
||||
@@ -283,11 +283,28 @@ WriteNewElementPages(Relation index, HnswElement e, int m, BlockNumber insertPag
|
||||
*updatedInsertPage = newInsertPage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if connection already exists
|
||||
*/
|
||||
static bool
|
||||
ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm)
|
||||
{
|
||||
for (int i = 0; i < lm; i++)
|
||||
{
|
||||
ItemPointer indextid = &ntup->indextids[startIdx + i];
|
||||
|
||||
if (ItemPointerGetBlockNumber(indextid) == e->blkno && ItemPointerGetOffsetNumber(indextid) == e->offno)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update neighbors
|
||||
*/
|
||||
void
|
||||
UpdateNeighborPages(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m)
|
||||
UpdateNeighborPages(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting)
|
||||
{
|
||||
for (int lc = e->level; lc >= 0; lc--)
|
||||
{
|
||||
@@ -339,7 +356,10 @@ UpdateNeighborPages(Relation index, FmgrInfo *procinfo, Oid collation, HnswEleme
|
||||
/* Calculate index for update */
|
||||
startIdx = (hc->element->level - lc) * m;
|
||||
|
||||
if (idx == -2)
|
||||
/* Check for existing connection */
|
||||
if (checkExisting && ConnectionExists(e, ntup, startIdx, lm))
|
||||
idx = -1;
|
||||
else if (idx == -2)
|
||||
{
|
||||
/* Find free offset if still exists */
|
||||
/* TODO Retry updating connections if not */
|
||||
@@ -496,7 +516,7 @@ WriteElement(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement elem
|
||||
HnswUpdateMetaPage(index, 0, NULL, newInsertPage, MAIN_FORKNUM);
|
||||
|
||||
/* Update neighbors */
|
||||
UpdateNeighborPages(index, procinfo, collation, element, m);
|
||||
UpdateNeighborPages(index, procinfo, collation, element, m, false);
|
||||
|
||||
/* Update metapage if needed */
|
||||
if (element->level > entryPoint->level)
|
||||
|
||||
@@ -255,7 +255,7 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element)
|
||||
UnlockReleaseBuffer(buf);
|
||||
|
||||
/* Update neighbors */
|
||||
UpdateNeighborPages(index, procinfo, collation, element, m);
|
||||
UpdateNeighborPages(index, procinfo, collation, element, m, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user