1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-21 12:05:57 +03:00

Improve API of GenericXLogRegister().

Rename this function to GenericXLogRegisterBuffer() to make it clearer
what it does, and leave room for other sorts of "register" actions in
future.  Also, replace its "bool isNew" argument with an integer flags
argument, so as to allow adding more flags in future without an API
break.

Alexander Korotkov, adjusted slightly by me
This commit is contained in:
Tom Lane 2016-04-12 11:42:06 -04:00
parent bdf7db8192
commit 5713f03973
6 changed files with 41 additions and 31 deletions

View File

@ -49,7 +49,7 @@ flushCachedPage(Relation index, BloomBuildState *buildstate)
GenericXLogState *state; GenericXLogState *state;
state = GenericXLogStart(index); state = GenericXLogStart(index);
page = GenericXLogRegister(state, buffer, true); page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE);
memcpy(page, buildstate->data, BLCKSZ); memcpy(page, buildstate->data, BLCKSZ);
GenericXLogFinish(state); GenericXLogFinish(state);
UnlockReleaseBuffer(buffer); UnlockReleaseBuffer(buffer);
@ -221,7 +221,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
state = GenericXLogStart(index); state = GenericXLogStart(index);
page = GenericXLogRegister(state, buffer, false); page = GenericXLogRegisterBuffer(state, buffer, 0);
if (BloomPageAddItem(&blstate, page, itup)) if (BloomPageAddItem(&blstate, page, itup))
{ {
@ -268,7 +268,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
state = GenericXLogStart(index); state = GenericXLogStart(index);
/* get modifiable copy of metapage */ /* get modifiable copy of metapage */
metaPage = GenericXLogRegister(state, metaBuffer, false); metaPage = GenericXLogRegisterBuffer(state, metaBuffer, 0);
metaData = BloomPageGetMeta(metaPage); metaData = BloomPageGetMeta(metaPage);
if (nStart >= metaData->nEnd) if (nStart >= metaData->nEnd)
@ -279,7 +279,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
buffer = ReadBuffer(index, blkno); buffer = ReadBuffer(index, blkno);
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
page = GenericXLogRegister(state, buffer, false); page = GenericXLogRegisterBuffer(state, buffer, 0);
if (BloomPageAddItem(&blstate, page, itup)) if (BloomPageAddItem(&blstate, page, itup))
{ {
@ -305,7 +305,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
*/ */
buffer = BloomNewBuffer(index); buffer = BloomNewBuffer(index);
page = GenericXLogRegister(state, buffer, true); page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE);
BloomInitPage(page, 0); BloomInitPage(page, 0);
if (!BloomPageAddItem(&blstate, page, itup)) if (!BloomPageAddItem(&blstate, page, itup))

View File

@ -39,7 +39,7 @@ PG_FUNCTION_INFO_V1(blhandler);
/* Kind of relation optioms for bloom index */ /* Kind of relation optioms for bloom index */
static relopt_kind bl_relopt_kind; static relopt_kind bl_relopt_kind;
static int32 myRand(); static int32 myRand(void);
static void mySrand(uint32 seed); static void mySrand(uint32 seed);
/* /*
@ -173,15 +173,16 @@ initBloomState(BloomState *state, Relation index)
static int32 next; static int32 next;
static int32 static int32
myRand() myRand(void)
{ {
/* /*----------
* Compute x = (7^5 * x) mod (2^31 - 1) * Compute x = (7^5 * x) mod (2^31 - 1)
* without overflowing 31 bits: * without overflowing 31 bits:
* (2^31 - 1) = 127773 * (7^5) + 2836 * (2^31 - 1) = 127773 * (7^5) + 2836
* From "Random number generators: good ones are hard to find", * From "Random number generators: good ones are hard to find",
* Park and Miller, Communications of the ACM, vol. 31, no. 10, * Park and Miller, Communications of the ACM, vol. 31, no. 10,
* October 1988, p. 1195. * October 1988, p. 1195.
*----------
*/ */
int32 hi, lo, x; int32 hi, lo, x;
@ -418,7 +419,7 @@ BloomInitMetapage(Relation index)
/* Initialize contents of meta page */ /* Initialize contents of meta page */
state = GenericXLogStart(index); state = GenericXLogStart(index);
metaPage = GenericXLogRegister(state, metaBuffer, true); metaPage = GenericXLogRegisterBuffer(state, metaBuffer, GENERIC_XLOG_FULL_IMAGE);
BloomInitPage(metaPage, BLOOM_META); BloomInitPage(metaPage, BLOOM_META);
metadata = BloomPageGetMeta(metaPage); metadata = BloomPageGetMeta(metaPage);

View File

@ -65,7 +65,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
gxlogState = GenericXLogStart(index); gxlogState = GenericXLogStart(index);
page = GenericXLogRegister(gxlogState, buffer, false); page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
if (BloomPageIsDeleted(page)) if (BloomPageIsDeleted(page))
{ {
@ -145,7 +145,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
gxlogState = GenericXLogStart(index); gxlogState = GenericXLogStart(index);
page = GenericXLogRegister(gxlogState, buffer, false); page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
metaData = BloomPageGetMeta(page); metaData = BloomPageGetMeta(page);
memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage); memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage);

View File

@ -31,15 +31,18 @@
<listitem> <listitem>
<para> <para>
<function>page = GenericXLogRegister(state, buffer, isNew)</> &mdash; <function>page = GenericXLogRegisterBuffer(state, buffer, flags)</>
register a buffer to be modified within the current generic WAL &mdash; register a buffer to be modified within the current generic WAL
record. This function returns a pointer to a temporary copy of the record. This function returns a pointer to a temporary copy of the
buffer's page, where modifications should be made. (Do not modify the buffer's page, where modifications should be made. (Do not modify the
buffer's contents directly.) The third argument indicates if the page buffer's contents directly.) The third argument is a bitmask of flags
is new; if true, this will result in a full-page image rather than a applicable to the operation. Currently the only such flag is
delta update being included in the WAL record. <literal>GENERIC_XLOG_FULL_IMAGE</>, which indicates that a full-page
<function>GenericXLogRegister</> can be repeated if the WAL-logged image rather than a delta update should be included in the WAL record.
action needs to modify multiple pages. Typically this flag would be set if the page is new or has been
rewritten completely.
<function>GenericXLogRegisterBuffer</> can be repeated if the
WAL-logged action needs to modify multiple pages.
</para> </para>
</listitem> </listitem>
@ -71,13 +74,13 @@
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
No direct modifications of buffers are allowed! All modifications No direct modifications of buffers are allowed! All modifications must
must be done in copies acquired from <function>GenericXLogRegister()</>. be done in copies acquired from <function>GenericXLogRegisterBuffer()</>.
In other words, code that makes generic WAL records should never call In other words, code that makes generic WAL records should never call
<function>BufferGetPage()</> for itself. However, it remains the <function>BufferGetPage()</> for itself. However, it remains the
caller's responsibility to pin/unpin and lock/unlock the buffers at caller's responsibility to pin/unpin and lock/unlock the buffers at
appropriate times. Exclusive lock must be held on each target buffer appropriate times. Exclusive lock must be held on each target buffer
from before <function>GenericXLogRegister()</> until after from before <function>GenericXLogRegisterBuffer()</> until after
<function>GenericXLogFinish()</>. <function>GenericXLogFinish()</>.
</para> </para>
</listitem> </listitem>
@ -145,10 +148,11 @@
<listitem> <listitem>
<para> <para>
If a registered buffer is not new, the generic WAL record contains If <literal>GENERIC_XLOG_FULL_IMAGE</> is not specified for a
a delta between the old and the new page images. This delta is based registered buffer, the generic WAL record contains a delta between
on byte-by-byte comparison. This is not very compact for the case of the old and the new page images. This delta is based on byte-by-byte
moving data within a page, and might be improved in the future. comparison. This is not very compact for the case of moving data
within a page, and might be improved in the future.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View File

@ -50,7 +50,7 @@
typedef struct typedef struct
{ {
Buffer buffer; /* registered buffer */ Buffer buffer; /* registered buffer */
bool fullImage; /* are we taking a full image of this page? */ int flags; /* flags for this buffer */
int deltaLen; /* space consumed in delta field */ int deltaLen; /* space consumed in delta field */
char image[BLCKSZ]; /* copy of page image for modification */ char image[BLCKSZ]; /* copy of page image for modification */
char delta[MAX_DELTA_SIZE]; /* delta between page images */ char delta[MAX_DELTA_SIZE]; /* delta between page images */
@ -280,9 +280,11 @@ GenericXLogStart(Relation relation)
* is what the caller should modify. * is what the caller should modify.
* *
* If the buffer is already registered, just return its existing entry. * If the buffer is already registered, just return its existing entry.
* (It's not very clear what to do with the flags in such a case, but
* for now we stay with the original flags.)
*/ */
Page Page
GenericXLogRegister(GenericXLogState *state, Buffer buffer, bool isNew) GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
{ {
int block_id; int block_id;
@ -295,7 +297,7 @@ GenericXLogRegister(GenericXLogState *state, Buffer buffer, bool isNew)
{ {
/* Empty slot, so use it (there cannot be a match later) */ /* Empty slot, so use it (there cannot be a match later) */
page->buffer = buffer; page->buffer = buffer;
page->fullImage = isNew; page->flags = flags;
memcpy(page->image, memcpy(page->image,
BufferGetPage(buffer, NULL, NULL, BGP_NO_SNAPSHOT_TEST), BufferGetPage(buffer, NULL, NULL, BGP_NO_SNAPSHOT_TEST),
BLCKSZ); BLCKSZ);
@ -347,7 +349,7 @@ GenericXLogFinish(GenericXLogState *state)
BGP_NO_SNAPSHOT_TEST); BGP_NO_SNAPSHOT_TEST);
pageHeader = (PageHeader) pageData->image; pageHeader = (PageHeader) pageData->image;
if (pageData->fullImage) if (pageData->flags & GENERIC_XLOG_FULL_IMAGE)
{ {
/* /*
* A full-page image does not require us to supply any xlog * A full-page image does not require us to supply any xlog

View File

@ -22,14 +22,17 @@
#define MAX_GENERIC_XLOG_PAGES XLR_NORMAL_MAX_BLOCK_ID #define MAX_GENERIC_XLOG_PAGES XLR_NORMAL_MAX_BLOCK_ID
/* Flag bits for GenericXLogRegisterBuffer */
#define GENERIC_XLOG_FULL_IMAGE 0x0001 /* write full-page image */
/* state of generic xlog record construction */ /* state of generic xlog record construction */
struct GenericXLogState; struct GenericXLogState;
typedef struct GenericXLogState GenericXLogState; typedef struct GenericXLogState GenericXLogState;
/* API for construction of generic xlog records */ /* API for construction of generic xlog records */
extern GenericXLogState *GenericXLogStart(Relation relation); extern GenericXLogState *GenericXLogStart(Relation relation);
extern Page GenericXLogRegister(GenericXLogState *state, Buffer buffer, extern Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer,
bool isNew); int flags);
extern XLogRecPtr GenericXLogFinish(GenericXLogState *state); extern XLogRecPtr GenericXLogFinish(GenericXLogState *state);
extern void GenericXLogAbort(GenericXLogState *state); extern void GenericXLogAbort(GenericXLogState *state);