Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit04eee1f

Browse files
committed
More GIN refactoring.
Split off the portion of ginInsertValue that inserts the tuple to currentlevel into a separate function, ginPlaceToPage. ginInsertValue's charteris now to recurse up the tree to insert the downlink, when a page split isrequired.This is in preparation for a patch to change the way incomplete splits arehandled, which will need to do these operations separately. And IMHO makesthe code more readable anyway.
1 parent5010126 commit04eee1f

File tree

1 file changed

+148
-128
lines changed

1 file changed

+148
-128
lines changed

‎src/backend/access/gin/ginbtree.c

Lines changed: 148 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -280,80 +280,115 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack,
280280
}
281281

282282
/*
283-
* Insert value (stored in GinBtree) to tree described by stack
284-
*
285-
* During an index build, buildStats is non-null and the counters
286-
* it contains are incremented as needed.
283+
* Returns true if the insertion is done, false if the page was split and
284+
* downlink insertion is pending.
287285
*
288-
*NB: the passed-in stackisfreed, as though by freeGinBtreeStack.
286+
*stack->bufferislocked on entry, and is kept locked.
289287
*/
290-
void
291-
ginInsertValue(GinBtreebtree,GinBtreeStack*stack,GinStatsData*buildStats)
288+
staticbool
289+
ginPlaceToPage(GinBtreebtree,BlockNumberrootBlkno,GinBtreeStack*stack,
290+
GinStatsData*buildStats)
292291
{
293-
GinBtreeStack*parent;
294-
BlockNumberrootBlkno;
295-
Pagepage,
296-
rpage,
297-
lpage;
292+
Pagepage=BufferGetPage(stack->buffer);
293+
XLogRecData*rdata;
294+
boolfit;
298295

299-
/* extract root BlockNumber from stack */
300-
Assert(stack!=NULL);
301-
parent=stack;
302-
while (parent->parent)
303-
parent=parent->parent;
304-
rootBlkno=parent->blkno;
305-
Assert(BlockNumberIsValid(rootBlkno));
296+
START_CRIT_SECTION();
297+
fit=btree->placeToPage(btree,stack->buffer,stack->off,&rdata);
298+
if (fit)
299+
{
300+
MarkBufferDirty(stack->buffer);
306301

307-
/* this loop crawls up the stack until the insertion is complete */
308-
for (;;)
302+
if (RelationNeedsWAL(btree->index))
303+
{
304+
XLogRecPtrrecptr;
305+
306+
recptr=XLogInsert(RM_GIN_ID,XLOG_GIN_INSERT,rdata);
307+
PageSetLSN(page,recptr);
308+
}
309+
310+
END_CRIT_SECTION();
311+
312+
return true;
313+
}
314+
else
309315
{
310-
XLogRecData*rdata;
316+
/* Didn't fit, have to split */
317+
Bufferrbuffer;
318+
Pagenewlpage;
311319
BlockNumbersavedRightLink;
312-
boolfit;
320+
GinBtreeStack*parent;
321+
Pagelpage,
322+
rpage;
323+
324+
END_CRIT_SECTION();
325+
326+
rbuffer=GinNewBuffer(btree->index);
313327

314-
page=BufferGetPage(stack->buffer);
315328
savedRightLink=GinPageGetOpaque(page)->rightlink;
316329

317-
START_CRIT_SECTION();
318-
fit=btree->placeToPage(btree,stack->buffer,stack->off,&rdata);
319-
if (fit)
330+
/*
331+
* newlpage is a pointer to memory page, it is not associated with
332+
* a buffer. stack->buffer is not touched yet.
333+
*/
334+
newlpage=btree->splitPage(btree,stack->buffer,rbuffer,stack->off,&rdata);
335+
336+
((ginxlogSplit*) (rdata->data))->rootBlkno=rootBlkno;
337+
338+
/* During index build, count the newly-split page */
339+
if (buildStats)
320340
{
341+
if (btree->isData)
342+
buildStats->nDataPages++;
343+
else
344+
buildStats->nEntryPages++;
345+
}
346+
347+
parent=stack->parent;
348+
349+
if (parent==NULL)
350+
{
351+
/*
352+
* split root, so we need to allocate new left page and place
353+
* pointer on root to left and right page
354+
*/
355+
Bufferlbuffer=GinNewBuffer(btree->index);
356+
357+
((ginxlogSplit*) (rdata->data))->isRootSplit= TRUE;
358+
((ginxlogSplit*) (rdata->data))->rrlink=InvalidBlockNumber;
359+
360+
lpage=BufferGetPage(lbuffer);
361+
rpage=BufferGetPage(rbuffer);
362+
363+
GinPageGetOpaque(rpage)->rightlink=InvalidBlockNumber;
364+
GinPageGetOpaque(newlpage)->rightlink=BufferGetBlockNumber(rbuffer);
365+
((ginxlogSplit*) (rdata->data))->lblkno=BufferGetBlockNumber(lbuffer);
366+
367+
START_CRIT_SECTION();
368+
369+
GinInitBuffer(stack->buffer,GinPageGetOpaque(newlpage)->flags& ~GIN_LEAF);
370+
PageRestoreTempPage(newlpage,lpage);
371+
btree->fillRoot(btree,stack->buffer,lbuffer,rbuffer);
372+
373+
MarkBufferDirty(rbuffer);
374+
MarkBufferDirty(lbuffer);
321375
MarkBufferDirty(stack->buffer);
322376

323377
if (RelationNeedsWAL(btree->index))
324378
{
325379
XLogRecPtrrecptr;
326380

327-
recptr=XLogInsert(RM_GIN_ID,XLOG_GIN_INSERT,rdata);
381+
recptr=XLogInsert(RM_GIN_ID,XLOG_GIN_SPLIT,rdata);
328382
PageSetLSN(page,recptr);
383+
PageSetLSN(lpage,recptr);
384+
PageSetLSN(rpage,recptr);
329385
}
330386

331-
LockBuffer(stack->buffer,GIN_UNLOCK);
332-
END_CRIT_SECTION();
333-
334-
freeGinBtreeStack(stack);
335-
336-
return;
337-
}
338-
else
339-
{
340-
/* Didn't fit, have to split */
341-
Bufferrbuffer;
342-
Pagenewlpage;
343-
387+
UnlockReleaseBuffer(rbuffer);
388+
UnlockReleaseBuffer(lbuffer);
344389
END_CRIT_SECTION();
345390

346-
rbuffer=GinNewBuffer(btree->index);
347-
348-
/*
349-
* newlpage is a pointer to memory page, it is not associated with
350-
* a buffer. stack->buffer is not touched yet.
351-
*/
352-
newlpage=btree->splitPage(btree,stack->buffer,rbuffer,stack->off,&rdata);
353-
354-
((ginxlogSplit*) (rdata->data))->rootBlkno=rootBlkno;
355-
356-
/* During index build, count the newly-split page */
391+
/* During index build, count the newly-added root page */
357392
if (buildStats)
358393
{
359394
if (btree->isData)
@@ -362,98 +397,83 @@ ginInsertValue(GinBtree btree, GinBtreeStack *stack, GinStatsData *buildStats)
362397
buildStats->nEntryPages++;
363398
}
364399

365-
parent=stack->parent;
366-
367-
if (parent==NULL)
368-
{
369-
/*
370-
* split root, so we need to allocate new left page and place
371-
* pointer on root to left and right page
372-
*/
373-
Bufferlbuffer=GinNewBuffer(btree->index);
374-
375-
((ginxlogSplit*) (rdata->data))->isRootSplit= TRUE;
376-
((ginxlogSplit*) (rdata->data))->rrlink=InvalidBlockNumber;
377-
378-
page=BufferGetPage(stack->buffer);
379-
lpage=BufferGetPage(lbuffer);
380-
rpage=BufferGetPage(rbuffer);
381-
382-
GinPageGetOpaque(rpage)->rightlink=InvalidBlockNumber;
383-
GinPageGetOpaque(newlpage)->rightlink=BufferGetBlockNumber(rbuffer);
384-
((ginxlogSplit*) (rdata->data))->lblkno=BufferGetBlockNumber(lbuffer);
385-
386-
START_CRIT_SECTION();
387-
388-
GinInitBuffer(stack->buffer,GinPageGetOpaque(newlpage)->flags& ~GIN_LEAF);
389-
PageRestoreTempPage(newlpage,lpage);
390-
btree->fillRoot(btree,stack->buffer,lbuffer,rbuffer);
391-
392-
MarkBufferDirty(rbuffer);
393-
MarkBufferDirty(lbuffer);
394-
MarkBufferDirty(stack->buffer);
400+
return true;
401+
}
402+
else
403+
{
404+
/* split non-root page */
405+
((ginxlogSplit*) (rdata->data))->isRootSplit= FALSE;
406+
((ginxlogSplit*) (rdata->data))->rrlink=savedRightLink;
395407

396-
if (RelationNeedsWAL(btree->index))
397-
{
398-
XLogRecPtrrecptr;
408+
lpage=BufferGetPage(stack->buffer);
409+
rpage=BufferGetPage(rbuffer);
399410

400-
recptr=XLogInsert(RM_GIN_ID,XLOG_GIN_SPLIT,rdata);
401-
PageSetLSN(page,recptr);
402-
PageSetLSN(lpage,recptr);
403-
PageSetLSN(rpage,recptr);
404-
}
411+
GinPageGetOpaque(rpage)->rightlink=savedRightLink;
412+
GinPageGetOpaque(newlpage)->rightlink=BufferGetBlockNumber(rbuffer);
405413

406-
UnlockReleaseBuffer(rbuffer);
407-
UnlockReleaseBuffer(lbuffer);
408-
LockBuffer(stack->buffer,GIN_UNLOCK);
409-
END_CRIT_SECTION();
414+
START_CRIT_SECTION();
415+
PageRestoreTempPage(newlpage,lpage);
410416

411-
freeGinBtreeStack(stack);
417+
MarkBufferDirty(rbuffer);
418+
MarkBufferDirty(stack->buffer);
412419

413-
/* During index build, count the newly-added root page */
414-
if (buildStats)
415-
{
416-
if (btree->isData)
417-
buildStats->nDataPages++;
418-
else
419-
buildStats->nEntryPages++;
420-
}
420+
if (RelationNeedsWAL(btree->index))
421+
{
422+
XLogRecPtrrecptr;
421423

422-
return;
424+
recptr=XLogInsert(RM_GIN_ID,XLOG_GIN_SPLIT,rdata);
425+
PageSetLSN(lpage,recptr);
426+
PageSetLSN(rpage,recptr);
423427
}
424-
else
425-
{
426-
/* split non-root page */
427-
((ginxlogSplit*) (rdata->data))->isRootSplit= FALSE;
428-
((ginxlogSplit*) (rdata->data))->rrlink=savedRightLink;
428+
UnlockReleaseBuffer(rbuffer);
429+
END_CRIT_SECTION();
429430

430-
lpage=BufferGetPage(stack->buffer);
431-
rpage=BufferGetPage(rbuffer);
431+
return false;
432+
}
433+
}
434+
}
432435

433-
GinPageGetOpaque(rpage)->rightlink=savedRightLink;
434-
GinPageGetOpaque(newlpage)->rightlink=BufferGetBlockNumber(rbuffer);
436+
/*
437+
* Insert value (stored in GinBtree) to tree described by stack
438+
*
439+
* During an index build, buildStats is non-null and the counters
440+
* it contains are incremented as needed.
441+
*
442+
* NB: the passed-in stack is freed, as though by freeGinBtreeStack.
443+
*/
444+
void
445+
ginInsertValue(GinBtreebtree,GinBtreeStack*stack,GinStatsData*buildStats)
446+
{
447+
GinBtreeStack*parent;
448+
BlockNumberrootBlkno;
449+
Pagepage;
450+
451+
/* extract root BlockNumber from stack */
452+
Assert(stack!=NULL);
453+
parent=stack;
454+
while (parent->parent)
455+
parent=parent->parent;
456+
rootBlkno=parent->blkno;
457+
Assert(BlockNumberIsValid(rootBlkno));
435458

436-
START_CRIT_SECTION();
437-
PageRestoreTempPage(newlpage,lpage);
459+
/* this loop crawls up the stack until the insertion is complete */
460+
for (;;)
461+
{
462+
booldone;
438463

439-
MarkBufferDirty(rbuffer);
440-
MarkBufferDirty(stack->buffer);
464+
done=ginPlaceToPage(btree,rootBlkno,stack,buildStats);
441465

442-
if (RelationNeedsWAL(btree->index))
443-
{
444-
XLogRecPtrrecptr;
466+
/* just to be extra sure we don't delete anything by accident... */
467+
btree->isDelete= FALSE;
445468

446-
recptr=XLogInsert(RM_GIN_ID,XLOG_GIN_SPLIT,rdata);
447-
PageSetLSN(lpage,recptr);
448-
PageSetLSN(rpage,recptr);
449-
}
450-
UnlockReleaseBuffer(rbuffer);
451-
END_CRIT_SECTION();
452-
}
469+
if (done)
470+
{
471+
LockBuffer(stack->buffer,GIN_UNLOCK);
472+
freeGinBtreeStack(stack);
473+
break;
453474
}
454475

455476
btree->prepareDownlink(btree,stack->buffer);
456-
btree->isDelete= FALSE;
457477

458478
/* search parent to lock */
459479
LockBuffer(parent->buffer,GIN_EXCLUSIVE);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp