From 2b129bb6dadf74bb7edb4497da6e0cca983531ad Mon Sep 17 00:00:00 2001 From: Yao Feng Date: Tue, 29 Sep 2026 09:09:20 +0000 Subject: [PATCH 2/2] Add specialized in-page search support for int8 (bigint) opclasses Extend specialized in-page binary search and interpolation support to single-column int8 (bigint) B-tree indexes. This allows 64-bit integer index searches to bypass fmgr calling overhead and leverage range interpolation, while demonstrating the modularity and datatype-extensibility of the refactored specialized search framework. --- src/backend/access/nbtree/nbtcompare.c | 69 ++++++++++++++++++++++++++ src/include/catalog/pg_amproc.dat | 3 ++ src/include/catalog/pg_proc.dat | 3 ++ 3 files changed, 75 insertions(+) diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c index 9685ecad9e3..0cc22f43dde 100644 --- a/src/backend/access/nbtree/nbtcompare.c +++ b/src/backend/access/nbtree/nbtcompare.c @@ -362,6 +362,75 @@ btint8sortsupport(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +static inline bool +btint8tuplevalue(IndexTuple itup, int64 *value) +{ + if (!bt_tuple_value_check(itup)) + return false; + + /* int8 is the first and only key, so its offset is fixed. */ + memcpy(value, (char *) itup + sizeof(IndexTupleData), sizeof(*value)); + return true; +} + +static bool +btint8pagecmp(BTScanInsert key, IndexTuple itup, int32 *result) +{ + ScanKey skey = key->scankeys; + int64 search = DatumGetInt64(skey->sk_argument); + int64 value; + + if (likely(btint8tuplevalue(itup, &value))) + { + if (skey->sk_flags & SK_BT_DESC) + *result = pg_cmp_s64(value, search); + else + *result = pg_cmp_s64(search, value); + return true; + } + + return false; +} + +/* + * Interpolation support for int8 single-column page search. + */ +static bool +btint8interpolate(IndexTuple itup_low, IndexTuple itup_high, + Datum target, bool desc, int nslots, int *offset) +{ + int64 lowval; + int64 highval; + int64 search; + double span; + double delta; + + if (!btint8tuplevalue(itup_low, &lowval) || + !btint8tuplevalue(itup_high, &highval) || + lowval == highval) + return false; + + search = DatumGetInt64(target); + span = desc ? (double) lowval - (double) highval : (double) highval - (double) lowval; + delta = desc ? (double) lowval - (double) search : (double) search - (double) lowval; + + if (span <= 0.0 || delta < 0.0 || delta > span) + return false; + + *offset = (int) ((delta * (double) nslots) / span); + return true; +} + +Datum +btint8binsearchsupport(PG_FUNCTION_ARGS) +{ + BTBinSearchSupportData *support = + (BTBinSearchSupportData *) PG_GETARG_POINTER(0); + + support->compare_tuple = btint8pagecmp; + support->interpolate = btint8interpolate; + PG_RETURN_VOID(); +} static Datum int8_decrement(Relation rel, Datum existing, bool *underflow) diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat index b2a413e9263..33ddfec4f3b 100644 --- a/src/include/catalog/pg_amproc.dat +++ b/src/include/catalog/pg_amproc.dat @@ -181,6 +181,9 @@ amprocrighttype => 'int8', amprocnum => '4', amproc => 'btequalimage' }, { amprocfamily => 'btree/integer_ops', amproclefttype => 'int8', amprocrighttype => 'int8', amprocnum => '6', amproc => 'btint8skipsupport' }, +{ amprocfamily => 'btree/integer_ops', amproclefttype => 'int8', + amprocrighttype => 'int8', amprocnum => '7', + amproc => 'btint8binsearchsupport' }, { amprocfamily => 'btree/integer_ops', amproclefttype => 'int8', amprocrighttype => 'int4', amprocnum => '1', amproc => 'btint84cmp' }, { amprocfamily => 'btree/integer_ops', amproclefttype => 'int8', diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 12c39a57a51..372627e15ce 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1028,6 +1028,9 @@ { oid => '6404', descr => 'skip support', proname => 'btint8skipsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btint8skipsupport' }, +{ oid => '8001', descr => 'binary search support', + proname => 'btint8binsearchsupport', prorettype => 'void', + proargtypes => 'internal', prosrc => 'btint8binsearchsupport' }, { oid => '354', descr => 'less-equal-greater', proname => 'btfloat4cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'float4 float4', prosrc => 'btfloat4cmp' }, -- 2.53.0