From c3bafc76e86f7e5cd300c1b68f190586d6582250 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Tue, 15 Aug 2023 12:31:06 -0700 Subject: [PATCH] Only update entry point on inserts if level is greater --- src/hnsw.h | 7 +++++-- src/hnswbuild.c | 2 +- src/hnswinsert.c | 6 +++--- src/hnswutils.c | 6 +++--- src/hnswvacuum.c | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/hnsw.h b/src/hnsw.h index c9aabf6..bc79c8a 100644 --- a/src/hnsw.h +++ b/src/hnsw.h @@ -44,6 +44,9 @@ /* Make graph robust against non-HOT updates */ #define HNSW_HEAPTIDS 10 +#define HNSW_UPDATE_ENTRY_GREATER 1 +#define HNSW_UPDATE_ENTRY_ALWAYS 2 + /* Build phases */ /* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 */ #define PROGRESS_HNSW_PHASE_LOAD 2 @@ -262,8 +265,8 @@ HnswElement HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno); void HnswInsertElement(HnswElement element, HnswElement entryPoint, Relation index, FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing); HnswElement HnswFindDuplicate(HnswElement e); HnswCandidate *HnswEntryCandidate(HnswElement em, Datum q, Relation rel, FmgrInfo *procinfo, Oid collation, bool loadVec); -void HnswUpdateMetaPageInfo(Page page, bool updateEntry, HnswElement entryPoint, BlockNumber insertPage); -void HnswUpdateMetaPage(Relation index, bool updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum); +void HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, BlockNumber insertPage); +void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum); void HnswSetNeighborTuple(HnswNeighborTuple ntup, HnswElement e, int m); void HnswAddHeapTid(HnswElement element, ItemPointer heaptid); void HnswInitNeighbors(HnswElement element, int m); diff --git a/src/hnswbuild.c b/src/hnswbuild.c index cd8c9e2..8cf5b75 100644 --- a/src/hnswbuild.c +++ b/src/hnswbuild.c @@ -183,7 +183,7 @@ CreateElementPages(HnswBuildState * buildstate) GenericXLogFinish(state); UnlockReleaseBuffer(buf); - HnswUpdateMetaPage(index, true, buildstate->entryPoint, insertPage, forkNum); + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_ALWAYS, buildstate->entryPoint, insertPage, forkNum); pfree(etup); pfree(ntup); diff --git a/src/hnswinsert.c b/src/hnswinsert.c index a3a4314..87e0dc6 100644 --- a/src/hnswinsert.c +++ b/src/hnswinsert.c @@ -410,7 +410,7 @@ HnswAddEntryPoint(Relation index, HnswElement element, int m, HnswElement * entr page = GenericXLogRegisterBuffer(state, buf, 0); /* Update the metapage info */ - HnswUpdateMetaPageInfo(page, true, element, newInsertPage); + HnswUpdateMetaPageInfo(page, HNSW_UPDATE_ENTRY_ALWAYS, element, newInsertPage); /* Commit and unlock */ HnswCommitBuffer(buf, state); @@ -488,14 +488,14 @@ WriteElement(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement elem /* Update insert page if needed */ if (BlockNumberIsValid(newInsertPage)) - HnswUpdateMetaPage(index, false, NULL, newInsertPage, MAIN_FORKNUM); + HnswUpdateMetaPage(index, 0, NULL, newInsertPage, MAIN_FORKNUM); /* Update neighbors */ UpdateNeighborPages(index, procinfo, collation, element, m); /* Update metapage if needed */ if (element->level > entryPoint->level) - HnswUpdateMetaPage(index, true, element, InvalidBlockNumber, MAIN_FORKNUM); + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM); } /* diff --git a/src/hnswutils.c b/src/hnswutils.c index 56db0ee..1beb4e9 100644 --- a/src/hnswutils.c +++ b/src/hnswutils.c @@ -237,7 +237,7 @@ HnswGetEntryPoint(Relation index) * Update the metapage info */ void -HnswUpdateMetaPageInfo(Page page, bool updateEntry, HnswElement entryPoint, BlockNumber insertPage) +HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, BlockNumber insertPage) { HnswMetaPage metap = HnswPageGetMeta(page); @@ -249,7 +249,7 @@ HnswUpdateMetaPageInfo(Page page, bool updateEntry, HnswElement entryPoint, Bloc metap->entryOffno = InvalidOffsetNumber; metap->entryLevel = -1; } - else + else if (entryPoint->level > metap->entryLevel || updateEntry == HNSW_UPDATE_ENTRY_ALWAYS) { metap->entryBlkno = entryPoint->blkno; metap->entryOffno = entryPoint->offno; @@ -265,7 +265,7 @@ HnswUpdateMetaPageInfo(Page page, bool updateEntry, HnswElement entryPoint, Bloc * Update the metapage */ void -HnswUpdateMetaPage(Relation index, bool updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum) +HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum) { Buffer buf; Page page; diff --git a/src/hnswvacuum.c b/src/hnswvacuum.c index e2f412d..2bf3eef 100644 --- a/src/hnswvacuum.c +++ b/src/hnswvacuum.c @@ -294,7 +294,7 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) ItemPointerSet(&epData, entryPoint->blkno, entryPoint->offno); if (DeletedContains(vacuumstate->deleted, &epData)) - HnswUpdateMetaPage(index, true, highestPoint, InvalidBlockNumber, MAIN_FORKNUM); + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_ALWAYS, highestPoint, InvalidBlockNumber, MAIN_FORKNUM); else { /* Highest point will be used to repair */ @@ -507,7 +507,7 @@ MarkDeleted(HnswVacuumState * vacuumstate) } /* Update insert page last, after everything has been marked as deleted */ - HnswUpdateMetaPage(index, false, NULL, insertPage, MAIN_FORKNUM); + HnswUpdateMetaPage(index, 0, NULL, insertPage, MAIN_FORKNUM); } /*