mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-13 16:16:56 +08:00
Improved locking code [skip ci]
This commit is contained in:
@@ -28,6 +28,10 @@
|
|||||||
#define HNSW_METAPAGE_BLKNO 0
|
#define HNSW_METAPAGE_BLKNO 0
|
||||||
#define HNSW_HEAD_BLKNO 1 /* first element page */
|
#define HNSW_HEAD_BLKNO 1 /* first element page */
|
||||||
|
|
||||||
|
/* Must correspond to page numbers since page lock is used */
|
||||||
|
#define HNSW_UPDATE_LOCK 0
|
||||||
|
#define HNSW_SCAN_LOCK 1
|
||||||
|
|
||||||
#define HNSW_DEFAULT_M 16
|
#define HNSW_DEFAULT_M 16
|
||||||
#define HNSW_MIN_M 2
|
#define HNSW_MIN_M 2
|
||||||
#define HNSW_MAX_M 100
|
#define HNSW_MAX_M 100
|
||||||
|
|||||||
@@ -519,7 +519,7 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti
|
|||||||
* Get a shared lock for the duration of the insert. Use a page lock so it
|
* Get a shared lock for the duration of the insert. Use a page lock so it
|
||||||
* does not interfere with buffer lock (or reads when vacuuming).
|
* does not interfere with buffer lock (or reads when vacuuming).
|
||||||
*/
|
*/
|
||||||
LockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
|
LockPage(index, HNSW_UPDATE_LOCK, lockmode);
|
||||||
|
|
||||||
/* Get entry point */
|
/* Get entry point */
|
||||||
entryPoint = HnswGetEntryPoint(index);
|
entryPoint = HnswGetEntryPoint(index);
|
||||||
@@ -528,11 +528,11 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti
|
|||||||
if (entryPoint == NULL || element->level > entryPoint->level)
|
if (entryPoint == NULL || element->level > entryPoint->level)
|
||||||
{
|
{
|
||||||
/* Release shared lock */
|
/* Release shared lock */
|
||||||
UnlockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
|
UnlockPage(index, HNSW_UPDATE_LOCK, lockmode);
|
||||||
|
|
||||||
/* Get exclusive lock */
|
/* Get exclusive lock */
|
||||||
lockmode = ExclusiveLock;
|
lockmode = ExclusiveLock;
|
||||||
LockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
|
LockPage(index, HNSW_UPDATE_LOCK, lockmode);
|
||||||
|
|
||||||
/* Get latest entry point after lock is acquired */
|
/* Get latest entry point after lock is acquired */
|
||||||
entryPoint = HnswGetEntryPoint(index);
|
entryPoint = HnswGetEntryPoint(index);
|
||||||
@@ -548,7 +548,7 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti
|
|||||||
WriteElement(index, procinfo, collation, element, m, efConstruction, dup, entryPoint);
|
WriteElement(index, procinfo, collation, element, m, efConstruction, dup, entryPoint);
|
||||||
|
|
||||||
/* Release shared lock */
|
/* Release shared lock */
|
||||||
UnlockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
|
UnlockPage(index, HNSW_UPDATE_LOCK, lockmode);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,9 +145,17 @@ hnswgettuple(IndexScanDesc scan, ScanDirection dir)
|
|||||||
HnswNormValue(so->normprocinfo, so->collation, &value, NULL);
|
HnswNormValue(so->normprocinfo, so->collation, &value, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
LockPage(scan->indexRelation, HNSW_HEAD_BLKNO, ShareLock);
|
/*
|
||||||
|
* Get a shared lock. This allows vacuum to ensure no in-flight scans
|
||||||
|
* before marking tuples as deleted.
|
||||||
|
*/
|
||||||
|
LockPage(scan->indexRelation, HNSW_SCAN_LOCK, ShareLock);
|
||||||
|
|
||||||
so->w = GetScanItems(scan, value);
|
so->w = GetScanItems(scan, value);
|
||||||
UnlockPage(scan->indexRelation, HNSW_HEAD_BLKNO, ShareLock);
|
|
||||||
|
/* Release shared lock */
|
||||||
|
UnlockPage(scan->indexRelation, HNSW_SCAN_LOCK, ShareLock);
|
||||||
|
|
||||||
so->first = false;
|
so->first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -316,8 +316,8 @@ RepairGraph(HnswVacuumState * vacuumstate)
|
|||||||
RepairGraphEntryPoint(vacuumstate);
|
RepairGraphEntryPoint(vacuumstate);
|
||||||
|
|
||||||
/* Wait for inserts to complete */
|
/* Wait for inserts to complete */
|
||||||
LockPage(index, HNSW_METAPAGE_BLKNO, ExclusiveLock);
|
LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock);
|
||||||
UnlockPage(index, HNSW_METAPAGE_BLKNO, ExclusiveLock);
|
UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock);
|
||||||
|
|
||||||
while (BlockNumberIsValid(blkno))
|
while (BlockNumberIsValid(blkno))
|
||||||
{
|
{
|
||||||
@@ -405,8 +405,8 @@ MarkDeleted(HnswVacuumState * vacuumstate)
|
|||||||
BufferAccessStrategy bas = vacuumstate->bas;
|
BufferAccessStrategy bas = vacuumstate->bas;
|
||||||
|
|
||||||
/* Wait for selects to complete */
|
/* Wait for selects to complete */
|
||||||
LockPage(index, HNSW_HEAD_BLKNO, ExclusiveLock);
|
LockPage(index, HNSW_SCAN_LOCK, ExclusiveLock);
|
||||||
UnlockPage(index, HNSW_HEAD_BLKNO, ExclusiveLock);
|
UnlockPage(index, HNSW_SCAN_LOCK, ExclusiveLock);
|
||||||
|
|
||||||
while (BlockNumberIsValid(blkno))
|
while (BlockNumberIsValid(blkno))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user