mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-12 15:46:54 +08:00
Use same locking as insert
This commit is contained in:
@@ -419,6 +419,7 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
Pointer valuePtr;
|
Pointer valuePtr;
|
||||||
bool updateEntryPoint;
|
bool updateEntryPoint;
|
||||||
LWLock *flushLock = &graph->flushLock;
|
LWLock *flushLock = &graph->flushLock;
|
||||||
|
LWLock *entryLock;
|
||||||
char *base = buildstate->hnswarea;
|
char *base = buildstate->hnswarea;
|
||||||
|
|
||||||
/* Detoast once for all calls */
|
/* Detoast once for all calls */
|
||||||
@@ -484,14 +485,26 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
/* Create element lock */
|
/* Create element lock */
|
||||||
LWLockInitialize(&element->lock, hnsw_lock_tranche_id);
|
LWLockInitialize(&element->lock, hnsw_lock_tranche_id);
|
||||||
|
|
||||||
/* Get entry point */
|
entryLock = &graph->entryLock;
|
||||||
LWLockAcquire(&graph->entryLock, LW_EXCLUSIVE);
|
updateEntryPoint = false;
|
||||||
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
|
||||||
updateEntryPoint = entryPoint == NULL || element->level > entryPoint->level;
|
|
||||||
|
|
||||||
/* Release lock if not updating entry point */
|
/* Get entry point */
|
||||||
if (!updateEntryPoint)
|
LWLockAcquire(entryLock, LW_SHARED);
|
||||||
LWLockRelease(&graph->entryLock);
|
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
||||||
|
|
||||||
|
/* Prevent concurrent inserts when likely updating entry point */
|
||||||
|
if (entryPoint == NULL || element->level > entryPoint->level)
|
||||||
|
{
|
||||||
|
/* Release shared lock */
|
||||||
|
LWLockRelease(entryLock);
|
||||||
|
|
||||||
|
/* Get exclusive lock */
|
||||||
|
LWLockAcquire(entryLock, LW_EXCLUSIVE);
|
||||||
|
|
||||||
|
/* Get latest entry point after lock is acquired */
|
||||||
|
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
||||||
|
updateEntryPoint = entryPoint == NULL || element->level > entryPoint->level;
|
||||||
|
}
|
||||||
|
|
||||||
/* Insert element in graph */
|
/* Insert element in graph */
|
||||||
HnswInsertElement(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false);
|
HnswInsertElement(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false);
|
||||||
@@ -499,9 +512,8 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
/* Write to memory */
|
/* Write to memory */
|
||||||
WriteElementInMemory(index, procinfo, collation, element, m, efConstruction, entryPoint, buildstate, graph, updateEntryPoint);
|
WriteElementInMemory(index, procinfo, collation, element, m, efConstruction, entryPoint, buildstate, graph, updateEntryPoint);
|
||||||
|
|
||||||
/* Release lock if needed */
|
/* Release entry lock */
|
||||||
if (updateEntryPoint)
|
LWLockRelease(entryLock);
|
||||||
LWLockRelease(&graph->entryLock);
|
|
||||||
|
|
||||||
/* Release flush lock */
|
/* Release flush lock */
|
||||||
LWLockRelease(flushLock);
|
LWLockRelease(flushLock);
|
||||||
|
|||||||
Reference in New Issue
Block a user