diff --git a/src/hnsw.h b/src/hnsw.h index a650005..7495e40 100644 --- a/src/hnsw.h +++ b/src/hnsw.h @@ -272,6 +272,7 @@ 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 HnswUpdateNeighborPages(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting); +void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, 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 HnswUpdateConnection(HnswElement element, HnswCandidate * hc, int m, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation); diff --git a/src/hnswutils.c b/src/hnswutils.c index 55a55ee..acfae8c 100644 --- a/src/hnswutils.c +++ b/src/hnswutils.c @@ -395,6 +395,37 @@ HnswLoadNeighbors(HnswElement element, Relation index) UnlockReleaseBuffer(buf); } +/* + * Load an element from a tuple + */ +void +HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec) +{ + element->level = etup->level; + element->deleted = etup->deleted; + element->neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); + element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); + element->heaptids = NIL; + + if (loadHeaptids) + { + for (int i = 0; i < HNSW_HEAPTIDS; i++) + { + /* Can stop at first invalid */ + if (!ItemPointerIsValid(&etup->heaptids[i])) + break; + + HnswAddHeapTid(element, &etup->heaptids[i]); + } + } + + if (loadVec) + { + element->vec = palloc(VECTOR_SIZE(etup->vec.dim)); + memcpy(element->vec, &etup->vec, VECTOR_SIZE(etup->vec.dim)); + } +} + /* * Load an element and optionally get its distance from q */ @@ -415,25 +446,7 @@ HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, Assert(HnswIsElementTuple(etup)); /* Load element */ - element->heaptids = NIL; - for (int i = 0; i < HNSW_HEAPTIDS; i++) - { - /* Can stop at first invalid */ - if (!ItemPointerIsValid(&etup->heaptids[i])) - break; - - HnswAddHeapTid(element, &etup->heaptids[i]); - } - element->level = etup->level; - element->neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); - element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - element->deleted = etup->deleted; - - if (loadVec) - { - element->vec = palloc(VECTOR_SIZE(etup->vec.dim)); - memcpy(element->vec, &etup->vec, VECTOR_SIZE(etup->vec.dim)); - } + HnswLoadElementFromTuple(element, etup, true, loadVec); /* Calculate distance */ if (distance != NULL) diff --git a/src/hnswvacuum.c b/src/hnswvacuum.c index 60e2410..ec16b6a 100644 --- a/src/hnswvacuum.c +++ b/src/hnswvacuum.c @@ -348,14 +348,8 @@ RepairGraph(HnswVacuumState * vacuumstate) continue; /* Create an element */ - element = palloc(sizeof(HnswElementData)); - element->neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); - element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - element->level = etup->level; - element->blkno = blkno; - element->offno = offno; - element->vec = palloc(VECTOR_SIZE(etup->vec.dim)); - memcpy(element->vec, &etup->vec, VECTOR_SIZE(etup->vec.dim)); + element = HnswInitElementFromBlock(blkno, offno); + HnswLoadElementFromTuple(element, etup, false, true); elements = lappend(elements, element); }