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:
parent
bdf7db8192
commit
5713f03973
@ -49,7 +49,7 @@ flushCachedPage(Relation index, BloomBuildState *buildstate)
|
||||
GenericXLogState *state;
|
||||
|
||||
state = GenericXLogStart(index);
|
||||
page = GenericXLogRegister(state, buffer, true);
|
||||
page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE);
|
||||
memcpy(page, buildstate->data, BLCKSZ);
|
||||
GenericXLogFinish(state);
|
||||
UnlockReleaseBuffer(buffer);
|
||||
@ -221,7 +221,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
|
||||
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
|
||||
|
||||
state = GenericXLogStart(index);
|
||||
page = GenericXLogRegister(state, buffer, false);
|
||||
page = GenericXLogRegisterBuffer(state, buffer, 0);
|
||||
|
||||
if (BloomPageAddItem(&blstate, page, itup))
|
||||
{
|
||||
@ -268,7 +268,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
|
||||
state = GenericXLogStart(index);
|
||||
|
||||
/* get modifiable copy of metapage */
|
||||
metaPage = GenericXLogRegister(state, metaBuffer, false);
|
||||
metaPage = GenericXLogRegisterBuffer(state, metaBuffer, 0);
|
||||
metaData = BloomPageGetMeta(metaPage);
|
||||
|
||||
if (nStart >= metaData->nEnd)
|
||||
@ -279,7 +279,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
|
||||
|
||||
buffer = ReadBuffer(index, blkno);
|
||||
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
|
||||
page = GenericXLogRegister(state, buffer, false);
|
||||
page = GenericXLogRegisterBuffer(state, buffer, 0);
|
||||
|
||||
if (BloomPageAddItem(&blstate, page, itup))
|
||||
{
|
||||
@ -305,7 +305,7 @@ blinsert(Relation index, Datum *values, bool *isnull,
|
||||
*/
|
||||
buffer = BloomNewBuffer(index);
|
||||
|
||||
page = GenericXLogRegister(state, buffer, true);
|
||||
page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE);
|
||||
BloomInitPage(page, 0);
|
||||
|
||||
if (!BloomPageAddItem(&blstate, page, itup))
|
||||
|
@ -39,7 +39,7 @@ PG_FUNCTION_INFO_V1(blhandler);
|
||||
/* Kind of relation optioms for bloom index */
|
||||
static relopt_kind bl_relopt_kind;
|
||||
|
||||
static int32 myRand();
|
||||
static int32 myRand(void);
|
||||
static void mySrand(uint32 seed);
|
||||
|
||||
/*
|
||||
@ -173,15 +173,16 @@ initBloomState(BloomState *state, Relation index)
|
||||
static int32 next;
|
||||
|
||||
static int32
|
||||
myRand()
|
||||
myRand(void)
|
||||
{
|
||||
/*
|
||||
/*----------
|
||||
* Compute x = (7^5 * x) mod (2^31 - 1)
|
||||
* without overflowing 31 bits:
|
||||
* (2^31 - 1) = 127773 * (7^5) + 2836
|
||||
* From "Random number generators: good ones are hard to find",
|
||||
* Park and Miller, Communications of the ACM, vol. 31, no. 10,
|
||||
* October 1988, p. 1195.
|
||||
*----------
|
||||
*/
|
||||
int32 hi, lo, x;
|
||||
|
||||
@ -418,7 +419,7 @@ BloomInitMetapage(Relation index)
|
||||
|
||||
/* Initialize contents of meta page */
|
||||
state = GenericXLogStart(index);
|
||||
metaPage = GenericXLogRegister(state, metaBuffer, true);
|
||||
metaPage = GenericXLogRegisterBuffer(state, metaBuffer, GENERIC_XLOG_FULL_IMAGE);
|
||||
|
||||
BloomInitPage(metaPage, BLOOM_META);
|
||||
metadata = BloomPageGetMeta(metaPage);
|
||||
|
@ -65,7 +65,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
||||
|
||||
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
|
||||
gxlogState = GenericXLogStart(index);
|
||||
page = GenericXLogRegister(gxlogState, buffer, false);
|
||||
page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
|
||||
|
||||
if (BloomPageIsDeleted(page))
|
||||
{
|
||||
@ -145,7 +145,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
||||
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
|
||||
|
||||
gxlogState = GenericXLogStart(index);
|
||||
page = GenericXLogRegister(gxlogState, buffer, false);
|
||||
page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
|
||||
|
||||
metaData = BloomPageGetMeta(page);
|
||||
memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage);
|
||||
|
@ -31,15 +31,18 @@
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>page = GenericXLogRegister(state, buffer, isNew)</> —
|
||||
register a buffer to be modified within the current generic WAL
|
||||
<function>page = GenericXLogRegisterBuffer(state, buffer, flags)</>
|
||||
— register a buffer to be modified within the current generic WAL
|
||||
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 contents directly.) The third argument indicates if the page
|
||||
is new; if true, this will result in a full-page image rather than a
|
||||
delta update being included in the WAL record.
|
||||
<function>GenericXLogRegister</> can be repeated if the WAL-logged
|
||||
action needs to modify multiple pages.
|
||||
buffer's contents directly.) The third argument is a bitmask of flags
|
||||
applicable to the operation. Currently the only such flag is
|
||||
<literal>GENERIC_XLOG_FULL_IMAGE</>, which indicates that a full-page
|
||||
image rather than a delta update should be included in the WAL record.
|
||||
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>
|
||||
</listitem>
|
||||
|
||||
@ -71,13 +74,13 @@
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
No direct modifications of buffers are allowed! All modifications
|
||||
must be done in copies acquired from <function>GenericXLogRegister()</>.
|
||||
No direct modifications of buffers are allowed! All modifications must
|
||||
be done in copies acquired from <function>GenericXLogRegisterBuffer()</>.
|
||||
In other words, code that makes generic WAL records should never call
|
||||
<function>BufferGetPage()</> for itself. However, it remains the
|
||||
caller's responsibility to pin/unpin and lock/unlock the buffers at
|
||||
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()</>.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -145,10 +148,11 @@
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
If a registered buffer is not new, the generic WAL record contains
|
||||
a delta between the old and the new page images. This delta is based
|
||||
on byte-by-byte comparison. This is not very compact for the case of
|
||||
moving data within a page, and might be improved in the future.
|
||||
If <literal>GENERIC_XLOG_FULL_IMAGE</> is not specified for a
|
||||
registered buffer, the generic WAL record contains a delta between
|
||||
the old and the new page images. This delta is based on byte-by-byte
|
||||
comparison. This is not very compact for the case of moving data
|
||||
within a page, and might be improved in the future.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -50,7 +50,7 @@
|
||||
typedef struct
|
||||
{
|
||||
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 */
|
||||
char image[BLCKSZ]; /* copy of page image for modification */
|
||||
char delta[MAX_DELTA_SIZE]; /* delta between page images */
|
||||
@ -280,9 +280,11 @@ GenericXLogStart(Relation relation)
|
||||
* is what the caller should modify.
|
||||
*
|
||||
* 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
|
||||
GenericXLogRegister(GenericXLogState *state, Buffer buffer, bool isNew)
|
||||
GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
|
||||
{
|
||||
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) */
|
||||
page->buffer = buffer;
|
||||
page->fullImage = isNew;
|
||||
page->flags = flags;
|
||||
memcpy(page->image,
|
||||
BufferGetPage(buffer, NULL, NULL, BGP_NO_SNAPSHOT_TEST),
|
||||
BLCKSZ);
|
||||
@ -347,7 +349,7 @@ GenericXLogFinish(GenericXLogState *state)
|
||||
BGP_NO_SNAPSHOT_TEST);
|
||||
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
|
||||
|
@ -22,14 +22,17 @@
|
||||
|
||||
#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 */
|
||||
struct GenericXLogState;
|
||||
typedef struct GenericXLogState GenericXLogState;
|
||||
|
||||
/* API for construction of generic xlog records */
|
||||
extern GenericXLogState *GenericXLogStart(Relation relation);
|
||||
extern Page GenericXLogRegister(GenericXLogState *state, Buffer buffer,
|
||||
bool isNew);
|
||||
extern Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer,
|
||||
int flags);
|
||||
extern XLogRecPtr GenericXLogFinish(GenericXLogState *state);
|
||||
extern void GenericXLogAbort(GenericXLogState *state);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user