Compare commits

..

1 Commits

Author SHA1 Message Date
Andrew Kane
f858705293 No dimensions 2023-10-16 16:20:10 -07:00
5 changed files with 9 additions and 41 deletions

View File

@@ -33,12 +33,6 @@ HnswInit(void)
HNSW_DEFAULT_EF_CONSTRUCTION, HNSW_MIN_EF_CONSTRUCTION, HNSW_MAX_EF_CONSTRUCTION HNSW_DEFAULT_EF_CONSTRUCTION, HNSW_MIN_EF_CONSTRUCTION, HNSW_MAX_EF_CONSTRUCTION
#if PG_VERSION_NUM >= 130000 #if PG_VERSION_NUM >= 130000
,AccessExclusiveLock ,AccessExclusiveLock
#endif
);
add_int_reloption(hnsw_relopt_kind, "dimensions", "Number of dimensions",
HNSW_DEFAULT_DIMENSIONS, HNSW_MIN_DIMENSIONS, HNSW_MAX_DIMENSIONS
#if PG_VERSION_NUM >= 130000
,AccessExclusiveLock
#endif #endif
); );
@@ -131,7 +125,6 @@ hnswoptions(Datum reloptions, bool validate)
static const relopt_parse_elt tab[] = { static const relopt_parse_elt tab[] = {
{"m", RELOPT_TYPE_INT, offsetof(HnswOptions, m)}, {"m", RELOPT_TYPE_INT, offsetof(HnswOptions, m)},
{"ef_construction", RELOPT_TYPE_INT, offsetof(HnswOptions, efConstruction)}, {"ef_construction", RELOPT_TYPE_INT, offsetof(HnswOptions, efConstruction)},
{"dimensions", RELOPT_TYPE_INT, offsetof(HnswOptions, dimensions)},
}; };
#if PG_VERSION_NUM >= 130000 #if PG_VERSION_NUM >= 130000

View File

@@ -42,9 +42,6 @@
#define HNSW_DEFAULT_EF_SEARCH 40 #define HNSW_DEFAULT_EF_SEARCH 40
#define HNSW_MIN_EF_SEARCH 1 #define HNSW_MIN_EF_SEARCH 1
#define HNSW_MAX_EF_SEARCH 1000 #define HNSW_MAX_EF_SEARCH 1000
#define HNSW_DEFAULT_DIMENSIONS -1
#define HNSW_MIN_DIMENSIONS 1
#define HNSW_MAX_DIMENSIONS HNSW_MAX_DIM
/* Tuple types */ /* Tuple types */
#define HNSW_ELEMENT_TUPLE_TYPE 1 #define HNSW_ELEMENT_TUPLE_TYPE 1
@@ -101,6 +98,7 @@ typedef struct HnswElementData
List *heaptids; List *heaptids;
uint8 level; uint8 level;
uint8 deleted; uint8 deleted;
bool loaded;
HnswNeighborArray *neighbors; HnswNeighborArray *neighbors;
BlockNumber blkno; BlockNumber blkno;
OffsetNumber offno; OffsetNumber offno;
@@ -137,7 +135,6 @@ typedef struct HnswOptions
int32 vl_len_; /* varlena header (do not touch directly!) */ int32 vl_len_; /* varlena header (do not touch directly!) */
int m; /* number of connections */ int m; /* number of connections */
int efConstruction; /* size of dynamic candidate list */ int efConstruction; /* size of dynamic candidate list */
int dimensions;
} HnswOptions; } HnswOptions;
typedef struct HnswBuildState typedef struct HnswBuildState
@@ -266,7 +263,6 @@ typedef struct HnswVacuumState
/* Methods */ /* Methods */
int HnswGetM(Relation index); int HnswGetM(Relation index);
int HnswGetEfConstruction(Relation index); int HnswGetEfConstruction(Relation index);
int HnswGetDimensions(Relation index);
FmgrInfo *HnswOptionalProcInfo(Relation index, uint16 procnum); FmgrInfo *HnswOptionalProcInfo(Relation index, uint16 procnum);
bool HnswNormValue(FmgrInfo *procinfo, Oid collation, Datum *value, Vector * result); bool HnswNormValue(FmgrInfo *procinfo, Oid collation, Datum *value, Vector * result);
void HnswCommitBuffer(Buffer buf, GenericXLogState *state); void HnswCommitBuffer(Buffer buf, GenericXLogState *state);

View File

