From e2f915c46b66295cb3d2cea9a21643eb2ab01271 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Sat, 12 Jul 2025 09:12:00 -0700 Subject: [PATCH] Use maintenance_io_concurrency where needed [skip ci] --- src/hnsw.h | 4 ++-- src/hnswbuild.c | 2 +- src/hnswinsert.c | 2 +- src/hnswscan.c | 6 +++--- src/hnswutils.c | 15 +++++++++------ src/hnswvacuum.c | 2 +- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/hnsw.h b/src/hnsw.h index 4af23a9..3f41afd 100644 --- a/src/hnsw.h +++ b/src/hnsw.h @@ -424,13 +424,13 @@ 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, HnswQuery * q, List *ep, int ef, int lc, Relation index, HnswSupport * support, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples); +List *HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation index, HnswSupport * support, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples, bool maintenance); HnswElement HnswGetEntryPoint(Relation index); void HnswGetMetaPageInfo(Relation index, int *m, 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); +void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, HnswSupport * support, int m, int efConstruction, bool existing, bool maintenance); HnswSearchCandidate *HnswEntryCandidate(char *base, HnswElement em, HnswQuery * q, Relation rel, HnswSupport * support, 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); diff --git a/src/hnswbuild.c b/src/hnswbuild.c index b667478..c54b8df 100644 --- a/src/hnswbuild.c +++ b/src/hnswbuild.c @@ -457,7 +457,7 @@ InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) } /* Find neighbors for element */ - HnswFindElementNeighbors(base, element, entryPoint, NULL, support, m, efConstruction, false); + HnswFindElementNeighbors(base, element, entryPoint, NULL, support, m, efConstruction, false, true); /* Update graph in memory */ UpdateGraphInMemory(support, element, m, efConstruction, entryPoint, buildstate); diff --git a/src/hnswinsert.c b/src/hnswinsert.c index a5fac4e..e9b5326 100644 --- a/src/hnswinsert.c +++ b/src/hnswinsert.c @@ -725,7 +725,7 @@ HnswInsertTupleOnDisk(Relation index, HnswSupport * support, Datum value, ItemPo } /* Find neighbors for element */ - HnswFindElementNeighbors(base, element, entryPoint, index, support, m, efConstruction, false); + HnswFindElementNeighbors(base, element, entryPoint, index, support, m, efConstruction, false, building); /* Update graph on disk */ UpdateGraphOnDisk(index, support, element, m, efConstruction, entryPoint, building); diff --git a/src/hnswscan.c b/src/hnswscan.c index 955998a..40de879 100644 --- a/src/hnswscan.c +++ b/src/hnswscan.c @@ -37,11 +37,11 @@ GetScanItems(IndexScanDesc scan, Datum value) for (int lc = entryPoint->level; lc >= 1; lc--) { - w = HnswSearchLayer(base, q, ep, 1, lc, index, support, m, false, NULL, NULL, NULL, true, NULL); + w = HnswSearchLayer(base, q, ep, 1, lc, index, support, m, false, NULL, NULL, NULL, true, NULL, false); ep = w; } - return HnswSearchLayer(base, q, ep, hnsw_ef_search, 0, index, support, m, false, NULL, &so->v, hnsw_iterative_scan != HNSW_ITERATIVE_SCAN_OFF ? &so->discarded : NULL, true, &so->tuples); + return HnswSearchLayer(base, q, ep, hnsw_ef_search, 0, index, support, m, false, NULL, &so->v, hnsw_iterative_scan != HNSW_ITERATIVE_SCAN_OFF ? &so->discarded : NULL, true, &so->tuples, false); } /* @@ -72,7 +72,7 @@ ResumeScanItems(IndexScanDesc scan) ep = lappend(ep, sc); } - return HnswSearchLayer(base, &so->q, ep, batch_size, 0, index, &so->support, so->m, false, NULL, &so->v, &so->discarded, false, &so->tuples); + return HnswSearchLayer(base, &so->q, ep, batch_size, 0, index, &so->support, so->m, false, NULL, &so->v, &so->discarded, false, &so->tuples, false); } /* diff --git a/src/hnswutils.c b/src/hnswutils.c index 5a178ad..724fbed 100644 --- a/src/hnswutils.c +++ b/src/hnswutils.c @@ -835,7 +835,7 @@ HnswReadStreamNextBlock(ReadStream *stream, void *callback_private_data, void *p * Algorithm 2 from paper */ List * -HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation index, HnswSupport * support, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples) +HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation index, HnswSupport * support, int m, bool inserting, HnswElement skipElement, visited_hash * v, pairingheap **discarded, bool initVisited, int64 *tuples, bool maintenance) { List *w = NIL; pairingheap *C = pairingheap_allocate(CompareNearestCandidates, NULL); @@ -854,9 +854,12 @@ HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation in HnswReadStreamData streamData; ReadStream *stream = NULL; - /* TODO Use READ_STREAM_MAINTENANCE when creating index or vacuuming */ if (!inMemory) - stream = read_stream_begin_relation(READ_STREAM_DEFAULT, NULL, index, MAIN_FORKNUM, HnswReadStreamNextBlock, &streamData, sizeof(OffsetNumber)); + { + int flags = maintenance ? READ_STREAM_MAINTENANCE : READ_STREAM_DEFAULT; + + stream = read_stream_begin_relation(flags, NULL, index, MAIN_FORKNUM, HnswReadStreamNextBlock, &streamData, sizeof(OffsetNumber)); + } #endif if (v == NULL) @@ -1326,7 +1329,7 @@ PrecomputeHash(char *base, HnswElement element) * Algorithm 1 from paper */ void -HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, HnswSupport * support, int m, int efConstruction, bool existing) +HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, HnswSupport * support, int m, int efConstruction, bool existing, bool maintenance) { List *ep; List *w; @@ -1353,7 +1356,7 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint /* 1st phase: greedy search to insert level */ for (int lc = entryLevel; lc >= level + 1; lc--) { - w = HnswSearchLayer(base, &q, ep, 1, lc, index, support, m, true, skipElement, NULL, NULL, true, NULL); + w = HnswSearchLayer(base, &q, ep, 1, lc, index, support, m, true, skipElement, NULL, NULL, true, NULL, maintenance); ep = w; } @@ -1372,7 +1375,7 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint List *lw = NIL; ListCell *lc2; - w = HnswSearchLayer(base, &q, ep, efConstruction, lc, index, support, m, true, skipElement, NULL, NULL, true, NULL); + w = HnswSearchLayer(base, &q, ep, efConstruction, lc, index, support, m, true, skipElement, NULL, NULL, true, NULL, maintenance); /* Convert search candidates to candidates */ foreach(lc2, w) diff --git a/src/hnswvacuum.c b/src/hnswvacuum.c index 2f7b2f3..07820af 100644 --- a/src/hnswvacuum.c +++ b/src/hnswvacuum.c @@ -208,7 +208,7 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme element->heaptidsLength = 0; /* Find neighbors for element, skipping itself */ - HnswFindElementNeighbors(base, element, entryPoint, index, support, m, efConstruction, true); + HnswFindElementNeighbors(base, element, entryPoint, index, support, m, efConstruction, true, true); /* Zero memory for each element */ MemSet(ntup, 0, HNSW_TUPLE_ALLOC_SIZE);