mirror of
https://github.com/pgvector/pgvector.git
synced 2026-06-06 05:51:21 +08:00
194 lines
5.4 KiB
C
194 lines
5.4 KiB
C
#ifndef IVFFLAT_H
|
|
#define IVFFLAT_H
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "access/generic_xlog.h"
|
|
#include "access/reloptions.h"
|
|
#include "nodes/execnodes.h"
|
|
#include "utils/sampling.h"
|
|
#include "utils/tuplesort.h"
|
|
#include "vector.h"
|
|
|
|
/* Support functions */
|
|
#define IVFFLAT_DISTANCE_PROC 1
|
|
#define IVFFLAT_NORM_PROC 2
|
|
#define IVFFLAT_KMEANS_DISTANCE_PROC 3
|
|
#define IVFFLAT_KMEANS_NORM_PROC 4
|
|
|
|
#define IVFFLAT_VERSION 1
|
|
#define IVFFLAT_MAGIC_NUMBER 0x14FF1A7
|
|
#define IVFFLAT_PAGE_ID 0xFF84
|
|
|
|
/* Preserved page numbers */
|
|
#define IVFFLAT_METAPAGE_BLKNO 0
|
|
#define IVFFLAT_HEAD_BLKNO 1 /* first list page */
|
|
|
|
#define IVFFLAT_DEFAULT_LISTS 100
|
|
#define IVFFLAT_MAX_LISTS 32768
|
|
|
|
#define IVFFLAT_LIST_SIZE(_dim) (offsetof(IvfflatListData, center) + VECTOR_SIZE(_dim))
|
|
|
|
#define IvfflatPageGetOpaque(page) ((IvfflatPageOpaque) PageGetSpecialPointer(page))
|
|
#define IvfflatPageGetMeta(page) ((IvfflatMetaPageData *) PageGetContents(page))
|
|
|
|
#if PG_VERSION_NUM < 100000
|
|
#define ItemPointerGetBlockNumberNoCheck ItemPointerGetBlockNumber
|
|
#define ItemPointerGetOffsetNumberNoCheck ItemPointerGetOffsetNumber
|
|
#endif
|
|
|
|
/* Variables */
|
|
int ivfflat_probes;
|
|
|
|
typedef struct VectorArrayData
|
|
{
|
|
int length;
|
|
int maxlen;
|
|
int dim;
|
|
Vector items[FLEXIBLE_ARRAY_MEMBER];
|
|
} VectorArrayData;
|
|
|
|
typedef VectorArrayData * VectorArray;
|
|
|
|
typedef struct ListInfo
|
|
{
|
|
BlockNumber blkno;
|
|
OffsetNumber offno;
|
|
} ListInfo;
|
|
|
|
/* IVFFlat index options */
|
|
typedef struct IvfflatOptions
|
|
{
|
|
int32 vl_len_; /* varlena header (do not touch directly!) */
|
|
int lists; /* number of lists */
|
|
} IvfflatOptions;
|
|
|
|
typedef struct IvfflatBuildState
|
|
{
|
|
/* Info */
|
|
Relation heap;
|
|
Relation index;
|
|
IndexInfo *indexInfo;
|
|
|
|
/* Settings */
|
|
int dimensions;
|
|
int lists;
|
|
|
|
/* Statistics */
|
|
double indtuples;
|
|
double reltuples;
|
|
|
|
/* Support functions */
|
|
FmgrInfo *procinfo;
|
|
FmgrInfo *normprocinfo;
|
|
Oid collation;
|
|
|
|
/* Variables */
|
|
VectorArray samples;
|
|
VectorArray centers;
|
|
ListInfo *listInfo;
|
|
Vector *normvec;
|
|
|
|
/* Sampling */
|
|
BlockSamplerData bs;
|
|
ReservoirStateData rstate;
|
|
int rowstoskip;
|
|
|
|
/* Sorting */
|
|
Tuplesortstate *sortstate;
|
|
TupleDesc tupdesc;
|
|
TupleTableSlot *slot;
|
|
} IvfflatBuildState;
|
|
|
|
typedef struct IvfflatMetaPageData
|
|
{
|
|
uint32 magicNumber;
|
|
uint32 version;
|
|
uint16 dimensions;
|
|
uint16 lists;
|
|
} IvfflatMetaPageData;
|
|
|
|
typedef IvfflatMetaPageData * IvfflatMetaPage;
|
|
|
|
typedef struct IvfflatPageOpaqueData
|
|
{
|
|
BlockNumber nextblkno;
|
|
uint16 unused;
|
|
uint16 page_id; /* for identification of IVFFlat indexes */
|
|
} IvfflatPageOpaqueData;
|
|
|
|
typedef IvfflatPageOpaqueData * IvfflatPageOpaque;
|
|
|
|
typedef struct IvfflatListData
|
|
{
|
|
BlockNumber startPage;
|
|
BlockNumber insertPage;
|
|
Vector center;
|
|
} IvfflatListData;
|
|
|
|
typedef IvfflatListData * IvfflatList;
|
|
|
|
typedef struct IvfflatScanList
|
|
{
|
|
BlockNumber startPage;
|
|
double distance;
|
|
} IvfflatScanList;
|
|
|
|
typedef struct IvfflatScanOpaqueData
|
|
{
|
|
int probes;
|
|
bool first;
|
|
Buffer buf;
|
|
|
|
/* Sorting */
|
|
Tuplesortstate *sortstate;
|
|
TupleDesc tupdesc;
|
|
TupleTableSlot *slot;
|
|
bool isnull;
|
|
|
|
/* Support functions */
|
|
FmgrInfo *procinfo;
|
|
FmgrInfo *normprocinfo;
|
|
Oid collation;
|
|
|
|
IvfflatScanList lists[FLEXIBLE_ARRAY_MEMBER]; /* must come last */
|
|
} IvfflatScanOpaqueData;
|
|
|
|
typedef IvfflatScanOpaqueData * IvfflatScanOpaque;
|
|
|
|
#define VECTOR_ARRAY_SIZE(_length, _dim) (offsetof(VectorArrayData, items) + _length * VECTOR_SIZE(_dim))
|
|
#define VECTOR_ARRAY_OFFSET(_arr, _offset) ((char*) _arr + offsetof(VectorArrayData, items) + (_offset) * VECTOR_SIZE(_arr->dim))
|
|
#define VectorArrayGet(_arr, _offset) ((Vector *) VECTOR_ARRAY_OFFSET(_arr, _offset))
|
|
#define VectorArraySet(_arr, _offset, _val) (memcpy(VECTOR_ARRAY_OFFSET(_arr, _offset), _val, VECTOR_SIZE(_arr->dim)))
|
|
|
|
/* Methods */
|
|
void _PG_init(void);
|
|
VectorArray VectorArrayInit(int maxlen, int dimensions);
|
|
void PrintVectorArray(char *msg, VectorArray arr);
|
|
void IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers);
|
|
FmgrInfo *IvfflatOptionalProcInfo(Relation rel, uint16 procnum);
|
|
bool IvfflatNormValue(FmgrInfo *procinfo, Oid collation, Datum *value, Vector * result);
|
|
int IvfflatGetLists(Relation index);
|
|
void IvfflatUpdateList(Relation index, GenericXLogState *state, ListInfo listInfo, BlockNumber insertPage, BlockNumber startPage, ForkNumber forkNum);
|
|
void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state);
|
|
void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum);
|
|
Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum);
|
|
void IvfflatInitPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state);
|
|
|
|
/* Index access methods */
|
|
IndexBuildResult *ivfflatbuild(Relation heap, Relation index, IndexInfo *indexInfo);
|
|
void ivfflatbuildempty(Relation index);
|
|
bool ivfflatinsert(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique
|
|
#if PG_VERSION_NUM >= 100000
|
|
,IndexInfo *indexInfo
|
|
#endif
|
|
);
|
|
IndexBulkDeleteResult *ivfflatbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state);
|
|
IndexBulkDeleteResult *ivfflatvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats);
|
|
IndexScanDesc ivfflatbeginscan(Relation index, int nkeys, int norderbys);
|
|
void ivfflatrescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys);
|
|
bool ivfflatgettuple(IndexScanDesc scan, ScanDirection dir);
|
|
void ivfflatendscan(IndexScanDesc scan);
|
|
|
|
#endif
|