mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-11 15:16:54 +08:00
Update neighbor tuples in-place for HNSW vacuum
This commit is contained in:
@@ -354,7 +354,6 @@ typedef struct HnswVacuumState
|
|||||||
/* Variables */
|
/* Variables */
|
||||||
struct tidhash_hash *deleted;
|
struct tidhash_hash *deleted;
|
||||||
BufferAccessStrategy bas;
|
BufferAccessStrategy bas;
|
||||||
HnswNeighborTuple ntup;
|
|
||||||
HnswElementData highestPoint;
|
HnswElementData highestPoint;
|
||||||
|
|
||||||
/* Memory */
|
/* Memory */
|
||||||
|
|||||||
@@ -198,8 +198,8 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme
|
|||||||
FmgrInfo *procinfo = vacuumstate->procinfo;
|
FmgrInfo *procinfo = vacuumstate->procinfo;
|
||||||
Oid collation = vacuumstate->collation;
|
Oid collation = vacuumstate->collation;
|
||||||
BufferAccessStrategy bas = vacuumstate->bas;
|
BufferAccessStrategy bas = vacuumstate->bas;
|
||||||
HnswNeighborTuple ntup = vacuumstate->ntup;
|
ItemId itemid;
|
||||||
Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m);
|
HnswNeighborTuple ntup;
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
|
|
||||||
/* Skip if element is entry point */
|
/* Skip if element is entry point */
|
||||||
@@ -213,19 +213,19 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme
|
|||||||
/* Find neighbors for element, skipping itself */
|
/* Find neighbors for element, skipping itself */
|
||||||
HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, true);
|
HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, true);
|
||||||
|
|
||||||
/* Update neighbor tuple */
|
|
||||||
/* Do this before getting page to minimize locking */
|
|
||||||
HnswSetNeighborTuple(base, ntup, element, m);
|
|
||||||
|
|
||||||
/* Get neighbor page */
|
/* Get neighbor page */
|
||||||
buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas);
|
buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas);
|
||||||
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
|
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
|
||||||
state = GenericXLogStart(index);
|
state = GenericXLogStart(index);
|
||||||
page = GenericXLogRegisterBuffer(state, buf, 0);
|
page = GenericXLogRegisterBuffer(state, buf, 0);
|
||||||
|
itemid = PageGetItemId(page, element->neighborOffno);
|
||||||
|
ntup = (HnswNeighborTuple) PageGetItem(page, itemid);
|
||||||
|
|
||||||
/* Overwrite tuple */
|
/* Check expected size */
|
||||||
if (!PageIndexTupleOverwrite(page, element->neighborOffno, (Item) ntup, ntupSize))
|
Assert(ItemIdGetLength(itemid) == HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m));
|
||||||
elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index));
|
|
||||||
|
/* Update page in-place */
|
||||||
|
HnswSetNeighborTuple(base, ntup, element, m);
|
||||||
|
|
||||||
/* Commit */
|
/* Commit */
|
||||||
GenericXLogFinish(state);
|
GenericXLogFinish(state);
|
||||||
@@ -588,7 +588,6 @@ InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkD
|
|||||||
vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD);
|
vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD);
|
||||||
vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC);
|
vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC);
|
||||||
vacuumstate->collation = index->rd_indcollation[0];
|
vacuumstate->collation = index->rd_indcollation[0];
|
||||||
vacuumstate->ntup = palloc0(BLCKSZ);
|
|
||||||
vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
|
vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
|
||||||
"Hnsw vacuum temporary context",
|
"Hnsw vacuum temporary context",
|
||||||
ALLOCSET_DEFAULT_SIZES);
|
ALLOCSET_DEFAULT_SIZES);
|
||||||
@@ -608,7 +607,6 @@ FreeVacuumState(HnswVacuumState * vacuumstate)
|
|||||||
{
|
{
|
||||||
tidhash_destroy(vacuumstate->deleted);
|
tidhash_destroy(vacuumstate->deleted);
|
||||||
FreeAccessStrategy(vacuumstate->bas);
|
FreeAccessStrategy(vacuumstate->bas);
|
||||||
pfree(vacuumstate->ntup);
|
|
||||||
MemoryContextDelete(vacuumstate->tmpCtx);
|
MemoryContextDelete(vacuumstate->tmpCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user