LogicalRepPartMap is keyed by the partition's OID, which is assigned
to entry->relmapentry.localreloid when the entry is populated in
logicalrep_partition_open(). The invalidation callback therefore
does not need to iterate over every entry to find the one matching
the invalidated relation OID; a single hash_search(HASH_FIND) on
reloid suffices.
This replaces an O(N) hash_seq_search loop with an O(1) lookup and
removes the longstanding "TODO, use inverse lookup hashtable?"
comment. An Assert in logicalrep_partition_open() documents the
partOid == entry->relmapentry.localreloid invariant that the new
path relies on.
---
Tested on an --enable-cassert build: the full src/test/subscription
TAP suite (39 files, 579 tests) passes, including 013_partition.pl
which exercises the partmap invalidation path via ADD COLUMN on a
partitioned root (cascades a relcache inval to every leaf partition).
src/backend/replication/logical/relation.c | 23 +++++++++-------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index 0b1d80b5b0f..f6e2a9a6422 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -544,20 +544,14 @@ logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid)
if (reloid != InvalidOid)
{
- HASH_SEQ_STATUS status;
-
- hash_seq_init(&status, LogicalRepPartMap);
-
- /* TODO, use inverse lookup hashtable? */
- while ((entry = (LogicalRepPartMapEntry *) hash_seq_search(&status)) != NULL)
- {
- if (entry->relmapentry.localreloid == reloid)
- {
- entry->relmapentry.localrelvalid = false;
- hash_seq_term(&status);
- break;
- }
- }
+ /*
+ * LogicalRepPartMap is keyed by partition OID, which matches
+ * entry->relmapentry.localreloid (see logicalrep_partition_open), so
+ * we can invalidate via a direct hash lookup.
+ */
+ entry = hash_search(LogicalRepPartMap, &reloid, HASH_FIND, NULL);
+ if (entry != NULL)
+ entry->relmapentry.localrelvalid = false;
}
else
{
@@ -676,6 +670,7 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
*/
if (found && entry->localrelvalid)
{
+ Assert(entry->localreloid == partOid);
entry->localrel = partrel;
return entry;
}