mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-15 09:06:56 +08:00
Revert "Added IndexTuple to HNSW elements (first step to support multiple attributes)"
This reverts commit 53a8734bac.
This commit is contained in:
@@ -133,7 +133,6 @@ HnswPtrDeclare(HnswElementData, HnswElementRelptr, HnswElementPtr);
|
|||||||
HnswPtrDeclare(HnswNeighborArray, HnswNeighborArrayRelptr, HnswNeighborArrayPtr);
|
HnswPtrDeclare(HnswNeighborArray, HnswNeighborArrayRelptr, HnswNeighborArrayPtr);
|
||||||
HnswPtrDeclare(HnswNeighborArrayPtr, HnswNeighborsRelptr, HnswNeighborsPtr);
|
HnswPtrDeclare(HnswNeighborArrayPtr, HnswNeighborsRelptr, HnswNeighborsPtr);
|
||||||
HnswPtrDeclare(char, DatumRelptr, DatumPtr);
|
HnswPtrDeclare(char, DatumRelptr, DatumPtr);
|
||||||
HnswPtrDeclare(IndexTupleData, IndexTupleRelptr, IndexTuplePtr);
|
|
||||||
|
|
||||||
struct HnswElementData
|
struct HnswElementData
|
||||||
{
|
{
|
||||||
@@ -150,7 +149,6 @@ struct HnswElementData
|
|||||||
OffsetNumber neighborOffno;
|
OffsetNumber neighborOffno;
|
||||||
BlockNumber neighborPage;
|
BlockNumber neighborPage;
|
||||||
DatumPtr value;
|
DatumPtr value;
|
||||||
IndexTuplePtr itup;
|
|
||||||
LWLock lock;
|
LWLock lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -290,7 +288,6 @@ typedef struct HnswBuildState
|
|||||||
HnswGraph *graph;
|
HnswGraph *graph;
|
||||||
double ml;
|
double ml;
|
||||||
int maxLevel;
|
int maxLevel;
|
||||||
TupleDesc tupdesc;
|
|
||||||
|
|
||||||
/* Memory */
|
/* Memory */
|
||||||
MemoryContext graphCtx;
|
MemoryContext graphCtx;
|
||||||
@@ -431,12 +428,11 @@ void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, in
|
|||||||
void HnswAddHeapTid(HnswElement element, ItemPointer heaptid);
|
void HnswAddHeapTid(HnswElement element, ItemPointer heaptid);
|
||||||
HnswNeighborArray *HnswInitNeighborArray(int lm, HnswAllocator * allocator);
|
HnswNeighborArray *HnswInitNeighborArray(int lm, HnswAllocator * allocator);
|
||||||
void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * alloc);
|
void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * alloc);
|
||||||
bool HnswInsertTupleOnDisk(Relation index, HnswSupport * support, TupleDesc tupdesc, IndexTuple itup, ItemPointer heaptid, bool building);
|
bool HnswInsertTupleOnDisk(Relation index, HnswSupport * support, Datum value, ItemPointer heaptid, bool building);
|
||||||
void HnswUpdateNeighborsOnDisk(Relation index, HnswSupport * support, HnswElement e, int m, bool checkExisting, bool building);
|
void HnswUpdateNeighborsOnDisk(Relation index, HnswSupport * support, HnswElement e, int m, bool checkExisting, bool building);
|
||||||
void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec);
|
void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec);
|
||||||
void HnswLoadElement(HnswElement element, double *distance, HnswQuery * q, Relation index, HnswSupport * support, bool loadVec, double *maxDistance);
|
void HnswLoadElement(HnswElement element, double *distance, HnswQuery * q, Relation index, HnswSupport * support, bool loadVec, double *maxDistance);
|
||||||
TupleDesc HnswTupleDesc(Relation index);
|
bool HnswFormIndexValue(Datum *out, Datum *values, bool *isnull, const HnswTypeInfo * typeInfo, HnswSupport * support);
|
||||||
bool HnswFormIndexTuple(IndexTuple *out, Datum *values, bool *isnull, const HnswTypeInfo * typeInfo, HnswSupport * support, TupleDesc tupdesc);
|
|
||||||
void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element);
|
void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element);
|
||||||
void HnswUpdateConnection(char *base, HnswNeighborArray * neighbors, HnswElement newElement, float distance, int lm, int *updateIdx, Relation index, HnswSupport * support);
|
void HnswUpdateConnection(char *base, HnswNeighborArray * neighbors, HnswElement newElement, float distance, int lm, int *updateIdx, Relation index, HnswSupport * support);
|
||||||
bool HnswLoadNeighborTids(HnswElement element, ItemPointerData *indextids, Relation index, int m, int lm, int lc);
|
bool HnswLoadNeighborTids(HnswElement element, ItemPointerData *indextids, Relation index, int m, int lm, int lc);
|
||||||
|
|||||||
@@ -476,20 +476,18 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
HnswElement element;
|
HnswElement element;
|
||||||
HnswAllocator *allocator = &buildstate->allocator;
|
HnswAllocator *allocator = &buildstate->allocator;
|
||||||
HnswSupport *support = &buildstate->support;
|
HnswSupport *support = &buildstate->support;
|
||||||
|
Size valueSize;
|
||||||
|
Pointer valuePtr;
|
||||||
LWLock *flushLock = &graph->flushLock;
|
LWLock *flushLock = &graph->flushLock;
|
||||||
char *base = buildstate->hnswarea;
|
char *base = buildstate->hnswarea;
|
||||||
TupleDesc tupdesc = buildstate->tupdesc;
|
Datum value;
|
||||||
IndexTuple itup;
|
|
||||||
Size itupSize;
|
|
||||||
IndexTuple itupShared;
|
|
||||||
bool unused;
|
|
||||||
|
|
||||||
/* Form index value */
|
/* Form index value */
|
||||||
if (!HnswFormIndexTuple(&itup, values, isnull, buildstate->typeInfo, support, tupdesc))
|
if (!HnswFormIndexValue(&value, values, isnull, buildstate->typeInfo, support))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Get tuple size */
|
/* Get datum size */
|
||||||
itupSize = IndexTupleSize(itup);
|
valueSize = VARSIZE_ANY(DatumGetPointer(value));
|
||||||
|
|
||||||
/* Ensure graph not flushed when inserting */
|
/* Ensure graph not flushed when inserting */
|
||||||
LWLockAcquire(flushLock, LW_SHARED);
|
LWLockAcquire(flushLock, LW_SHARED);
|
||||||
@@ -499,7 +497,7 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
{
|
{
|
||||||
LWLockRelease(flushLock);
|
LWLockRelease(flushLock);
|
||||||
|
|
||||||
return HnswInsertTupleOnDisk(index, support, tupdesc, itup, heaptid, true);
|
return HnswInsertTupleOnDisk(index, support, value, heaptid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -531,12 +529,12 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
|
|
||||||
LWLockRelease(flushLock);
|
LWLockRelease(flushLock);
|
||||||
|
|
||||||
return HnswInsertTupleOnDisk(index, support, tupdesc, itup, heaptid, true);
|
return HnswInsertTupleOnDisk(index, support, value, heaptid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ok, we can proceed to allocate the element */
|
/* Ok, we can proceed to allocate the element */
|
||||||
element = HnswInitElement(base, heaptid, buildstate->m, buildstate->ml, buildstate->maxLevel, allocator);
|
element = HnswInitElement(base, heaptid, buildstate->m, buildstate->ml, buildstate->maxLevel, allocator);
|
||||||
itupShared = HnswAlloc(allocator, itupSize);
|
valuePtr = HnswAlloc(allocator, valueSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have now allocated the space needed for the element, so we don't
|
* We have now allocated the space needed for the element, so we don't
|
||||||
@@ -545,10 +543,9 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid, Hn
|
|||||||
*/
|
*/
|
||||||
LWLockRelease(&graph->allocatorLock);
|
LWLockRelease(&graph->allocatorLock);
|
||||||
|
|
||||||
/* Copy the tuple */
|
/* Copy the datum */
|
||||||
memcpy(itupShared, itup, itupSize);
|
memcpy(valuePtr, DatumGetPointer(value), valueSize);
|
||||||
HnswPtrStore(base, element->itup, itupShared);
|
HnswPtrStore(base, element->value, valuePtr);
|
||||||
HnswPtrStore(base, element->value, DatumGetPointer(index_getattr(itupShared, 1, tupdesc, &unused)));
|
|
||||||
|
|
||||||
/* Create a lock for the element */
|
/* Create a lock for the element */
|
||||||
LWLockInitialize(&element->lock, hnsw_lock_tranche_id);
|
LWLockInitialize(&element->lock, hnsw_lock_tranche_id);
|
||||||
@@ -701,7 +698,6 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index
|
|||||||
buildstate->graph = &buildstate->graphData;
|
buildstate->graph = &buildstate->graphData;
|
||||||
buildstate->ml = HnswGetMl(buildstate->m);
|
buildstate->ml = HnswGetMl(buildstate->m);
|
||||||
buildstate->maxLevel = HnswGetMaxLevel(buildstate->m);
|
buildstate->maxLevel = HnswGetMaxLevel(buildstate->m);
|
||||||
buildstate->tupdesc = HnswTupleDesc(index);
|
|
||||||
|
|
||||||
buildstate->graphCtx = GenerationContextCreate(CurrentMemoryContext,
|
buildstate->graphCtx = GenerationContextCreate(CurrentMemoryContext,
|
||||||
"Hnsw build graph context",
|
"Hnsw build graph context",
|
||||||
@@ -726,7 +722,6 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index
|
|||||||
static void
|
static void
|
||||||
FreeBuildState(HnswBuildState * buildstate)
|
FreeBuildState(HnswBuildState * buildstate)
|
||||||
{
|
{
|
||||||
pfree(buildstate->tupdesc);
|
|
||||||
MemoryContextDelete(buildstate->graphCtx);
|
MemoryContextDelete(buildstate->graphCtx);
|
||||||
MemoryContextDelete(buildstate->tmpCtx);
|
MemoryContextDelete(buildstate->tmpCtx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -687,7 +687,7 @@ UpdateGraphOnDisk(Relation index, HnswSupport * support, HnswElement element, in
|
|||||||
* Insert a tuple into the index
|
* Insert a tuple into the index
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
HnswInsertTupleOnDisk(Relation index, HnswSupport * support, TupleDesc tupdesc, IndexTuple itup, ItemPointer heaptid, bool building)
|
HnswInsertTupleOnDisk(Relation index, HnswSupport * support, Datum value, ItemPointer heaptid, bool building)
|
||||||
{
|
{
|
||||||
HnswElement entryPoint;
|
HnswElement entryPoint;
|
||||||
HnswElement element;
|
HnswElement element;
|
||||||
@@ -695,7 +695,6 @@ HnswInsertTupleOnDisk(Relation index, HnswSupport * support, TupleDesc tupdesc,
|
|||||||
int efConstruction = HnswGetEfConstruction(index);
|
int efConstruction = HnswGetEfConstruction(index);
|
||||||
LOCKMODE lockmode = ShareLock;
|
LOCKMODE lockmode = ShareLock;
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
bool unused;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a shared lock. This allows vacuum to ensure no in-flight inserts
|
* Get a shared lock. This allows vacuum to ensure no in-flight inserts
|
||||||
@@ -709,8 +708,7 @@ HnswInsertTupleOnDisk(Relation index, HnswSupport * support, TupleDesc tupdesc,
|
|||||||
|
|
||||||
/* Create an element */
|
/* Create an element */
|
||||||
element = HnswInitElement(base, heaptid, m, HnswGetMl(m), HnswGetMaxLevel(m), NULL);
|
element = HnswInitElement(base, heaptid, m, HnswGetMl(m), HnswGetMaxLevel(m), NULL);
|
||||||
HnswPtrStore(base, element->itup, itup);
|
HnswPtrStore(base, element->value, DatumGetPointer(value));
|
||||||
HnswPtrStore(base, element->value, DatumGetPointer(index_getattr(itup, 1, tupdesc, &unused)));
|
|
||||||
|
|
||||||
/* Prevent concurrent inserts when likely updating entry point */
|
/* Prevent concurrent inserts when likely updating entry point */
|
||||||
if (entryPoint == NULL || element->level > entryPoint->level)
|
if (entryPoint == NULL || element->level > entryPoint->level)
|
||||||
@@ -744,18 +742,17 @@ HnswInsertTupleOnDisk(Relation index, HnswSupport * support, TupleDesc tupdesc,
|
|||||||
static void
|
static void
|
||||||
HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid)
|
HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heaptid)
|
||||||
{
|
{
|
||||||
IndexTuple itup;
|
Datum value;
|
||||||
const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index);
|
const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index);
|
||||||
HnswSupport support;
|
HnswSupport support;
|
||||||
TupleDesc tupdesc = HnswTupleDesc(index);
|
|
||||||
|
|
||||||
HnswInitSupport(&support, index);
|
HnswInitSupport(&support, index);
|
||||||
|
|
||||||
/* Form index tuple */
|
/* Form index value */
|
||||||
if (!HnswFormIndexTuple(&itup, values, isnull, typeInfo, &support, tupdesc))
|
if (!HnswFormIndexValue(&value, values, isnull, typeInfo, &support))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
HnswInsertTupleOnDisk(index, &support, tupdesc, itup, heaptid, false);
|
HnswInsertTupleOnDisk(index, &support, value, heaptid, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -395,24 +395,10 @@ HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, Bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the tuple descriptor
|
* Form index value
|
||||||
*/
|
|
||||||
TupleDesc
|
|
||||||
HnswTupleDesc(Relation index)
|
|
||||||
{
|
|
||||||
TupleDesc tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(index));
|
|
||||||
|
|
||||||
/* Prevent compression */
|
|
||||||
TupleDescAttr(tupdesc, 0)->attstorage = TYPSTORAGE_PLAIN;
|
|
||||||
|
|
||||||
return tupdesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Form index tuple
|
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
HnswFormIndexTuple(IndexTuple *out, Datum *values, bool *isnull, const HnswTypeInfo * typeInfo, HnswSupport * support, TupleDesc tupdesc)
|
HnswFormIndexValue(Datum *out, Datum *values, bool *isnull, const HnswTypeInfo * typeInfo, HnswSupport * support)
|
||||||
{
|
{
|
||||||
/* Detoast once for all calls */
|
/* Detoast once for all calls */
|
||||||
Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0]));
|
Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0]));
|
||||||
@@ -430,9 +416,7 @@ HnswFormIndexTuple(IndexTuple *out, Datum *values, bool *isnull, const HnswTypeI
|
|||||||
value = HnswNormValue(typeInfo, support->collation, value);
|
value = HnswNormValue(typeInfo, support->collation, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO Combine value with values to support multiple attributes */
|
*out = value;
|
||||||
Assert(tupdesc->natts == 1);
|
|
||||||
*out = index_form_tuple(tupdesc, &value, isnull);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user