Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i0c98-0001rv-Lv for pgsql-hackers@arkaria.postgresql.org; Thu, 22 Aug 2019 01:44:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1i0c95-00019h-W9 for pgsql-hackers@arkaria.postgresql.org; Thu, 22 Aug 2019 01:44:11 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i0c95-00019a-Lp for pgsql-hackers@lists.postgresql.org; Thu, 22 Aug 2019 01:44:11 +0000 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i0c91-00015k-Gx for pgsql-hackers@postgresql.org; Thu, 22 Aug 2019 01:44:10 +0000 Received: by mail-pf1-x442.google.com with SMTP id q139so2701059pfc.13 for ; Wed, 21 Aug 2019 18:44:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:message-id:to:cc:subject:from:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=YLzQWr2ccjXiC0rezI0RPD+TYyOwXLZS2BOZqQqrTBo=; b=qOA49XkQcm8KRma24R5fB0J4yw8MgmG7zYmsIAE0gN7POBDzuomA2kQYNZB1dBZxqr Q/vbsDhRLcdoFdjYG1/tIaERrwJGl5t3dcNzfbyI3ij7ATt9cQK7twTMrhN67GA1+weg zC3tnTyh7VAnECz14pXqqvQSpSXutbQnDuqQufN4wabY2d0oB2YYg3wz1I+gRxdxvSpk KbbOUinLTih3SxqUHEzT6o5Hj0TkEX4uYRxg/lu3+3I/XkVNDfxgLq7bKrAvVAcQF8wM r+FHyYEQFzQ949cqQYZvwg0F6whM0rpnWqGlgjRYaghIyP0DoCczSdau9hQdfQOBZK5R QMTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:to:cc:subject:from:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=YLzQWr2ccjXiC0rezI0RPD+TYyOwXLZS2BOZqQqrTBo=; b=K3DKUA6e/SAuygfquXDbMCE23+dOgnKS0TOOv3bI7OuaipBBmBrhMdTyjZt0VaiPHI lN4chP+V8Tt28T+x4xZANQe/7PAnZWrb6b5B8PnmlaiZ72W1JhGH7Q8iGbw/L41jTN2c m6NWKNzRshlSqzB5j57E+Vtqu6cBXoTPueDa1KQvjuV8AF/kgqnToxHltCzf5uPZYjAh F3FYiWS2p+9+ImSxt0N9MFqtkeJxqQK9lM4N/jOBXLvbIUBe8lPy8d4q0SRglqcql76V Eh8L+IeujDeoQPGUkgyHJdB4uUBMVy+VK5kJFtPfUhWQm4y23ynopfuSqxzSo5cWbeLC /4Iw== X-Gm-Message-State: APjAAAVIOf7bihQPeqKFwjR3HvH+fsiOYO0walYkcJ0DoSoXa44pUi0u 5xNBaO+oojC5U2GFvfVxfjo= X-Google-Smtp-Source: APXvYqxM7xI+gpafOp6WNo4OkjkQjkuZ4Yp4ADM1qp80qxRhkOFvqaTt6rTUW32EdoztOUUKwySSnA== X-Received: by 2002:a17:90a:d34f:: with SMTP id i15mr2982359pjx.42.1566438245006; Wed, 21 Aug 2019 18:44:05 -0700 (PDT) Received: from localhost (w204177.dynamic.ppp.asahi-net.or.jp. [121.1.204.177]) by smtp.gmail.com with ESMTPSA id a10sm34984375pfl.159.2019.08.21.18.44.02 (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Aug 2019 18:44:04 -0700 (PDT) Date: Thu, 22 Aug 2019 10:43:52 +0900 (Tokyo Standard Time) Message-Id: <20190822.104352.26342272.horikyota.ntt@gmail.com> To: hlinnaka@iki.fi Cc: andres@anarazel.de, pgsql-hackers@postgresql.org Subject: Re: Remove page-read callback from XLogReaderState. From: Kyotaro Horiguchi In-Reply-To: References: <20190528114524.dvj6ymap2virlzro@alap3.anarazel.de> <20190712.161016.56338282.horikyota.ntt@gmail.com> User-Agent: Mew version 6.5 on Emacs 22.2 / Mule 5.0 =?iso-2022-jp?B?KBskQjpnGyhCKQ==?= / Meadow-3.01-dev (TSUBO-SUMIRE) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Thank you for the suggestion, Heikki. At Mon, 29 Jul 2019 22:39:57 +0300, Heikki Linnakangas wrote in > On 12/07/2019 10:10, Kyotaro Horiguchi wrote: > >> Just FYI, to me this doesn't clearly enough look like an improvement, > >> for a change of this size. > > Thanks for the opiniton. I kinda agree about size but it is a > > decision between "having multiple callbacks called under the > > hood" vs "just calling a series of functions". I think the > > patched XlogReadRecord is easy to use in many situations. > > It would be better if I could completely refactor the function > > without the syntax tricks but I think the current patch is still > > smaller and clearer than overhauling it. > > I like the idea of refactoring XLogReadRecord() to not use a callback, > and return a XLREAD_NEED_DATA value instead. It feels like a nicer, > easier-to-use, interface, given that all the page-read functions need > quite a bit of state and internal logic themselves. I remember that I > felt that that would be a nicer interface when we originally extracted > xlogreader.c into a reusable module, but I didn't want to make such > big changes to XLogReadRecord() at that point. > > I don't much like the "continuation" style of implementing the state > machine. Nothing wrong with such a style in principle, but we don't do > that anywhere else, and the macros seem like overkill, and turning the Agreed that it's a kind of ugly. I could overhaul the logic to reduce state variables, but I thought that it would make the patch hardly reviewable. The "continuation" style was intended to impact the main path's shape as small as possible. For the same reason I made variables static instead of using individual state struct or reducing state variables. (And it the style was fun for me:p) > local variables static is pretty ugly. But I think XLogReadRecord() > could be rewritten into a more traditional state machine. > > I started hacking on that, to get an idea of what it would look like > and came up with the attached patch, to be applied on top of all your > patches. It's still very messy, it needs quite a lot of cleanup before > it can be committed, but I think the resulting switch-case state > machine in XLogReadRecord() is quite straightforward at high level, > with four states. Sorry for late reply. It seems less messy than I thought it could be if I refactored it more aggressively. > I made some further changes to the XLogReadRecord() interface: > > * If you pass a valid ReadPtr (i.e. the starting point to read from) > * argument to XLogReadRecord(), it always restarts reading from that > * record, even if it was in the middle of reading another record > * previously. (Perhaps it would be more convenient to provide a separate > * function to set the starting point, and remove the RecPtr argument > * from XLogReadRecord altogther?) Seems reasonable. randAccess property was replaced with the state.PrevRecPtr = Invalid. It is easier to understand for me. > * XLogReaderState->readBuf is now allocated and controlled by the > * caller, not by xlogreader.c itself. When XLogReadRecord() needs data, > * the caller makes the data available in readBuf, which can point to the > * same buffer in all calls, or the caller may allocate a new buffer, or > * it may point to a part of a larger buffer, whatever is convenient for > * the caller. (Currently, all callers just allocate a BLCKSZ'd buffer, > * though). The caller also sets readPagPtr, readLen and readPageTLI to > * tell XLogReadRecord() what's in the buffer. So all these read* fields > * are now set by the caller, XLogReadRecord() only reads them. The caller knows how many byes to be read. So the caller provides the required buffer seems reasonable. > * In your patch, if XLogReadRecord() was called with state->readLen == > * -1, XLogReadRecord() returned an error. That seemed a bit silly; if an > * error happened while reading the data, why call XLogReadRecord() at > * all? You could just report the error directly. So I removed that. Agreed. I forgot to move the error handling to more proper location. > I'm not sure how intelligible this patch is in its current state. But > I think the general idea is good. I plan to clean it up further next > week, but feel free to work on it before that, either based on this > patch or by starting afresh from your patch set. I think you diff is intelligible enough for me. I'll take this if you haven't done. Anyway I'm staring on this. Thanks! -- Kyotaro Horiguchi NTT Open Source Software Center