Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sSD5e-005E2a-RW for pgsql-hackers@arkaria.postgresql.org; Fri, 12 Jul 2024 10:01:23 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sSD5b-006meW-VP for pgsql-hackers@arkaria.postgresql.org; Fri, 12 Jul 2024 10:01:19 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sSD5b-006meO-FC for pgsql-hackers@lists.postgresql.org; Fri, 12 Jul 2024 10:01:19 +0000 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sSD5X-001ksI-OQ for pgsql-hackers@lists.postgresql.org; Fri, 12 Jul 2024 10:01:18 +0000 Received: by mail-ed1-x533.google.com with SMTP id 4fb4d7f45d1cf-5957040e32aso1145150a12.2 for ; Fri, 12 Jul 2024 03:01:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec-at.20230601.gappssmtp.com; s=20230601; t=1720778473; x=1721383273; darn=lists.postgresql.org; h=message-id:date:mime-version:comments:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=k3QAgKy3FsUnOiIbpGFDoRBxzZyQqiyYyYMgx5tUv8I=; b=RjzK9n1A4zt2Hg3BPYvAD1/FPNqiIcjupa78JyunPdSAZVltoTjiuDTLKDq9xZkXao MRo6eki7K5sPMrHQLJeTiw/4WiGTw3IOTOewn6NkBSl5ZPAtcNCJZ3x5NggMSriS/1G2 JfWP9Vvs5goRwgRSedPa69VORCcY/48pXCmN/V4NFPTga5J++2iENHBI4jT/Yq4wQAoK QErBBjgV08lW6ZDcBEkAGUTsvji58P2GATIY8ZLwOCDENOzt84jBvjVsNykvyFGEPVvF l3sgg//irXfXjO8MHdssC8UonyppQVsZ2Ydgz+sS4BnJgikTNV8MmfODkPlshJ5SKFos u2IQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720778473; x=1721383273; h=message-id:date:mime-version:comments:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=k3QAgKy3FsUnOiIbpGFDoRBxzZyQqiyYyYMgx5tUv8I=; b=kPkEW184+C1iZEVmr8BnEsuh4KcDFROiNXP2qEjxJwnrSBHigcisBLMjFoin8QHiQ9 naBdQjCMgPe6K/VYmv9lluny+eonCBAmdhyedUUzulGM3SpLFCcsDmVHzFHUFcRIAKWE QRbvFuFMo//UEsLxfo0OjKUQ1D5wUgUGdHn7JrW4XP/VCkj0Uyyw4/PbAkauCIkwfwck SlUqIAXWq5icJwIcP3+ubxKb80V+rGF9/f8ZNIzgsGPBfkH7wWtZarMXladt2M5H6/1s NjiwExsyLLdosuXefnrl+AO5gdGivo6iYhwvZO8vXOEzBnNWiPbdLd0FJRh+XgF2GWw7 p7eg== X-Gm-Message-State: AOJu0Yx1h/Q0HAzSORxpKU0gaPX+hMqdelQRU3ZQtvX9auhwvGU4j398 XnF16y19ZIv2DMhSLJW0otNJ6WgFcDklb9L/PnEL9LW6aw9886lMUjhqlNleoQg= X-Google-Smtp-Source: AGHT+IGXV69QGS92eyBCIZKOynBpZygoamKLfI2CiE+QMfrOP5CnGpC4xqvI0kXAYSPrervefdRecA== X-Received: by 2002:a05:6402:354e:b0:57d:1696:fd14 with SMTP id 4fb4d7f45d1cf-594bab80ab5mr11302053a12.8.1720778473150; Fri, 12 Jul 2024 03:01:13 -0700 (PDT) Received: from antos (109-81-174-87.rct.o2.cz. [109.81.174.87]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-594bda30a30sm4403349a12.82.2024.07.12.03.01.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jul 2024 03:01:12 -0700 (PDT) From: Antonin Houska To: Nathan Bossart cc: pgsql-hackers@lists.postgresql.org Subject: Re: Missed opportunity for bsearch() in TransactionIdIsCurrentTransactionId()? In-reply-to: References: <36977.1720623613@antos> Comments: In-reply-to Nathan Bossart message dated "Wed, 10 Jul 2024 13:59:15 -0500." X-Mailer: MH-E 8.6+git; nmh 1.8; GNU Emacs 28.2.50 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Date: Fri, 12 Jul 2024 12:01:11 +0200 Message-ID: <47366.1720778471@antos> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --=-=-= Content-Type: text/plain Nathan Bossart wrote: > On Wed, Jul 10, 2024 at 05:00:13PM +0200, Antonin Houska wrote: > > I don't quite understand why TransactionIdIsCurrentTransactionId() implements > > binary search in ParallelCurrentXids "from scratch" instead of using > > bsearch(). > > I believe there are a number of open-coded binary searches in the tree. Not sure if there are many, but I could find some: * TransactionIdIsCurrentTransactionId() * RelationHasSysCache() * pg_dump.c:getRoleName() > My concern with switching them to bsearch() would be the performance impact > of using a function pointer for the comparisons. Perhaps we could add a > couple of inlined binary search implementations for common types to replace > many of the open-coded ones. bsearch() appears to be used widely, but o.k., I don't insist on using it to replace the existing open-coded searches. What actually bothers me more than the absence of bsearch() is that TransactionIdIsCurrentTransactionId() implements the binary search from scratch. Even w/o bsearch(), it can still call TransactionIdInArray(). I ran into the problem when working on [1], which adds one more XID array. Does the attached patch seem worth being applied separately, or at all? [1] https://www.postgresql.org/message-id/82651.1720540558%40antos -- Antonin Houska Web: https://www.cybertec-postgresql.com --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Refactor-search-in-a-sorted-XID-array.patch From 470a66d0086bd8b656f88c86aec9f5861a763df7 Mon Sep 17 00:00:00 2001 From: Antonin Houska Date: Fri, 12 Jul 2024 10:06:32 +0200 Subject: [PATCH] Refactor search in a sorted XID array. First, avoid duplicate definition of TransactionIdInArray(). Second, prefer open-coded implementation to bsearch(): it's probably cheaper to compare two XIDs directly than via a bsearch() callback. --- src/backend/access/heap/heapam_visibility.c | 10 ------ src/backend/access/transam/xact.c | 29 ++--------------- .../replication/logical/reorderbuffer.c | 11 ------- src/include/access/transam.h | 32 +++++++++++++++++++ 4 files changed, 35 insertions(+), 47 deletions(-) diff --git a/src/backend/access/heap/heapam_visibility.c b/src/backend/access/heap/heapam_visibility.c index 9243feed01..d4653a28db 100644 --- a/src/backend/access/heap/heapam_visibility.c +++ b/src/backend/access/heap/heapam_visibility.c @@ -1559,16 +1559,6 @@ HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple) return true; } -/* - * check whether the transaction id 'xid' is in the pre-sorted array 'xip'. - */ -static bool -TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num) -{ - return num > 0 && - bsearch(&xid, xip, num, sizeof(TransactionId), xidComparator) != NULL; -} - /* * See the comments for HeapTupleSatisfiesMVCC for the semantics this function * obeys. diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index d119ab909d..795c04a879 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -961,33 +961,10 @@ TransactionIdIsCurrentTransactionId(TransactionId xid) /* * In parallel workers, the XIDs we must consider as current are stored in - * ParallelCurrentXids rather than the transaction-state stack. Note that - * the XIDs in this array are sorted numerically rather than according to - * transactionIdPrecedes order. + * ParallelCurrentXids rather than the transaction-state stack. */ - if (nParallelCurrentXids > 0) - { - int low, - high; - - low = 0; - high = nParallelCurrentXids - 1; - while (low <= high) - { - int middle; - TransactionId probe; - - middle = low + (high - low) / 2; - probe = ParallelCurrentXids[middle]; - if (probe == xid) - return true; - else if (probe < xid) - low = middle + 1; - else - high = middle - 1; - } - return false; - } + if (TransactionIdInArray(xid, ParallelCurrentXids, nParallelCurrentXids)) + return true; /* * We will return true for the Xid of the current subtransaction, any of diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 00a8327e77..bd3edd0b47 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -5136,17 +5136,6 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, Oid relid, const char *fname) errmsg("could not close file \"%s\": %m", path))); } - -/* - * Check whether the TransactionId 'xid' is in the pre-sorted array 'xip'. - */ -static bool -TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num) -{ - return bsearch(&xid, xip, num, - sizeof(TransactionId), xidComparator) != NULL; -} - /* * list_sort() comparator for sorting RewriteMappingFiles in LSN order. */ diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 28a2d287fd..78739b2490 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -370,6 +370,38 @@ FullTransactionIdNewer(FullTransactionId a, FullTransactionId b) return b; } +/* + * Check whether the transaction id 'xid' is in the pre-sorted array 'xip'. + * + * Note that the XIDs in this array must be sorted numerically rather than + * according to TransactionIdPrecedes order. + */ +static inline bool +TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num) +{ + int low, high; + + if (num == 0) + return false; + + low = 0; + high = num - 1; + while (low <= high) + { + int middle; + TransactionId probe; + + middle = low + (high - low) / 2; + probe = xip[middle]; + if (probe == xid) + return true; + else if (probe < xid) + low = middle + 1; + else + high = middle - 1; + } + return false; +} #endif /* FRONTEND */ #endif /* TRANSAM_H */ -- 2.45.2 --=-=-=--