@@ -375,13 +375,11 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values,
if (inserted) if (inserted)
{ {
element->value = datumCopy(element->value, false, -1); element->value = datumCopy(element->value, false, -1);
element->loaded = true;
buildstate->elements = lappend(buildstate->elements, element); buildstate->elements = lappend(buildstate->elements, element);
} }
else else
{
element->value = PointerGetDatum(NULL);
HnswFreeElement(element); HnswFreeElement(element);
}
/* Reset memory context */ /* Reset memory context */
MemoryContextReset(buildstate->tmpCtx); MemoryContextReset(buildstate->tmpCtx);
@@ -417,14 +415,7 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index
buildstate->m = HnswGetM(index); buildstate->m = HnswGetM(index);
buildstate->efConstruction = HnswGetEfConstruction(index); buildstate->efConstruction = HnswGetEfConstruction(index);
buildstate->dimensions = HnswGetDimensions(index); buildstate->dimensions = TupleDescAttr(index->rd_att, 0)->atttypmod;
if (buildstate->dimensions < 0)
buildstate->dimensions = TupleDescAttr(index->rd_att, 0)->atttypmod;
/* Require column to have dimensions to be indexed */
if (buildstate->dimensions < 0)
elog(ERROR, "column does not have dimensions");
if (buildstate->dimensions > HNSW_MAX_DIM) if (buildstate->dimensions > HNSW_MAX_DIM)
elog(ERROR, "column cannot have more than %d dimensions for hnsw index", HNSW_MAX_DIM); elog(ERROR, "column cannot have more than %d dimensions for hnsw index", HNSW_MAX_DIM);
@@ -448,6 +439,7 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index
buildstate->flushed = false; buildstate->flushed = false;
/* Reuse for each tuple */ /* Reuse for each tuple */
/* TODO Fix / replace with support function */
buildstate->normvec = InitVector(buildstate->dimensions); buildstate->normvec = InitVector(buildstate->dimensions);
buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext,

View File

@@ -35,20 +35,6 @@ HnswGetEfConstruction(Relation index)
return HNSW_DEFAULT_EF_CONSTRUCTION; return HNSW_DEFAULT_EF_CONSTRUCTION;
} }
/*
* Get the number of dimensions in the index
*/
int
HnswGetDimensions(Relation index)
{
HnswOptions *opts = (HnswOptions *) index->rd_options;
if (opts)
return opts->dimensions;
return HNSW_DEFAULT_DIMENSIONS;
}
/* /*
* Get proc * Get proc
*/ */
@@ -202,7 +188,7 @@ HnswFreeElement(HnswElement element)
{ {
HnswFreeNeighbors(element); HnswFreeNeighbors(element);
list_free_deep(element->heaptids); list_free_deep(element->heaptids);
if (DatumGetPointer(element->value)) if (element->loaded)
pfree(DatumGetPointer(element->value)); pfree(DatumGetPointer(element->value));
pfree(element); pfree(element);
} }
@@ -230,7 +216,7 @@ HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno)
element->blkno = blkno; element->blkno = blkno;
element->offno = offno; element->offno = offno;
element->neighbors = NULL; element->neighbors = NULL;
element->value = PointerGetDatum(NULL); element->loaded = false;
return element; return element;
} }
@@ -466,6 +452,7 @@ HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHe
Datum value = PointerGetDatum(&etup->value); Datum value = PointerGetDatum(&etup->value);
element->value = datumCopy(value, false, -1); element->value = datumCopy(value, false, -1);
element->loaded = true;
} }
} }
@@ -953,7 +940,7 @@ HnswUpdateConnection(HnswElement element, HnswCandidate * hc, int m, int lc, int
{ {
HnswCandidate *hc3 = &currentNeighbors->items[i]; HnswCandidate *hc3 = &currentNeighbors->items[i];
if (!DatumGetPointer(hc3->element->value)) if (!hc3->element->loaded)
HnswLoadElement(hc3->element, &hc3->distance, &q, index, procinfo, collation, true); HnswLoadElement(hc3->element, &hc3->distance, &q, index, procinfo, collation, true);
else else
hc3->distance = GetCandidateDistance(hc3, q, procinfo, collation); hc3->distance = GetCandidateDistance(hc3, q, procinfo, collation);

View File

@@ -104,7 +104,7 @@ for my $i (0 .. $#operators)
} }
# Add index # Add index
$node->safe_psql("postgres", "CREATE INDEX ON tst USING hnsw (v $opclass) WITH (dimensions = 3);"); $node->safe_psql("postgres", "CREATE INDEX ON tst USING hnsw (v $opclass);");
my $min = $operator eq "<#>" ? 0.80 : 0.99; my $min = $operator eq "<#>" ? 0.80 : 0.99;
test_recall($min, $operator); test_recall($min, $operator);