0001-Reduce-unnecessary-list-construction-in-RelationBuil.patch
application/octet-stream
Filename: 0001-Reduce-unnecessary-list-construction-in-RelationBuil.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch 0001
Subject: Reduce unnecessary list construction in RelationBuildPartitionDesc.
| File | + | − |
|---|---|---|
| src/backend/utils/cache/partcache.c | 26 | 35 |
From 6caedf3c86deb1c5bf9b3dc2c333a2ae6b83a3fc Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Wed, 14 Nov 2018 11:11:58 -0500
Subject: [PATCH 1/2] Reduce unnecessary list construction in
RelationBuildPartitionDesc.
The 'partoids' list which was constructed by the previous version
of this code was necessarily identical to 'inhoids'. There's no
point to duplicating the list, so avoid that. Instead, construct
the array representation directly from the original 'inhoids' list.
Also, use an array rather than a list for 'boundspecs'. We know
exactly how many items we need to store, so there's really no
reason to use a list. Using an array instead reduces the number
of memory allocations we perform.
---
src/backend/utils/cache/partcache.c | 61 ++++++++++++++++---------------------
1 file changed, 26 insertions(+), 35 deletions(-)
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c
index 5757301d05..25c8b69f3f 100644
--- a/src/backend/utils/cache/partcache.c
+++ b/src/backend/utils/cache/partcache.c
@@ -260,10 +260,9 @@ RelationBuildPartitionKey(Relation relation)
void
RelationBuildPartitionDesc(Relation rel)
{
- List *inhoids,
- *partoids;
+ List *inhoids;
Oid *oids = NULL;
- List *boundspecs = NIL;
+ PartitionBoundSpec **boundspecs = NULL;
ListCell *cell;
int i,
nparts;
@@ -286,17 +285,23 @@ RelationBuildPartitionDesc(Relation rel)
/* Get partition oids from pg_inherits */
inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock);
+ nparts = list_length(inhoids);
- /* Collect bound spec nodes in a list */
+ if (nparts > 0)
+ {
+ oids = palloc(nparts * sizeof(Oid));
+ boundspecs = palloc(nparts * sizeof(PartitionBoundSpec *));
+ }
+
+ /* Collect bound spec nodes for each partition */
i = 0;
- partoids = NIL;
foreach(cell, inhoids)
{
Oid inhrelid = lfirst_oid(cell);
HeapTuple tuple;
Datum datum;
bool isnull;
- Node *boundspec;
+ PartitionBoundSpec *boundspec;
tuple = SearchSysCache1(RELOID, inhrelid);
if (!HeapTupleIsValid(tuple))
@@ -307,14 +312,16 @@ RelationBuildPartitionDesc(Relation rel)
&isnull);
if (isnull)
elog(ERROR, "null relpartbound for relation %u", inhrelid);
- boundspec = (Node *) stringToNode(TextDatumGetCString(datum));
+ boundspec = stringToNode(TextDatumGetCString(datum));
+ if (!IsA(boundspec, PartitionBoundSpec))
+ elog(ERROR, "invalid relpartbound for relation %u", inhrelid);
/*
* Sanity check: If the PartitionBoundSpec says this is the default
* partition, its OID should correspond to whatever's stored in
* pg_partitioned_table.partdefid; if not, the catalog is corrupt.
*/
- if (castNode(PartitionBoundSpec, boundspec)->is_default)
+ if (boundspec->is_default)
{
Oid partdefid;
@@ -324,20 +331,14 @@ RelationBuildPartitionDesc(Relation rel)
inhrelid, partdefid);
}
- boundspecs = lappend(boundspecs, boundspec);
- partoids = lappend_oid(partoids, inhrelid);
+ oids[i] = inhrelid;
+ boundspecs[i] = boundspec;
+ ++i;
ReleaseSysCache(tuple);
}
- nparts = list_length(partoids);
-
if (nparts > 0)
{
- oids = (Oid *) palloc(nparts * sizeof(Oid));
- i = 0;
- foreach(cell, partoids)
- oids[i++] = lfirst_oid(cell);
-
/* Convert from node to the internal representation */
if (key->strategy == PARTITION_STRATEGY_HASH)
{
@@ -345,11 +346,9 @@ RelationBuildPartitionDesc(Relation rel)
hbounds = (PartitionHashBound **)
palloc(nparts * sizeof(PartitionHashBound *));
- i = 0;
- foreach(cell, boundspecs)
+ for (i = 0; i < nparts; ++i)
{
- PartitionBoundSpec *spec = castNode(PartitionBoundSpec,
- lfirst(cell));
+ PartitionBoundSpec *spec = boundspecs[i];
if (spec->strategy != PARTITION_STRATEGY_HASH)
elog(ERROR, "invalid strategy in partition bound spec");
@@ -360,7 +359,6 @@ RelationBuildPartitionDesc(Relation rel)
hbounds[i]->modulus = spec->modulus;
hbounds[i]->remainder = spec->remainder;
hbounds[i]->index = i;
- i++;
}
/* Sort all the bounds in ascending order */
@@ -374,12 +372,10 @@ RelationBuildPartitionDesc(Relation rel)
/*
* Create a unified list of non-null values across all partitions.
*/
- i = 0;
null_index = -1;
- foreach(cell, boundspecs)
+ for (i = 0; i < nparts; ++i)
{
- PartitionBoundSpec *spec = castNode(PartitionBoundSpec,
- lfirst(cell));
+ PartitionBoundSpec *spec = boundspecs[i];
ListCell *c;
if (spec->strategy != PARTITION_STRATEGY_LIST)
@@ -393,7 +389,6 @@ RelationBuildPartitionDesc(Relation rel)
if (spec->is_default)
{
default_index = i;
- i++;
continue;
}
@@ -425,8 +420,6 @@ RelationBuildPartitionDesc(Relation rel)
non_null_values = lappend(non_null_values,
list_value);
}
-
- i++;
}
ndatums = list_length(non_null_values);
@@ -465,11 +458,10 @@ RelationBuildPartitionDesc(Relation rel)
* Create a unified list of range bounds across all the
* partitions.
*/
- i = ndatums = 0;
- foreach(cell, boundspecs)
+ ndatums = 0;
+ for (i = 0; i < nparts; ++i)
{
- PartitionBoundSpec *spec = castNode(PartitionBoundSpec,
- lfirst(cell));
+ PartitionBoundSpec *spec = boundspecs[i];
PartitionRangeBound *lower,
*upper;
@@ -483,7 +475,7 @@ RelationBuildPartitionDesc(Relation rel)
*/
if (spec->is_default)
{
- default_index = i++;
+ default_index = i;
continue;
}
@@ -493,7 +485,6 @@ RelationBuildPartitionDesc(Relation rel)
false);
all_bounds[ndatums++] = lower;
all_bounds[ndatums++] = upper;
- i++;
}
Assert(ndatums == nparts * 2 ||
--
2.14.3 (Apple Git-98)