mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-07 13:10:56 +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 HnswAddHeapTid(HnswElement element, ItemPointer heaptid);
|
||||||
void HnswInitNeighbors(HnswElement element, int m);
|
void HnswInitNeighbors(HnswElement element, int m);
|
||||||
bool HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heapRel);
|
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 HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, Oid collation, bool loadVec);
|
||||||
void HnswSetElementTuple(HnswElementTuple etup, HnswElement element);
|
void HnswSetElementTuple(HnswElementTuple etup, HnswElement element);
|
||||||
void HnswUpdateConnection(HnswElement element, HnswCandidate * hc, int m, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation);
|
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;
|
*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
|
* Update neighbors
|
||||||
*/
|
*/
|
||||||
void
|
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--)
|
for (int lc = e->level; lc >= 0; lc--)
|
||||||
{
|
{
|
||||||
@@ -339,7 +356,10 @@ UpdateNeighborPages(Relation index, FmgrInfo *procinfo, Oid collation, HnswEleme
|
|||||||
/* Calculate index for update */
|
/* Calculate index for update */
|
||||||
startIdx = (hc->element->level - lc) * m;
|
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 */
|
/* Find free offset if still exists */
|
||||||
/* TODO Retry updating connections if not */
|
/* 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);
|
HnswUpdateMetaPage(index, 0, NULL, newInsertPage, MAIN_FORKNUM);
|
||||||
|
|
||||||
/* Update neighbors */
|
/* Update neighbors */
|
||||||
UpdateNeighborPages(index, procinfo, collation, element, m);
|
UpdateNeighborPages(index, procinfo, collation, element, m, false);
|
||||||
|
|
||||||
/* Update metapage if needed */
|
/* Update metapage if needed */
|
||||||
if (element->level > entryPoint->level)
|
if (element->level > entryPoint->level)
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element)
|
|||||||
UnlockReleaseBuffer(buf);
|
UnlockReleaseBuffer(buf);
|
||||||
|
|
||||||
/* Update neighbors */
|
/* Update neighbors */
|
||||||
UpdateNeighborPages(index, procinfo, collation, element, m);
|
UpdateNeighborPages(index, procinfo, collation, element, m, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user