diff --git a/src/hnsw.h b/src/hnsw.h index 1babe02..4dba028 100644 --- a/src/hnsw.h +++ b/src/hnsw.h @@ -103,7 +103,8 @@ typedef struct HnswNeighborArray HnswNeighborArray; typedef struct HnswElementData { - List *heaptids; + ItemPointerData heaptids[HNSW_HEAPTIDS]; + uint8 heaptidsLength; uint8 level; uint8 deleted; uint32 hash; diff --git a/src/hnswinsert.c b/src/hnswinsert.c index 5b6248e..0e23ee9 100644 --- a/src/hnswinsert.c +++ b/src/hnswinsert.c @@ -490,7 +490,7 @@ HnswAddDuplicate(Relation index, HnswElement element, HnswElement dup, bool buil } /* Add heap TID */ - etup->heaptids[i] = *((ItemPointer) linitial(element->heaptids)); + etup->heaptids[i] = element->heaptids[0]; /* Overwrite tuple */ if (!PageIndexTupleOverwrite(page, dup->offno, (Item) etup, etupSize)) diff --git a/src/hnswscan.c b/src/hnswscan.c index 7cf2bf0..48cd6ee 100644 --- a/src/hnswscan.c +++ b/src/hnswscan.c @@ -188,15 +188,13 @@ hnswgettuple(IndexScanDesc scan, ScanDirection dir) ItemPointer heaptid; /* Move to next element if no valid heap TIDs */ - if (list_length(hc->element->heaptids) == 0) + if (hc->element->heaptidsLength == 0) { so->w = list_delete_last(so->w); continue; } - heaptid = llast(hc->element->heaptids); - - hc->element->heaptids = list_delete_last(hc->element->heaptids); + heaptid = &hc->element->heaptids[--hc->element->heaptidsLength]; MemoryContextSwitchTo(oldCtx); diff --git a/src/hnswutils.c b/src/hnswutils.c index ed74f5a..57b8977 100644 --- a/src/hnswutils.c +++ b/src/hnswutils.c @@ -231,7 +231,7 @@ HnswInitElement(ItemPointer heaptid, int m, double ml, int maxLevel) if (level > maxLevel) level = maxLevel; - element->heaptids = NIL; + element->heaptidsLength = 0; HnswAddHeapTid(element, heaptid); element->level = level; @@ -251,7 +251,6 @@ void HnswFreeElement(HnswElement element) { HnswFreeNeighbors(element); - list_free_deep(element->heaptids); if (DatumGetPointer(element->value)) pfree(DatumGetPointer(element->value)); pfree(element); @@ -263,10 +262,7 @@ HnswFreeElement(HnswElement element) void HnswAddHeapTid(HnswElement element, ItemPointer heaptid) { - ItemPointer copy = palloc(sizeof(ItemPointerData)); - - ItemPointerCopy(heaptid, copy); - element->heaptids = lappend(element->heaptids, copy); + element->heaptids[element->heaptidsLength++] = *heaptid; } /* @@ -397,8 +393,8 @@ HnswSetElementTuple(HnswElementTuple etup, HnswElement element) etup->deleted = 0; for (int i = 0; i < HNSW_HEAPTIDS; i++) { - if (i < list_length(element->heaptids)) - etup->heaptids[i] = *((ItemPointer) list_nth(element->heaptids, i)); + if (i < element->heaptidsLength) + etup->heaptids[i] = element->heaptids[i]; else ItemPointerSetInvalid(&etup->heaptids[i]); } @@ -509,7 +505,7 @@ HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHe element->deleted = etup->deleted; element->neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - element->heaptids = NIL; + element->heaptidsLength = 0; if (loadHeaptids) { @@ -682,7 +678,7 @@ HnswSearchLayer(Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *pro * would be ideal to do this for inserts as well, but this could * affect insert performance. */ - if (skipElement == NULL || list_length(hc->element->heaptids) != 0) + if (skipElement == NULL || hc->element->heaptidsLength != 0) wlen++; } @@ -741,7 +737,7 @@ HnswSearchLayer(Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *pro * vacuuming. It would be ideal to do this for inserts as * well, but this could affect insert performance. */ - if (skipElement == NULL || list_length(e->element->heaptids) != 0) + if (skipElement == NULL || e->element->heaptidsLength != 0) { wlen++; @@ -953,7 +949,7 @@ HnswFindDuplicate(HnswElement e) break; /* Check for space */ - if (list_length(neighbor->element->heaptids) < HNSW_HEAPTIDS) + if (neighbor->element->heaptidsLength < HNSW_HEAPTIDS) return neighbor->element; } @@ -1014,7 +1010,7 @@ HnswUpdateConnection(HnswElement element, HnswCandidate * hc, int m, int lc, int hc3->distance = GetCandidateDistance(hc3, q, procinfo, collation); /* Prune element if being deleted */ - if (list_length(hc3->element->heaptids) == 0) + if (hc3->element->heaptidsLength == 0) { pruned = ¤tNeighbors->items[i]; break; @@ -1072,7 +1068,7 @@ RemoveElements(List *w, HnswElement skipElement) if (skipElement != NULL && hc->element->blkno == skipElement->blkno && hc->element->offno == skipElement->offno) continue; - if (list_length(hc->element->heaptids) != 0) + if (hc->element->heaptidsLength != 0) w2 = lappend(w2, hc); } diff --git a/src/hnswvacuum.c b/src/hnswvacuum.c index f11c362..96ac54c 100644 --- a/src/hnswvacuum.c +++ b/src/hnswvacuum.c @@ -206,7 +206,7 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme /* Init fields */ HnswInitNeighbors(element, m); - element->heaptids = NIL; + element->heaptidsLength = 0; /* Add element to graph, skipping itself */ HnswInsertElement(element, entryPoint, index, procinfo, collation, m, efConstruction, true);