gist_childoffnum.path

application/octet-stream

Filename: gist_childoffnum.path
Type: application/octet-stream
Part: 0
Message: Small patch for GiST: move childoffnum to child
*** a/src/backend/access/gist/gist.c
--- b/src/backend/access/gist/gist.c
***************
*** 625,630 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
--- 625,631 ----
  	firststack.blkno = GIST_ROOT_BLKNO;
  	firststack.lsn.xrecoff = 0;
  	firststack.parent = NULL;
+ 	firststack.childoffnum = InvalidOffsetNumber;
  	state.stack = stack = &firststack;
  
  	/*
***************
*** 701,709 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
  			BlockNumber childblkno;
  			IndexTuple	newtup;
  			GISTInsertStack *item;
  
! 			stack->childoffnum = gistchoose(state.r, stack->page, itup, giststate);
! 			iid = PageGetItemId(stack->page, stack->childoffnum);
  			idxtuple = (IndexTuple) PageGetItem(stack->page, iid);
  			childblkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid));
  
--- 702,711 ----
  			BlockNumber childblkno;
  			IndexTuple	newtup;
  			GISTInsertStack *item;
+ 			OffsetNumber childoffnum;
  
! 			childoffnum = gistchoose(state.r, stack->page, itup, giststate);
! 			iid = PageGetItemId(stack->page, childoffnum);
  			idxtuple = (IndexTuple) PageGetItem(stack->page, iid);
  			childblkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid));
  
***************
*** 753,759 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
  				 * tuple.
  				 */
  				if (gistinserttuples(&state, stack, giststate, &newtup, 1,
! 									 stack->childoffnum, InvalidBuffer))
  				{
  					/*
  					 * If this was a root split, the root page continues to be
--- 755,761 ----
  				 * tuple.
  				 */
  				if (gistinserttuples(&state, stack, giststate, &newtup, 1,
! 									 childoffnum, InvalidBuffer))
  				{
  					/*
  					 * If this was a root split, the root page continues to be
***************
*** 777,782 **** gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
--- 779,785 ----
  			item = (GISTInsertStack *) palloc0(sizeof(GISTInsertStack));
  			item->blkno = childblkno;
  			item->parent = stack;
+ 			item->childoffnum = childoffnum;
  			state.stack = stack = item;
  		}
  		else
***************
*** 873,878 **** gistFindPath(Relation r, BlockNumber child)
--- 876,882 ----
  
  	top = tail = (GISTInsertStack *) palloc0(sizeof(GISTInsertStack));
  	top->blkno = GIST_ROOT_BLKNO;
+ 	top->childoffnum = InvalidOffsetNumber;
  
  	while (top && top->blkno != child)
  	{
***************
*** 919,947 **** gistFindPath(Relation r, BlockNumber child)
  			blkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid));
  			if (blkno == child)
  			{
- 				OffsetNumber poff = InvalidOffsetNumber;
- 
- 				/* make childs links */
- 				ptr = top;
- 				while (ptr->parent)
- 				{
- 					/* move childoffnum.. */
- 					if (ptr == top)
- 					{
- 						/* first iteration */
- 						poff = ptr->parent->childoffnum;
- 						ptr->parent->childoffnum = ptr->childoffnum;
- 					}
- 					else
- 					{
- 						OffsetNumber tmp = ptr->parent->childoffnum;
- 
- 						ptr->parent->childoffnum = poff;
- 						poff = tmp;
- 					}
- 					ptr = ptr->parent;
- 				}
- 				top->childoffnum = i;
  				UnlockReleaseBuffer(buffer);
  				return top;
  			}
--- 923,928 ----
***************
*** 980,986 **** gistFindCorrectParent(Relation r, GISTInsertStack *child)
  	parent->page = (Page) BufferGetPage(parent->buffer);
  
  	/* here we don't need to distinguish between split and page update */
! 	if (parent->childoffnum == InvalidOffsetNumber || !XLByteEQ(parent->lsn, PageGetLSN(parent->page)))
  	{
  		/* parent is changed, look child in right links until found */
  		OffsetNumber i,
--- 961,967 ----
  	parent->page = (Page) BufferGetPage(parent->buffer);
  
  	/* here we don't need to distinguish between split and page update */
! 	if (child->childoffnum == InvalidOffsetNumber || !XLByteEQ(parent->lsn, PageGetLSN(parent->page)))
  	{
  		/* parent is changed, look child in right links until found */
  		OffsetNumber i,
***************
*** 999,1005 **** gistFindCorrectParent(Relation r, GISTInsertStack *child)
  				if (ItemPointerGetBlockNumber(&(idxtuple->t_tid)) == child->blkno)
  				{
  					/* yes!!, found */
! 					parent->childoffnum = i;
  					return;
  				}
  			}
--- 980,986 ----
  				if (ItemPointerGetBlockNumber(&(idxtuple->t_tid)) == child->blkno)
  				{
  					/* yes!!, found */
! 					child->childoffnum = i;
  					return;
  				}
  			}
***************
*** 1103,1109 **** gistformdownlink(Relation rel, Buffer buf, GISTSTATE *giststate,
  
  		LockBuffer(stack->parent->buffer, GIST_EXCLUSIVE);
  		gistFindCorrectParent(rel, stack);
! 		iid = PageGetItemId(stack->parent->page, stack->parent->childoffnum);
  		downlink = (IndexTuple) PageGetItem(stack->parent->page, iid);
  		downlink = CopyIndexTuple(downlink);
  		LockBuffer(stack->parent->buffer, GIST_UNLOCK);
--- 1084,1090 ----
  
  		LockBuffer(stack->parent->buffer, GIST_EXCLUSIVE);
  		gistFindCorrectParent(rel, stack);
! 		iid = PageGetItemId(stack->parent->page, stack->childoffnum);
  		downlink = (IndexTuple) PageGetItem(stack->parent->page, iid);
  		downlink = CopyIndexTuple(downlink);
  		LockBuffer(stack->parent->buffer, GIST_UNLOCK);
***************
*** 1131,1137 **** gistfixsplit(GISTInsertState *state, GISTSTATE *giststate)
  		 RelationGetRelationName(state->r), stack->blkno);
  
  	Assert(GistFollowRight(stack->page));
! 	Assert(OffsetNumberIsValid(stack->parent->childoffnum));
  
  	buf = stack->buffer;
  
--- 1112,1118 ----
  		 RelationGetRelationName(state->r), stack->blkno);
  
  	Assert(GistFollowRight(stack->page));
! 	Assert(OffsetNumberIsValid(stack->childoffnum));
  
  	buf = stack->buffer;
  
***************
*** 1268,1274 **** gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack,
  	tuples[1] = right->downlink;
  	gistinserttuples(state, stack->parent, giststate,
  					 tuples, 2,
! 					 stack->parent->childoffnum,
  					 left->buf);
  	LockBuffer(stack->parent->buffer, GIST_UNLOCK);
  	UnlockReleaseBuffer(right->buf);
--- 1249,1255 ----
  	tuples[1] = right->downlink;
  	gistinserttuples(state, stack->parent, giststate,
  					 tuples, 2,
! 					 stack->childoffnum,
  					 left->buf);
  	LockBuffer(stack->parent->buffer, GIST_UNLOCK);
  	UnlockReleaseBuffer(right->buf);