($INBOX_DIR/description missing)help / color / mirror / Atom feed
[PATCH 3/6] Optimize allocations in bringetbitmap 2+ messages / 2 participants [nested] [flat]
* [PATCH 3/6] Optimize allocations in bringetbitmap @ 2021-03-02 18:57 Tomas Vondra <[email protected]> 0 siblings, 0 replies; 2+ messages in thread From: Tomas Vondra @ 2021-03-02 18:57 UTC (permalink / raw) The bringetbitmap function allocates memory for various purposes, which may be quite expensive, depending on the number of scan keys. Instead of allocating them separately, allocate one bit chunk of memory an carve it into smaller pieces as needed - all the pieces have the same lifespan, and it saves quite a bit of CPU and memory overhead. Author: Tomas Vondra <[email protected]> Discussion: https://postgr.es/m/[email protected] --- src/backend/access/brin/brin.c | 60 ++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 9f2656b8d9..1f82e965f9 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -373,6 +373,9 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) int *nkeys, *nnullkeys; int keyno; + char *ptr; + Size len; + char *tmp PG_USED_FOR_ASSERTS_ONLY; opaque = (BrinOpaque *) scan->opaque; bdesc = opaque->bo_bdesc; @@ -402,15 +405,52 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) * We keep null and regular keys separate, so that we can pass just the * regular keys to the consistent function easily. * + * To reduce the allocation overhead, we allocate one big chunk and then + * carve it into smaller arrays ourselves. All the pieces have exactly the + * same lifetime, so that's OK. + * * XXX The widest table can have ~1600 attributes, so this may allocate a * couple kilobytes of memory). We could invent a more compact approach * (with just space for used attributes) but that would make the matching * more complicated, so it may not be a win. */ - keys = palloc0(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts); - nullkeys = palloc0(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts); - nkeys = palloc0(sizeof(int) * bdesc->bd_tupdesc->natts); - nnullkeys = palloc0(sizeof(int) * bdesc->bd_tupdesc->natts); + len = + MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts) + /* regular keys */ + MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys) * bdesc->bd_tupdesc->natts + + MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts) + + MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts) + /* NULL keys */ + MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys) * bdesc->bd_tupdesc->natts + + MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts); + + ptr = palloc(len); + tmp = ptr; + + keys = (ScanKey **) ptr; + ptr += MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts); + + nullkeys = (ScanKey **) ptr; + ptr += MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts); + + nkeys = (int *) ptr; + ptr += MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts); + + nnullkeys = (int *) ptr; + ptr += MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts); + + for (int i = 0; i < bdesc->bd_tupdesc->natts; i++) + { + keys[i] = (ScanKey *) ptr; + ptr += MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys); + + nullkeys[i] = (ScanKey *) ptr; + ptr += MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys); + } + + Assert(tmp + len == ptr); + + /* zero the number of keys */ + memset(nkeys, 0, sizeof(int) * bdesc->bd_tupdesc->natts); + memset(nnullkeys, 0, sizeof(int) * bdesc->bd_tupdesc->natts); /* * Preprocess the scan keys - split them into per-attribute arrays. @@ -444,9 +484,9 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) { FmgrInfo *tmp; - /* No key/null arrays for this attribute. */ - Assert((keys[keyattno - 1] == NULL) && (nkeys[keyattno - 1] == 0)); - Assert((nullkeys[keyattno - 1] == NULL) && (nnullkeys[keyattno - 1] == 0)); + /* First time we see this attribute, so no key/null keys. */ + Assert(nkeys[keyattno - 1] == 0); + Assert(nnullkeys[keyattno - 1] == 0); tmp = index_getprocinfo(idxRel, keyattno, BRIN_PROCNUM_CONSISTENT); @@ -457,17 +497,11 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) /* Add key to the proper per-attribute array. */ if (key->sk_flags & SK_ISNULL) { - if (!nullkeys[keyattno - 1]) - nullkeys[keyattno - 1] = palloc0(sizeof(ScanKey) * scan->numberOfKeys); - nullkeys[keyattno - 1][nnullkeys[keyattno - 1]] = key; nnullkeys[keyattno - 1]++; } else { - if (!keys[keyattno - 1]) - keys[keyattno - 1] = palloc0(sizeof(ScanKey) * scan->numberOfKeys); - keys[keyattno - 1][nkeys[keyattno - 1]] = key; nkeys[keyattno - 1]++; } -- 2.26.2 --------------6A37408A2C42B5B56C3B3D49 Content-Type: text/x-patch; charset=UTF-8; name="0004-BRIN-bloom-indexes-20210303.patch" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="0004-BRIN-bloom-indexes-20210303.patch" ^ permalink raw reply [nested|flat] 2+ messages in thread
* [PATCH v3 2/7] Handle pg_get_ruledef default args in system_functions.sql @ 2025-12-08 23:41 Mark Wong <[email protected]> 0 siblings, 0 replies; 2+ messages in thread From: Mark Wong @ 2025-12-08 23:41 UTC (permalink / raw) Modernize pg_get_ruledef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 18 ------------------ src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 2 ++ 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index eb9e31ae1bf..3aad2fbf8f3 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -657,6 +657,13 @@ LANGUAGE INTERNAL STRICT VOLATILE PARALLEL UNSAFE AS 'pg_replication_origin_session_setup'; +CREATE OR REPLACE FUNCTION + pg_get_ruledef(rule oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_ruledef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 033b625f3fc..3733212fe0a 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -558,24 +558,6 @@ static void get_json_table_nested_columns(TableFunc *tf, JsonTablePlan *plan, */ Datum pg_get_ruledef(PG_FUNCTION_ARGS) -{ - Oid ruleoid = PG_GETARG_OID(0); - int prettyFlags; - char *res; - - prettyFlags = PRETTYFLAG_INDENT; - - res = pg_get_ruledef_worker(ruleoid, prettyFlags); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - - -Datum -pg_get_ruledef_ext(PG_FUNCTION_ARGS) { Oid ruleoid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 894b6a1b6d6..2a3362567a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3961,9 +3961,6 @@ proargtypes => 'oid oid', prosrc => 'oidge' }, # System-view support functions -{ oid => '1573', descr => 'source text of a rule', - proname => 'pg_get_ruledef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_ruledef' }, { oid => '1640', descr => 'select statement of a view', proname => 'pg_get_viewdef', provolatile => 's', proparallel => 'r', prorettype => 'text', proargtypes => 'text', @@ -8508,7 +8505,7 @@ # System-view support functions with pretty-print option { oid => '2504', descr => 'source text of a rule with pretty-print option', proname => 'pg_get_ruledef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_ruledef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_ruledef' }, { oid => '2505', descr => 'select statement of a view with pretty-print option', proname => 'pg_get_viewdef', provolatile => 's', proparallel => 'r', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 413b68ad1cd..a3ce10c7f62 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -17,4 +17,6 @@ # At the same time, it may be good to be reminded what procedure was associated # with it. +{ oid => '1573', proname => 'pg_get_ruledef' } + ] -- 2.43.0 --zd8Z8rlPOcTi77n/ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0003-Handle-pg_get_viewdef-default-args-in-system_func.patch" ^ permalink raw reply [nested|flat] 2+ messages in thread
end of thread, other threads:[~2025-12-08 23:41 UTC | newest] Thread overview: 2+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2021-03-02 18:57 [PATCH 3/6] Optimize allocations in bringetbitmap Tomas Vondra <[email protected]> 2025-12-08 23:41 [PATCH v3 2/7] Handle pg_get_ruledef default args in system_functions.sql Mark Wong <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox