Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 04dadd7

Browse files
committed
add leftlink to entry/data trees
1 parent 8c6546f commit 04dadd7

File tree

4 files changed

+71
-29
lines changed

4 files changed

+71
-29
lines changed

rum.h

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
*/
3535
typedef struct RumPageOpaqueData
3636
{
37+
BlockNumber leftlink; /* prev page if any */
3738
BlockNumber rightlink; /* next page if any */
3839
OffsetNumber maxoff; /* number entries on RUM_DATA page: number of
3940
* heap ItemPointers on RUM_DATA|RUM_LEAF page

rumbtree.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,11 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
376376
/* this loop crawls up the stack until the insertion is complete */
377377
for (;;)
378378
{
379-
BlockNumber savedRightLink;
379+
BlockNumber savedLeftLink,
380+
savedRightLink;
380381

381382
page = BufferGetPage(stack->buffer);
383+
savedLeftLink = RumPageGetOpaque(page)->leftlink;
382384
savedRightLink = RumPageGetOpaque(page)->rightlink;
383385

384386
if (btree->isEnoughSpace(btree, stack->buffer, stack->off))
@@ -436,6 +438,8 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
436438
GENERIC_XLOG_FULL_IMAGE);
437439

438440
RumPageGetOpaque(rpage)->rightlink = InvalidBlockNumber;
441+
RumPageGetOpaque(newlpage)->leftlink = InvalidBlockNumber;
442+
RumPageGetOpaque(rpage)->leftlink = BufferGetBlockNumber(lbuffer);
439443
RumPageGetOpaque(newlpage)->rightlink = BufferGetBlockNumber(rbuffer);
440444

441445
RumInitPage(page, RumPageGetOpaque(newlpage)->flags & ~RUM_LEAF,
@@ -480,6 +484,8 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
480484
lpage, rpage, stack->off);
481485

482486
RumPageGetOpaque(rpage)->rightlink = savedRightLink;
487+
RumPageGetOpaque(newlpage)->leftlink = savedLeftLink;
488+
RumPageGetOpaque(rpage)->leftlink = BufferGetBlockNumber(stack->buffer);
483489
RumPageGetOpaque(newlpage)->rightlink = BufferGetBlockNumber(rbuffer);
484490

485491
PageRestoreTempPage(newlpage, lpage);

rumutil.c

+1
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ RumInitPage(Page page, uint32 f, Size pageSize)
481481
opaque = RumPageGetOpaque(page);
482482
memset(opaque, 0, sizeof(RumPageOpaqueData));
483483
opaque->flags = f;
484+
opaque->leftlink = InvalidBlockNumber;
484485
opaque->rightlink = InvalidBlockNumber;
485486
}
486487

rumvacuum.c

+62-28
Original file line numberDiff line numberDiff line change
@@ -305,19 +305,42 @@ rumVacuumPostingTreeLeaves(RumVacuumState * gvs, OffsetNumber attnum,
305305
/*
306306
* Delete a posting tree page.
307307
*/
308-
static void
309-
rumDeletePage(RumVacuumState * gvs, BlockNumber deleteBlkno, BlockNumber leftBlkno,
308+
static bool
309+
rumDeletePage(RumVacuumState * gvs, BlockNumber deleteBlkno,
310310
BlockNumber parentBlkno, OffsetNumber myoff, bool isParentRoot)
311311
{
312+
BlockNumber leftBlkno,
313+
rightBlkno;
312314
Buffer dBuffer;
313-
Buffer lBuffer;
315+
Buffer lBuffer,
316+
rBuffer;
314317
Buffer pBuffer;
315318
Page lPage,
316319
dPage,
320+
rPage,
317321
parentPage;
318-
BlockNumber rightlink;
319322
GenericXLogState *state;
320323

324+
restart:
325+
326+
dBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, deleteBlkno,
327+
RBM_NORMAL, gvs->strategy);
328+
329+
LockBuffer(dBuffer, RUM_EXCLUSIVE);
330+
331+
dPage = BufferGetPage(dBuffer);
332+
leftBlkno = RumPageGetOpaque(dPage)->leftlink;
333+
rightBlkno = RumPageGetOpaque(dPage)->rightlink;
334+
335+
/* do not remove left/right most pages */
336+
if (leftBlkno == InvalidBlockNumber || rightBlkno == InvalidBlockNumber)
337+
{
338+
UnlockReleaseBuffer(dBuffer);
339+
return false;
340+
}
341+
342+
LockBuffer(dBuffer, RUM_UNLOCK);
343+
321344
state = GenericXLogStart(gvs->index);
322345

323346
/*
@@ -326,23 +349,44 @@ rumDeletePage(RumVacuumState * gvs, BlockNumber deleteBlkno, BlockNumber leftBlk
326349
*/
327350
lBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, leftBlkno,
328351
RBM_NORMAL, gvs->strategy);
329-
dBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, deleteBlkno,
352+
rBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, rightBlkno,
330353
RBM_NORMAL, gvs->strategy);
331354
pBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, parentBlkno,
332355
RBM_NORMAL, gvs->strategy);
333356

334357
LockBuffer(lBuffer, RUM_EXCLUSIVE);
335358
LockBuffer(dBuffer, RUM_EXCLUSIVE);
359+
LockBuffer(rBuffer, RUM_EXCLUSIVE);
336360
if (!isParentRoot) /* parent is already locked by
337361
* LockBufferForCleanup() */
338362
LockBuffer(pBuffer, RUM_EXCLUSIVE);
339363

340-
/* Unlink the page by changing left sibling's rightlink */
341364
dPage = GenericXLogRegisterBuffer(state, dBuffer, 0);
342-
rightlink = RumPageGetOpaque(dPage)->rightlink;
343-
344365
lPage = GenericXLogRegisterBuffer(state, lBuffer, 0);
345-
RumPageGetOpaque(lPage)->rightlink = rightlink;
366+
rPage = GenericXLogRegisterBuffer(state, rBuffer, 0);
367+
368+
/*
369+
* last chance to check
370+
*/
371+
if (!(RumPageGetOpaque(lPage)->rightlink == deleteBlkno &&
372+
RumPageGetOpaque(rPage)->leftlink == deleteBlkno &&
373+
RumPageGetOpaque(dPage)->maxoff < FirstOffsetNumber))
374+
{
375+
if (!isParentRoot)
376+
LockBuffer(pBuffer, RUM_UNLOCK);
377+
ReleaseBuffer(pBuffer);
378+
UnlockReleaseBuffer(lBuffer);
379+
UnlockReleaseBuffer(dBuffer);
380+
UnlockReleaseBuffer(rBuffer);
381+
382+
if (RumPageGetOpaque(dPage)->maxoff >= FirstOffsetNumber)
383+
return false;
384+
385+
goto restart;
386+
}
387+
388+
RumPageGetOpaque(lPage)->rightlink = rightBlkno;
389+
RumPageGetOpaque(rPage)->leftlink = leftBlkno;
346390

347391
/* Delete downlink from parent */
348392
parentPage = GenericXLogRegisterBuffer(state, pBuffer, 0);
@@ -357,7 +401,7 @@ rumDeletePage(RumVacuumState * gvs, BlockNumber deleteBlkno, BlockNumber leftBlk
357401
RumPageDeletePostingItem(parentPage, myoff);
358402

359403
/*
360-
* we shouldn't change rightlink field to save workability of running
404+
* we shouldn't change left/right link field to save workability of running
361405
* search scan
362406
*/
363407
RumPageGetOpaque(dPage)->flags = RUM_DELETED;
@@ -369,8 +413,11 @@ rumDeletePage(RumVacuumState * gvs, BlockNumber deleteBlkno, BlockNumber leftBlk
369413
ReleaseBuffer(pBuffer);
370414
UnlockReleaseBuffer(lBuffer);
371415
UnlockReleaseBuffer(dBuffer);
416+
UnlockReleaseBuffer(rBuffer);
372417

373418
gvs->result->pages_deleted++;
419+
420+
return true;
374421
}
375422

376423
typedef struct DataPageDeleteStack
@@ -379,20 +426,20 @@ typedef struct DataPageDeleteStack
379426
struct DataPageDeleteStack *parent;
380427

381428
BlockNumber blkno; /* current block number */
382-
BlockNumber leftBlkno; /* rightest non-deleted page on left */
383429
bool isRoot;
384430
} DataPageDeleteStack;
385431

386432
/*
387433
* scans posting tree and deletes empty pages
388434
*/
389435
static bool
390-
rumScanToDelete(RumVacuumState * gvs, BlockNumber blkno, bool isRoot, DataPageDeleteStack *parent, OffsetNumber myoff)
436+
rumScanToDelete(RumVacuumState * gvs, BlockNumber blkno, bool isRoot,
437+
DataPageDeleteStack *parent, OffsetNumber myoff)
391438
{
392439
DataPageDeleteStack *me;
393440
Buffer buffer;
394441
Page page;
395-
bool meDelete = FALSE;
442+
bool meDelete = false;
396443

397444
if (isRoot)
398445
{
@@ -405,7 +452,6 @@ rumScanToDelete(RumVacuumState * gvs, BlockNumber blkno, bool isRoot, DataPageDe
405452
me = (DataPageDeleteStack *) palloc0(sizeof(DataPageDeleteStack));
406453
me->parent = parent;
407454
parent->child = me;
408-
me->leftBlkno = InvalidBlockNumber;
409455
}
410456
else
411457
me = parent->child;
@@ -431,22 +477,11 @@ rumScanToDelete(RumVacuumState * gvs, BlockNumber blkno, bool isRoot, DataPageDe
431477
}
432478
}
433479

434-
if (RumPageGetOpaque(page)->maxoff < FirstOffsetNumber)
435-
{
436-
/* we never delete the left- or rightmost branch */
437-
if (me->leftBlkno != InvalidBlockNumber && !RumPageRightMost(page))
438-
{
439-
Assert(!isRoot);
440-
rumDeletePage(gvs, blkno, me->leftBlkno, me->parent->blkno, myoff, me->parent->isRoot);
441-
meDelete = TRUE;
442-
}
443-
}
480+
if (RumPageGetOpaque(page)->maxoff < FirstOffsetNumber && !isRoot)
481+
meDelete = rumDeletePage(gvs, blkno, me->parent->blkno, myoff, me->parent->isRoot);
444482

445483
ReleaseBuffer(buffer);
446484

447-
if (!meDelete)
448-
me->leftBlkno = blkno;
449-
450485
return meDelete;
451486
}
452487

@@ -465,7 +500,6 @@ rumVacuumPostingTree(RumVacuumState * gvs, OffsetNumber attnum, BlockNumber root
465500
}
466501

467502
memset(&root, 0, sizeof(DataPageDeleteStack));
468-
root.leftBlkno = InvalidBlockNumber;
469503
root.isRoot = TRUE;
470504

471505
vacuum_delay_point();

0 commit comments

Comments
 (0)