|
|
|
|
@@ -400,7 +400,7 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme
|
|
|
|
|
* Update graph in memory
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, HnswBuildState * buildstate)
|
|
|
|
|
UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, bool updateEntryPoint, HnswBuildState * buildstate)
|
|
|
|
|
{
|
|
|
|
|
HnswGraph *graph = buildstate->graph;
|
|
|
|
|
char *base = buildstate->hnswarea;
|
|
|
|
|
@@ -416,7 +416,7 @@ UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int
|
|
|
|
|
UpdateNeighborsInMemory(base, procinfo, collation, element, m);
|
|
|
|
|
|
|
|
|
|
/* Update entry point if needed (already have lock) */
|
|
|
|
|
if (entryPoint == NULL || element->level > entryPoint->level)
|
|
|
|
|
if (updateEntryPoint)
|
|
|
|
|
HnswPtrStore(base, graph->entryPoint, element);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -431,42 +431,32 @@ InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element)
|
|
|
|
|
HnswGraph *graph = buildstate->graph;
|
|
|
|
|
HnswElement entryPoint;
|
|
|
|
|
LWLock *entryLock = &graph->entryLock;
|
|
|
|
|
LWLock *entryWaitLock = &graph->entryWaitLock;
|
|
|
|
|
int efConstruction = buildstate->efConstruction;
|
|
|
|
|
int m = buildstate->m;
|
|
|
|
|
char *base = buildstate->hnswarea;
|
|
|
|
|
|
|
|
|
|
/* Wait if another process needs exclusive lock */
|
|
|
|
|
LWLockAcquire(entryWaitLock, LW_EXCLUSIVE);
|
|
|
|
|
LWLockRelease(entryWaitLock);
|
|
|
|
|
bool updateEntryPoint;
|
|
|
|
|
|
|
|
|
|
/* Get entry point */
|
|
|
|
|
LWLockAcquire(entryLock, LW_SHARED);
|
|
|
|
|
LWLockAcquire(entryLock, LW_EXCLUSIVE);
|
|
|
|
|
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
|
|
|
|
|
|
|
|
|
/* Prevent concurrent inserts when likely updating entry point */
|
|
|
|
|
if (entryPoint == NULL || element->level > entryPoint->level)
|
|
|
|
|
{
|
|
|
|
|
/* Release shared lock */
|
|
|
|
|
/* Pause new inserts when updating entry point */
|
|
|
|
|
/* May still be in-flight inserts */
|
|
|
|
|
updateEntryPoint = entryPoint == NULL || element->level > entryPoint->level;
|
|
|
|
|
|
|
|
|
|
/* Release entry lock */
|
|
|
|
|
if (!updateEntryPoint)
|
|
|
|
|
LWLockRelease(entryLock);
|
|
|
|
|
|
|
|
|
|
/* Get exclusive lock */
|
|
|
|
|
LWLockAcquire(entryWaitLock, LW_EXCLUSIVE);
|
|
|
|
|
LWLockAcquire(entryLock, LW_EXCLUSIVE);
|
|
|
|
|
LWLockRelease(entryWaitLock);
|
|
|
|
|
|
|
|
|
|
/* Get latest entry point after lock is acquired */
|
|
|
|
|
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find neighbors for element */
|
|
|
|
|
HnswFindElementNeighbors(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false);
|
|
|
|
|
|
|
|
|
|
/* Update graph in memory */
|
|
|
|
|
UpdateGraphInMemory(procinfo, collation, element, m, efConstruction, entryPoint, buildstate);
|
|
|
|
|
UpdateGraphInMemory(procinfo, collation, element, m, efConstruction, updateEntryPoint, buildstate);
|
|
|
|
|
|
|
|
|
|
/* Release entry lock */
|
|
|
|
|
LWLockRelease(entryLock);
|
|
|
|
|
if (updateEntryPoint)
|
|
|
|
|
LWLockRelease(entryLock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@@ -619,7 +609,6 @@ InitGraph(HnswGraph * graph, char *base, long memoryTotal)
|
|
|
|
|
graph->indtuples = 0;
|
|
|
|
|
SpinLockInit(&graph->lock);
|
|
|
|
|
LWLockInitialize(&graph->entryLock, hnsw_lock_tranche_id);
|
|
|
|
|
LWLockInitialize(&graph->entryWaitLock, hnsw_lock_tranche_id);
|
|
|
|
|
LWLockInitialize(&graph->allocatorLock, hnsw_lock_tranche_id);
|
|
|
|
|
LWLockInitialize(&graph->flushLock, hnsw_lock_tranche_id);
|
|
|
|
|
}
|
|
|
|
|
|