diff --git a/CHANGELOG.md b/CHANGELOG.md index b7d07b8..1a38cb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.3 (unreleased) + +- Added build phase progress for Postgres 12+ + ## 0.2.2 (2022-01-15) - Fixed compilation error on Mac ARM diff --git a/src/ivfbuild.c b/src/ivfbuild.c index ce585af..2669ddd 100644 --- a/src/ivfbuild.c +++ b/src/ivfbuild.c @@ -82,6 +82,8 @@ SampleRows(IvfflatBuildState * buildstate) int targsamples = buildstate->samples->maxlen; BlockNumber totalblocks = RelationGetNumberOfBlocks(buildstate->heap); + IvfflatUpdateProgress(PROGRESS_IVFFLAT_PHASE_SAMPLE); + buildstate->rowstoskip = -1; BlockSampler_Init(&buildstate->bs, totalblocks, targsamples, random()); @@ -220,6 +222,8 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) #endif TupleDesc tupdesc = RelationGetDescr(index); + IvfflatUpdateProgress(PROGRESS_IVFFLAT_PHASE_LOAD); + GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); for (i = 0; i < buildstate->centers->length; i++) @@ -342,6 +346,7 @@ ComputeCenters(IvfflatBuildState * buildstate) SampleRows(buildstate); /* Calculate centers */ + IvfflatUpdateProgress(PROGRESS_IVFFLAT_PHASE_KMEANS); IvfflatKmeans(buildstate->index, buildstate->samples, buildstate->centers); /* Free samples before we allocate more memory */ @@ -432,6 +437,8 @@ CreateEntryPages(IvfflatBuildState * buildstate, ForkNumber forkNum) Oid sortCollations[] = {InvalidOid}; bool nullsFirstFlags[] = {false}; + IvfflatUpdateProgress(PROGRESS_IVFFLAT_PHASE_SORT); + #if PG_VERSION_NUM >= 110000 buildstate->sortstate = tuplesort_begin_heap(buildstate->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, maintenance_work_mem, NULL, false); #else diff --git a/src/ivfflat.c b/src/ivfflat.c index 38a3bed..d0c94ac 100644 --- a/src/ivfflat.c +++ b/src/ivfflat.c @@ -8,6 +8,10 @@ #include "utils/guc.h" #include "utils/selfuncs.h" +#if PG_VERSION_NUM >= 120000 +#include "commands/progress.h" +#endif + int ivfflat_probes; static relopt_kind ivfflat_relopt_kind; @@ -30,6 +34,31 @@ _PG_init(void) 1, 1, IVFFLAT_MAX_LISTS, PGC_USERSET, 0, NULL, NULL, NULL); } +/* + * Get the name of index build phase + */ +#if PG_VERSION_NUM >= 120000 +static char * +ivfflatbuildphasename(int64 phasenum) +{ + switch (phasenum) + { + case PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE: + return "initializing"; + case PROGRESS_IVFFLAT_PHASE_SAMPLE: + return "sampling table"; + case PROGRESS_IVFFLAT_PHASE_KMEANS: + return "performing k-means"; + case PROGRESS_IVFFLAT_PHASE_SORT: + return "sorting tuples"; + case PROGRESS_IVFFLAT_PHASE_LOAD: + return "loading tuples"; + default: + return NULL; + } +} +#endif + /* * Estimate the cost of an index scan */ @@ -174,7 +203,7 @@ ivfflathandler(PG_FUNCTION_ARGS) amroutine->amoptions = ivfflatoptions; amroutine->amproperty = NULL; /* TODO AMPROP_DISTANCE_ORDERABLE */ #if PG_VERSION_NUM >= 120000 - amroutine->ambuildphasename = NULL; + amroutine->ambuildphasename = ivfflatbuildphasename; #endif amroutine->amvalidate = ivfflatvalidate; amroutine->ambeginscan = ivfflatbeginscan; diff --git a/src/ivfflat.h b/src/ivfflat.h index c7576d4..7d39c84 100644 --- a/src/ivfflat.h +++ b/src/ivfflat.h @@ -27,6 +27,13 @@ #define IVFFLAT_DEFAULT_LISTS 100 #define IVFFLAT_MAX_LISTS 32768 +/* Build phases */ +/* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 */ +#define PROGRESS_IVFFLAT_PHASE_SAMPLE 2 +#define PROGRESS_IVFFLAT_PHASE_KMEANS 3 +#define PROGRESS_IVFFLAT_PHASE_SORT 4 +#define PROGRESS_IVFFLAT_PHASE_LOAD 5 + #define IVFFLAT_LIST_SIZE(_dim) (offsetof(IvfflatListData, center) + VECTOR_SIZE(_dim)) #define IvfflatPageGetOpaque(page) ((IvfflatPageOpaque) PageGetSpecialPointer(page)) @@ -175,6 +182,7 @@ 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); +void IvfflatUpdateProgress(int64 val); /* Index access methods */ IndexBuildResult *ivfflatbuild(Relation heap, Relation index, IndexInfo *indexInfo); diff --git a/src/ivfutils.c b/src/ivfutils.c index f3a2cf9..1cb5b1e 100644 --- a/src/ivfutils.c +++ b/src/ivfutils.c @@ -4,6 +4,16 @@ #include "storage/bufmgr.h" #include "vector.h" +#if PG_VERSION_NUM >= 120000 +#include "commands/progress.h" +#endif + +#if PG_VERSION_NUM >= 140000 +#include "utils/backend_progress.h" +#elif PG_VERSION_NUM >= 120000 +#include "pgstat.h" +#endif + /* * Allocate a vector array */ @@ -174,3 +184,14 @@ IvfflatUpdateList(Relation index, GenericXLogState *state, ListInfo listInfo, /* Could only commit if changed, but extra complexity isn't needed */ IvfflatCommitBuffer(buf, state); } + +/* + * Update build phase progress + */ +void +IvfflatUpdateProgress(int64 val) +{ +#if PG_VERSION_NUM >= 120000 + pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, val); +#endif +}