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;
|
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))
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -31,15 +31,18 @@
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<function>page = GenericXLogRegister(state, buffer, isNew)</> —
|
<function>page = GenericXLogRegisterBuffer(state, buffer, flags)</>
|
||||||
register a buffer to be modified within the current generic WAL
|
— 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>
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user