From b6e6b651af17cbf36192ab1f3f658968e94e172c Mon Sep 17 00:00:00 2001 From: Matthias van de Meent Date: Fri, 8 Apr 2022 14:54:52 +0200 Subject: [PATCH v1 6/6] Specialize the nbtree rd_indam entry. Because each rd_indam struct is seperately allocated for each index, we can freely modify it at runtime without impacting other indexes of the same access method. For btinsert (which effectively only calls _bt_insert) it is useful to specialize that function, which also makes rd_indam->aminsert a good signal whether or not the indexRelation has been fully optimized yet. --- src/backend/access/nbtree/nbtree.c | 7 +++++++ src/backend/access/nbtree/nbtree_spec.h | 20 +++++++++++++++----- src/backend/access/nbtree/nbtsearch.c | 2 ++ src/backend/access/nbtree/nbtsort.c | 2 ++ src/include/access/nbtree.h | 7 +++++++ 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 09c43eb226..95da2c46bf 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -161,6 +161,8 @@ btbuildempty(Relation index) metapage = (Page) palloc(BLCKSZ); _bt_initmetapage(metapage, P_NONE, 0, _bt_allequalimage(index, false)); + nbt_opt_specialize(index); + /* * Write the page and log it. It might seem that an immediate sync would * be sufficient to guarantee that the file exists on disk, but recovery @@ -323,6 +325,8 @@ btbeginscan(Relation rel, int nkeys, int norderbys) IndexScanDesc scan; BTScanOpaque so; + nbt_opt_specialize(rel); + /* no order by operators allowed */ Assert(norderbys == 0); @@ -765,6 +769,7 @@ btbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, { Relation rel = info->index; BTCycleId cycleid; + nbt_opt_specialize(info->index); /* allocate stats if first time through, else re-use existing struct */ if (stats == NULL) @@ -798,6 +803,8 @@ btvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) if (info->analyze_only) return stats; + nbt_opt_specialize(info->index); + /* * If btbulkdelete was called, we need not do anything (we just maintain * the information used within _bt_vacuum_needs_cleanup() by calling diff --git a/src/backend/access/nbtree/nbtree_spec.h b/src/backend/access/nbtree/nbtree_spec.h index 2e9190f267..001e56bfb8 100644 --- a/src/backend/access/nbtree/nbtree_spec.h +++ b/src/backend/access/nbtree/nbtree_spec.h @@ -2,9 +2,18 @@ * Specialized functions for nbtree.c */ +/* + * _bt_specialize() -- Specialize this index relation for its index key. + */ void -NBTS_FUNCTION(_bt_specialize)(Relation rel) { +NBTS_FUNCTION(_bt_specialize)(Relation rel) +{ + PopulateTupleDescCacheOffsets(rel->rd_att); +#ifdef NBTS_SPECIALIZING_DEFAULT + nbts_call_norel(_bt_specialize, rel, rel); +#else rel->rd_indam->aminsert = NBTS_FUNCTION(btinsert); +#endif } /* @@ -23,10 +32,11 @@ NBTS_FUNCTION(btinsert)(Relation rel, Datum *values, bool *isnull, bool result; IndexTuple itup; -#ifdef NBT_SPEC_DEFAULT - nbts_call(_bt_specialize, rel); - nbts_call(_bt_insert, rel, values, isnull, ht_ctid, heapRel, checkUnique, - indexUnchanged, indexInfo); +#ifdef NBTS_SPECIALIZING_DEFAULT + nbt_opt_specialize(rel); + + return nbts_call(btinsert, rel, values, isnull, ht_ctid, heapRel, + checkUnique, indexUnchanged, indexInfo); #else /* generate an index tuple */ diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index e81eee9c35..d5152bfcb7 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -181,6 +181,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) Assert(!BTScanPosIsValid(so->currPos)); + nbt_opt_specialize(scan->indexRelation); + pgstat_count_index_scan(rel); /* diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 762921e66a..f2311caf16 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -305,6 +305,8 @@ btbuild(Relation heap, Relation index, IndexInfo *indexInfo) BTBuildState buildstate; double reltuples; + nbt_opt_specialize(index); + #ifdef BTREE_BUILD_STATS if (log_btree_build_stats) ResetUsage(); diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index d59531f3b3..e101797419 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1134,6 +1134,12 @@ typedef struct BTOptions #ifdef NBTS_ENABLED +#define nbt_opt_specialize(rel) \ +do { \ + if (unlikely((rel)->rd_indam->aminsert == btinsert)) \ + _bt_specialize(rel); \ +} while (false) + #define NBT_SPECIALIZE_CALL(function, rel, ...) \ ( \ IndexRelationGetNumberOfKeyAttributes(rel) == 1 ? ( \ @@ -1154,6 +1160,7 @@ typedef struct BTOptions #else /* not defined NBTS_ENABLED */ +#define nbt_opt_specialize(rel) #define NBT_SPECIALIZE_CALL(function, rel, ...) function(__VA_ARGS__) #endif /* NBTS_ENABLED */ -- 2.30.2