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 1qLclr-000Hl2-SD for pgsql-hackers@arkaria.postgresql.org; Tue, 18 Jul 2023 04:57:11 +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 1qLclp-003n3w-1F for pgsql-hackers@arkaria.postgresql.org; Tue, 18 Jul 2023 04:57:09 +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 1qLclo-003n3o-M7 for pgsql-hackers@lists.postgresql.org; Tue, 18 Jul 2023 04:57:08 +0000 Received: from mail-oa1-x2b.google.com ([2001:4860:4864:20::2b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qLcll-00045s-1Q for pgsql-hackers@lists.postgresql.org; Tue, 18 Jul 2023 04:57:08 +0000 Received: by mail-oa1-x2b.google.com with SMTP id 586e51a60fabf-1b0719dd966so4150120fac.1 for ; Mon, 17 Jul 2023 21:57:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1689656224; x=1692248224; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=MsAb96r2yYpV+QWTQZOgJEdTO05GcCtV66CcF6Q8+34=; b=hX3LYx6G0W4JZ03AkPQ9GpEiEpWdaiKS6yyWBFLnXuhw4epQS3JrCVvDwvka7L0OXC seIvDOkYuKHC9Q0heentXxJsbe0QdHugr1WgUINXxoYrUzSJ/CH5AYi35OGnvW6JE7Sh KrobZ0bB55m1zdz21aYjLdWLxuOg+N7TGkFWjVscZ5fobUrsJoV7V9WrvxsaexShVE1E TvBbUjEsYkl7XAOmmuND0cMecqwAfF6PBnGd3NyR9D30jYAP7T+Rqvw2MKXKF+erhZiC 4GY+t8qr2aKtXxvDLjOR2dEWgQexr0kLI6maU3Rjl8Nw5f8QWDYh9L0pa2fBMG+utGZx txNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689656224; x=1692248224; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=MsAb96r2yYpV+QWTQZOgJEdTO05GcCtV66CcF6Q8+34=; b=jpDevMIU0Pfg3+sAYqJzFoSq0S1kEoAWb0BQ2cc1DTmJuim7ekW/WTm3TNXq1QAzg9 q0/4z3jV6sViAXIf5f+aFmAS+BqJtj89D/BTWZt/EXss60yU7xA9/9XOmcE1q+L1FIa3 UdRyr0rrJsMc3IbRc0BWsRZG9C4tmnHY5uGhOTExYJYvGh2VUXYTTr9bpYH7SPhQbZr/ ui+P1ci42ppaV/yrXLiPv9syNZo9+txiBQQh02F1OKchlgs70EkTasL/uGAqwMw8PQUt MjUNBaIdVG29uRZ5iLEkrSLTcRDsXWXez0k8Ky2PXgiJ1Obo8vCjI7gLvTXyo4W03cGv J2Yg== X-Gm-Message-State: ABy/qLab5pBqKc4vivseq7PWNIQBrpqUaIH2+SnvQrqQeIuoOBV9OR6M NfQ71A2aL7aTFmC4CQjIBoI= X-Google-Smtp-Source: APBJJlFwONhRtmaVNcReJRRHKADLvmUeRsvwqaFl0u1r74qPApY4xqqYn/cxmAhaKNQ2+4JNUpRyrw== X-Received: by 2002:a05:6870:9583:b0:1b0:f38:90f6 with SMTP id k3-20020a056870958300b001b00f3890f6mr16709744oao.7.1689656224196; Mon, 17 Jul 2023 21:57:04 -0700 (PDT) Received: from nathanxps13 ([50.47.162.83]) by smtp.gmail.com with ESMTPSA id t1-20020a63b241000000b0055bf13811f5sm679655pgo.15.2023.07.17.21.57.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jul 2023 21:57:03 -0700 (PDT) Date: Mon, 17 Jul 2023 21:57:01 -0700 From: Nathan Bossart To: Tom Lane Cc: Andrew Dunstan , pgsql-hackers@lists.postgresql.org Subject: Re: Inefficiency in parallel pg_restore with many tables Message-ID: <20230718045701.GA1090171@nathanxps13> References: <3612876.1689443232@sss.pgh.pa.us> <3787685.1689515154@sss.pgh.pa.us> <20230717035424.GA541888@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="jI8keyz6grp/JLjh" Content-Disposition: inline In-Reply-To: <20230717035424.GA541888@nathanxps13> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --jI8keyz6grp/JLjh Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, Jul 16, 2023 at 08:54:24PM -0700, Nathan Bossart wrote: > This seems worth a try. IIUC you are suggesting making binaryheap.c > frontend-friendly and expanding its API a bit. If no one has volunteered, > I could probably hack something together. I spent some time on the binaryheap changes. I haven't had a chance to plug it into the ready_list yet. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --jI8keyz6grp/JLjh Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="expand_binaryheap_api.patch" diff --git a/src/backend/lib/binaryheap.c b/src/backend/lib/binaryheap.c index 1737546757..36b6f5c51f 100644 --- a/src/backend/lib/binaryheap.c +++ b/src/backend/lib/binaryheap.c @@ -11,10 +11,17 @@ *------------------------------------------------------------------------- */ +#ifndef FRONTEND #include "postgres.h" +#else +#include "postgres_fe.h" +#endif #include +#ifdef FRONTEND +#include "common/logging.h" +#endif #include "lib/binaryheap.h" static void sift_down(binaryheap *heap, int node_off); @@ -35,7 +42,11 @@ binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg) binaryheap *heap; sz = offsetof(binaryheap, bh_nodes) + sizeof(Datum) * capacity; +#ifdef FRONTEND + heap = (binaryheap *) pg_malloc(sz); +#else heap = (binaryheap *) palloc(sz); +#endif heap->bh_space = capacity; heap->bh_compare = compare; heap->bh_arg = arg; @@ -109,7 +120,11 @@ void binaryheap_add_unordered(binaryheap *heap, Datum d) { if (heap->bh_size >= heap->bh_space) +#ifdef FRONTEND + pg_fatal("out of binary heap slots"); +#else elog(ERROR, "out of binary heap slots"); +#endif heap->bh_has_heap_property = false; heap->bh_nodes[heap->bh_size] = d; heap->bh_size++; @@ -141,7 +156,11 @@ void binaryheap_add(binaryheap *heap, Datum d) { if (heap->bh_size >= heap->bh_space) +#ifdef FRONTEND + pg_fatal("out of binary heap slots"); +#else elog(ERROR, "out of binary heap slots"); +#endif heap->bh_nodes[heap->bh_size] = d; heap->bh_size++; sift_up(heap, heap->bh_size - 1); @@ -196,6 +215,65 @@ binaryheap_remove_first(binaryheap *heap) return result; } +/* + * binaryheap_remove + * + * Removes the given datum from the heap. The caller must ensure that the + * datum exists in the heap. Always O(n). + */ +void +binaryheap_remove(binaryheap *heap, Datum d) +{ + Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property); + + for (int i = 0; i < heap->bh_size; i++) + { + if (heap->bh_compare(heap->bh_nodes[i], + d, + heap->bh_arg) == 0) + { + binaryheap_remove_node(heap, &heap->bh_nodes[i]); + return; + } + } + +#ifdef FRONTEND + pg_fatal("datum not found in heap"); +#else + elog(ERROR, "datum not found in heap"); +#endif +} + +/* + * binaryheap_remove_node + * + * Removes the given node from the heap. The caller must ensure that the node + * exists in the heap. O(log n) worst case. + */ +void +binaryheap_remove_node(binaryheap *heap, Datum *n) +{ + int cmp; + + Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property); + Assert(n >= &heap->bh_nodes[0]); + Assert(n <= &heap->bh_nodes[heap->bh_size - 1]); + + /* compare last node to the one that is being removed */ + cmp = heap->bh_compare(heap->bh_nodes[--heap->bh_size], + *n, + heap->bh_arg); + + /* remove the last node, placing it in the vacated entry */ + *n = heap->bh_nodes[heap->bh_size]; + + /* sift as needed to preserve the heap property */ + if (cmp > 0) + sift_up(heap, n - &heap->bh_nodes[0]); + else if (cmp < 0) + sift_down(heap, n - &heap->bh_nodes[0]); +} + /* * binaryheap_replace_first * diff --git a/src/include/lib/binaryheap.h b/src/include/lib/binaryheap.h index 52f7b06b25..411f7358ba 100644 --- a/src/include/lib/binaryheap.h +++ b/src/include/lib/binaryheap.h @@ -47,6 +47,8 @@ extern void binaryheap_build(binaryheap *heap); extern void binaryheap_add(binaryheap *heap, Datum d); extern Datum binaryheap_first(binaryheap *heap); extern Datum binaryheap_remove_first(binaryheap *heap); +extern void binaryheap_remove(binaryheap *heap, Datum d); +extern void binaryheap_remove_node(binaryheap *heap, Datum *n); extern void binaryheap_replace_first(binaryheap *heap, Datum d); #define binaryheap_empty(h) ((h)->bh_size == 0) --jI8keyz6grp/JLjh--