mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-22 20:15:46 +08:00
Compare commits
2 Commits
hnsw-debug
...
hnsw-entry
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abbc1c3379 | ||
|
|
72c20fc14f |
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.6.2 (unreleased)
|
||||||
|
|
||||||
|
- Improved performance of parallel HNSW index builds
|
||||||
|
|
||||||
## 0.6.1 (2024-03-04)
|
## 0.6.1 (2024-03-04)
|
||||||
|
|
||||||
- Fixed error with `ANALYZE` and vectors with different dimensions
|
- Fixed error with `ANALYZE` and vectors with different dimensions
|
||||||
|
|||||||
24
src/hnsw.c
24
src/hnsw.c
@@ -17,10 +17,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int hnsw_ef_search;
|
int hnsw_ef_search;
|
||||||
int hnsw_entry_lock_tranche_id;
|
int hnsw_lock_tranche_id;
|
||||||
int hnsw_allocator_lock_tranche_id;
|
|
||||||
int hnsw_flush_lock_tranche_id;
|
|
||||||
int hnsw_element_lock_tranche_id;
|
|
||||||
static relopt_kind hnsw_relopt_kind;
|
static relopt_kind hnsw_relopt_kind;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -39,27 +36,16 @@ HnswInitLockTranche(void)
|
|||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
|
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
|
||||||
tranche_ids = ShmemInitStruct("hnsw LWLock ids v2",
|
tranche_ids = ShmemInitStruct("hnsw LWLock ids",
|
||||||
sizeof(int) * 4,
|
sizeof(int) * 1,
|
||||||
&found);
|
&found);
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
|
||||||
tranche_ids[0] = LWLockNewTrancheId();
|
tranche_ids[0] = LWLockNewTrancheId();
|
||||||
tranche_ids[1] = LWLockNewTrancheId();
|
hnsw_lock_tranche_id = tranche_ids[0];
|
||||||
tranche_ids[2] = LWLockNewTrancheId();
|
|
||||||
tranche_ids[3] = LWLockNewTrancheId();
|
|
||||||
}
|
|
||||||
hnsw_entry_lock_tranche_id = tranche_ids[0];
|
|
||||||
hnsw_allocator_lock_tranche_id = tranche_ids[1];
|
|
||||||
hnsw_flush_lock_tranche_id = tranche_ids[2];
|
|
||||||
hnsw_element_lock_tranche_id = tranche_ids[3];
|
|
||||||
LWLockRelease(AddinShmemInitLock);
|
LWLockRelease(AddinShmemInitLock);
|
||||||
|
|
||||||
/* Per-backend registration of the tranche ID */
|
/* Per-backend registration of the tranche ID */
|
||||||
LWLockRegisterTranche(hnsw_entry_lock_tranche_id, "HnswEntry");
|
LWLockRegisterTranche(hnsw_lock_tranche_id, "HnswBuild");
|
||||||
LWLockRegisterTranche(hnsw_allocator_lock_tranche_id, "HnswAllocator");
|
|
||||||
LWLockRegisterTranche(hnsw_flush_lock_tranche_id, "HnswFlush");
|
|
||||||
LWLockRegisterTranche(hnsw_element_lock_tranche_id, "HnswElement");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -113,10 +113,7 @@
|
|||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
extern int hnsw_ef_search;
|
extern int hnsw_ef_search;
|
||||||
extern int hnsw_entry_lock_tranche_id;
|
extern int hnsw_lock_tranche_id;
|
||||||
extern int hnsw_allocator_lock_tranche_id;
|
|
||||||
extern int hnsw_flush_lock_tranche_id;
|
|
||||||
extern int hnsw_element_lock_tranche_id;
|
|
||||||
|
|
||||||
typedef struct HnswElementData HnswElementData;
|
typedef struct HnswElementData HnswElementData;
|
||||||
typedef struct HnswNeighborArray HnswNeighborArray;
|
typedef struct HnswNeighborArray HnswNeighborArray;
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme
|
|||||||
* Update graph in memory
|
* Update graph in memory
|
||||||
*/
|
*/
|
||||||
static void
|
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;
|
HnswGraph *graph = buildstate->graph;
|
||||||
char *base = buildstate->hnswarea;
|
char *base = buildstate->hnswarea;
|
||||||
@@ -416,7 +416,7 @@ UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int
|
|||||||
UpdateNeighborsInMemory(base, procinfo, collation, element, m);
|
UpdateNeighborsInMemory(base, procinfo, collation, element, m);
|
||||||
|
|
||||||
/* Update entry point if needed (already have lock) */
|
/* Update entry point if needed (already have lock) */
|
||||||
if (entryPoint == NULL || element->level > entryPoint->level)
|
if (updateEntryPoint)
|
||||||
HnswPtrStore(base, graph->entryPoint, element);
|
HnswPtrStore(base, graph->entryPoint, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,32 +434,29 @@ InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element)
|
|||||||
int efConstruction = buildstate->efConstruction;
|
int efConstruction = buildstate->efConstruction;
|
||||||
int m = buildstate->m;
|
int m = buildstate->m;
|
||||||
char *base = buildstate->hnswarea;
|
char *base = buildstate->hnswarea;
|
||||||
|
bool updateEntryPoint;
|
||||||
|
|
||||||
/* Get entry point */
|
/* Get entry point */
|
||||||
LWLockAcquire(entryLock, LW_SHARED);
|
LWLockAcquire(entryLock, LW_EXCLUSIVE);
|
||||||
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
||||||
|
|
||||||
/* Prevent concurrent inserts when likely updating entry point */
|
/* Pause new inserts when updating entry point */
|
||||||
if (entryPoint == NULL || element->level > entryPoint->level)
|
/* May still be in-flight inserts */
|
||||||
{
|
updateEntryPoint = entryPoint == NULL || element->level > entryPoint->level;
|
||||||
/* Release shared lock */
|
|
||||||
|
/* Release entry lock */
|
||||||
|
if (!updateEntryPoint)
|
||||||
LWLockRelease(entryLock);
|
LWLockRelease(entryLock);
|
||||||
|
|
||||||
/* Get exclusive lock */
|
|
||||||
LWLockAcquire(entryLock, LW_EXCLUSIVE);
|
|
||||||
|
|
||||||
/* Get latest entry point after lock is acquired */
|
|
||||||
entryPoint = HnswPtrAccess(base, graph->entryPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find neighbors for element */
|
/* Find neighbors for element */
|
||||||
HnswFindElementNeighbors(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false);
|
HnswFindElementNeighbors(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false);
|
||||||
|
|
||||||
/* Update graph in memory */
|
/* Update graph in memory */
|
||||||
UpdateGraphInMemory(procinfo, collation, element, m, efConstruction, entryPoint, buildstate);
|
UpdateGraphInMemory(procinfo, collation, element, m, efConstruction, updateEntryPoint, buildstate);
|
||||||
|
|
||||||
/* Release entry lock */
|
/* Release entry lock */
|
||||||
LWLockRelease(entryLock);
|
if (updateEntryPoint)
|
||||||
|
LWLockRelease(entryLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -548,7 +545,7 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
HnswPtrStore(base, element->value, valuePtr);
|
HnswPtrStore(base, element->value, valuePtr);
|
||||||
|
|
||||||
/* Create a lock for the element */
|
/* Create a lock for the element */
|
||||||
LWLockInitialize(&element->lock, hnsw_element_lock_tranche_id);
|
LWLockInitialize(&element->lock, hnsw_lock_tranche_id);
|
||||||
|
|
||||||
/* Insert tuple */
|
/* Insert tuple */
|
||||||
InsertTupleInMemory(buildstate, element);
|
InsertTupleInMemory(buildstate, element);
|
||||||
@@ -611,9 +608,9 @@ InitGraph(HnswGraph * graph, char *base, long memoryTotal)
|
|||||||
graph->flushed = false;
|
graph->flushed = false;
|
||||||
graph->indtuples = 0;
|
graph->indtuples = 0;
|
||||||
SpinLockInit(&graph->lock);
|
SpinLockInit(&graph->lock);
|
||||||
LWLockInitialize(&graph->entryLock, hnsw_entry_lock_tranche_id);
|
LWLockInitialize(&graph->entryLock, hnsw_lock_tranche_id);
|
||||||
LWLockInitialize(&graph->allocatorLock, hnsw_allocator_lock_tranche_id);
|
LWLockInitialize(&graph->allocatorLock, hnsw_lock_tranche_id);
|
||||||
LWLockInitialize(&graph->flushLock, hnsw_flush_lock_tranche_id);
|
LWLockInitialize(&graph->flushLock, hnsw_lock_tranche_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user