mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Add support for building GiST index by sorting.
This adds a new optional support function to the GiST access method: sortsupport. If it is defined, the GiST index is built by sorting all data to the order defined by the sortsupport's comparator function, and packing the tuples in that order to GiST pages. This is similar to how B-tree index build works, and is much faster than inserting the tuples one by one. The resulting index is smaller too, because the pages are packed more tightly, upto 'fillfactor'. The normal build method works by splitting pages, which tends to lead to more wasted space. The quality of the resulting index depends on how good the opclass-defined sort order is. A good order preserves locality of the input data. As the first user of this facility, add 'sortsupport' function to the point_ops opclass. It sorts the points in Z-order (aka Morton Code), by interleaving the bits of the X and Y coordinates. Author: Andrey Borodin Reviewed-by: Pavel Borisov, Thomas Munro Discussion: https://www.postgresql.org/message-id/1A36620E-CAD8-4267-9067-FB31385E7C0D%40yandex-team.ru
This commit is contained in:
@ -1019,6 +1019,63 @@ log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno,
|
||||
return recptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like log_newpage(), but allows logging multiple pages in one operation.
|
||||
* It is more efficient than calling log_newpage() for each page separately,
|
||||
* because we can write multiple pages in a single WAL record.
|
||||
*/
|
||||
void
|
||||
log_newpages(RelFileNode *rnode, ForkNumber forkNum, int num_pages,
|
||||
BlockNumber *blknos, Page *pages, bool page_std)
|
||||
{
|
||||
int flags;
|
||||
XLogRecPtr recptr;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
flags = REGBUF_FORCE_IMAGE;
|
||||
if (page_std)
|
||||
flags |= REGBUF_STANDARD;
|
||||
|
||||
/*
|
||||
* Iterate over all the pages. They are collected into batches of
|
||||
* XLR_MAX_BLOCK_ID pages, and a single WAL-record is written for each
|
||||
* batch.
|
||||
*/
|
||||
XLogEnsureRecordSpace(XLR_MAX_BLOCK_ID - 1, 0);
|
||||
|
||||
i = 0;
|
||||
while (i < num_pages)
|
||||
{
|
||||
int batch_start = i;
|
||||
int nbatch;
|
||||
|
||||
XLogBeginInsert();
|
||||
|
||||
nbatch = 0;
|
||||
while (nbatch < XLR_MAX_BLOCK_ID && i < num_pages)
|
||||
{
|
||||
XLogRegisterBlock(nbatch, rnode, forkNum, blknos[i], pages[i], flags);
|
||||
i++;
|
||||
nbatch++;
|
||||
}
|
||||
|
||||
recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI);
|
||||
|
||||
for (j = batch_start; j < i; j++)
|
||||
{
|
||||
/*
|
||||
* The page may be uninitialized. If so, we can't set the LSN because that
|
||||
* would corrupt the page.
|
||||
*/
|
||||
if (!PageIsNew(pages[j]))
|
||||
{
|
||||
PageSetLSN(pages[j], recptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a WAL record containing a full image of a page.
|
||||
*
|
||||
|
Reference in New Issue
Block a user