mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-12 23:56:55 +08:00
Moved insert-specific code to hnswinsert.c
This commit is contained in:
@@ -364,6 +364,32 @@ HnswLoadNeighbors(HnswElement element, Relation index, int m, int lm, int lc)
|
|||||||
return neighbors;
|
return neighbors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load elements for insert
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
LoadElementsForInsert(HnswNeighborArray * neighbors, Datum q, int *idx, Relation index, FmgrInfo *procinfo, Oid collation)
|
||||||
|
{
|
||||||
|
char *base = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < neighbors->length; i++)
|
||||||
|
{
|
||||||
|
HnswCandidate *hc = &neighbors->items[i];
|
||||||
|
HnswElement element = HnswPtrAccess(base, hc->element);
|
||||||
|
double distance;
|
||||||
|
|
||||||
|
HnswLoadElement(element, &distance, &q, index, procinfo, collation, true, NULL);
|
||||||
|
hc->distance = distance;
|
||||||
|
|
||||||
|
/* Prune element if being deleted */
|
||||||
|
if (element->heaptidsLength == 0)
|
||||||
|
{
|
||||||
|
*idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if connection already exists
|
* Check if connection already exists
|
||||||
*/
|
*/
|
||||||
@@ -426,7 +452,17 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Select neighbors */
|
/* Select neighbors */
|
||||||
HnswUpdateConnection(NULL, e, hc, neighborNeighbors, lm, &idx, index, procinfo, collation);
|
if (neighbors->length < lm)
|
||||||
|
idx = -2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Datum q = HnswGetValue(base, neighborElement);
|
||||||
|
|
||||||
|
LoadElementsForInsert(neighborNeighbors, q, &idx, index, procinfo, collation);
|
||||||
|
|
||||||
|
if (idx == -1)
|
||||||
|
HnswUpdateConnection(base, e, hc, neighborNeighbors, lm, &idx, index, procinfo, collation);
|
||||||
|
}
|
||||||
|
|
||||||
/* New element was not selected as a neighbor */
|
/* New element was not selected as a neighbor */
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
|
|||||||
@@ -1074,39 +1074,12 @@ AddConnections(char *base, HnswElement element, List *neighbors, int lc)
|
|||||||
a->items[a->length++] = *((HnswCandidate *) lfirst(lc2));
|
a->items[a->length++] = *((HnswCandidate *) lfirst(lc2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Load elements for insert
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
LoadElementsForInsert(HnswNeighborArray * neighbors, Datum q, HnswCandidate * *pruned, Relation index, FmgrInfo *procinfo, Oid collation)
|
|
||||||
{
|
|
||||||
char *base = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < neighbors->length; i++)
|
|
||||||
{
|
|
||||||
HnswCandidate *hc = &neighbors->items[i];
|
|
||||||
HnswElement element = HnswPtrAccess(base, hc->element);
|
|
||||||
double distance;
|
|
||||||
|
|
||||||
HnswLoadElement(element, &distance, &q, index, procinfo, collation, true, NULL);
|
|
||||||
hc->distance = distance;
|
|
||||||
|
|
||||||
/* Prune element if being deleted */
|
|
||||||
if (element->heaptidsLength == 0)
|
|
||||||
{
|
|
||||||
*pruned = &neighbors->items[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update connections
|
* Update connections
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
HnswUpdateConnection(char *base, HnswElement newElement, HnswCandidate * hc, HnswNeighborArray * neighbors, int lm, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation)
|
HnswUpdateConnection(char *base, HnswElement newElement, HnswCandidate * hc, HnswNeighborArray * neighbors, int lm, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation)
|
||||||
{
|
{
|
||||||
HnswElement hce = HnswPtrAccess(base, hc->element);
|
|
||||||
HnswCandidate newHc;
|
HnswCandidate newHc;
|
||||||
|
|
||||||
HnswPtrStore(base, newHc.element, newElement);
|
HnswPtrStore(base, newHc.element, newElement);
|
||||||
@@ -1123,27 +1096,19 @@ HnswUpdateConnection(char *base, HnswElement newElement, HnswCandidate * hc, Hns
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Shrink connections */
|
/* Shrink connections */
|
||||||
|
List *c = NIL;
|
||||||
HnswCandidate *pruned = NULL;
|
HnswCandidate *pruned = NULL;
|
||||||
|
|
||||||
/* Load elements on insert */
|
/* Add candidates */
|
||||||
if (index != NULL)
|
for (int i = 0; i < neighbors->length; i++)
|
||||||
LoadElementsForInsert(neighbors, HnswGetValue(base, hce), &pruned, index, procinfo, collation);
|
c = lappend(c, &neighbors->items[i]);
|
||||||
|
c = lappend(c, &newHc);
|
||||||
|
|
||||||
|
SelectNeighbors(base, c, lm, procinfo, collation, neighbors, &newHc, &pruned, true);
|
||||||
|
|
||||||
|
/* Should not happen */
|
||||||
if (pruned == NULL)
|
if (pruned == NULL)
|
||||||
{
|
return;
|
||||||
List *c = NIL;
|
|
||||||
|
|
||||||
/* Add candidates */
|
|
||||||
for (int i = 0; i < neighbors->length; i++)
|
|
||||||
c = lappend(c, &neighbors->items[i]);
|
|
||||||
c = lappend(c, &newHc);
|
|
||||||
|
|
||||||
SelectNeighbors(base, c, lm, procinfo, collation, neighbors, &newHc, &pruned, true);
|
|
||||||
|
|
||||||
/* Should not happen */
|
|
||||||
if (pruned == NULL)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find and replace the pruned element */
|
/* Find and replace the pruned element */
|
||||||
for (int i = 0; i < neighbors->length; i++)
|
for (int i = 0; i < neighbors->length; i++)
|
||||||
|
|||||||
Reference in New Issue
Block a user