Re: [PATCHES] [HACKERS] Dead code in _bt_split?

2007-02-21 Thread Bruce Momjian

Patch applied.  Thanks.

---


Heikki Linnakangas wrote:
 Tom Lane wrote:
  While testing it I realized that there seems to be a nearby bug in
  _bt_findsplitloc: it fails to consider the possibility of moving all the
  extant items to the left side.  It will always return a firstright =
  maxoff.  ISTM this would mean that it could choose a bad split if the
  incoming item goes at the end and both it and the last extant item are
  large: in this case they should be split apart, but they won't be.
  
  Heikki, do you feel like looking at that, or shall I?
 
 I refactored findsplitloc and checksplitloc so that the division of 
 labor is more clear IMO. I pushed all the space calculation inside the 
 loop to checksplitloc.
 
 I also fixed the off by 4 in free space calculation caused by 
 PageGetFreeSpace subtracting sizeof(ItemIdData), even though it was 
 harmless, because it was distracting and I felt it might come back to 
 bite us in the future if we change the page layout or alignments. 
 There's now a new function PageGetExactFreeSpace that doesn't do the 
 subtraction.
 
 findsplitloc now tries the just the new item to right page split as 
 well. If people don't like the refactoring, I can write a patch to just 
 add that.
 
 Some of the long variable names look ugly. camelCase or underscores 
 between words would be more readable, but I retained the old style for 
 the sake of consistency.
 
 -- 
Heikki Linnakangas
EnterpriseDB   http://www.enterprisedb.com


 
 ---(end of broadcast)---
 TIP 4: Have you searched our list archives?
 
http://archives.postgresql.org

-- 
  Bruce Momjian  [EMAIL PROTECTED]  http://momjian.us
  EnterpriseDB   http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PATCHES] [HACKERS] Dead code in _bt_split?

2007-02-17 Thread Bruce Momjian

Your patch has been added to the PostgreSQL unapplied patches list at:

http://momjian.postgresql.org/cgi-bin/pgpatches

It will be applied as soon as one of the PostgreSQL committers reviews
and approves it.

---


Heikki Linnakangas wrote:
 Tom Lane wrote:
  While testing it I realized that there seems to be a nearby bug in
  _bt_findsplitloc: it fails to consider the possibility of moving all the
  extant items to the left side.  It will always return a firstright =
  maxoff.  ISTM this would mean that it could choose a bad split if the
  incoming item goes at the end and both it and the last extant item are
  large: in this case they should be split apart, but they won't be.
  
  Heikki, do you feel like looking at that, or shall I?
 
 I refactored findsplitloc and checksplitloc so that the division of 
 labor is more clear IMO. I pushed all the space calculation inside the 
 loop to checksplitloc.
 
 I also fixed the off by 4 in free space calculation caused by 
 PageGetFreeSpace subtracting sizeof(ItemIdData), even though it was 
 harmless, because it was distracting and I felt it might come back to 
 bite us in the future if we change the page layout or alignments. 
 There's now a new function PageGetExactFreeSpace that doesn't do the 
 subtraction.
 
 findsplitloc now tries the just the new item to right page split as 
 well. If people don't like the refactoring, I can write a patch to just 
 add that.
 
 Some of the long variable names look ugly. camelCase or underscores 
 between words would be more readable, but I retained the old style for 
 the sake of consistency.
 
 -- 
Heikki Linnakangas
EnterpriseDB   http://www.enterprisedb.com


 
 ---(end of broadcast)---
 TIP 4: Have you searched our list archives?
 
http://archives.postgresql.org

-- 
  Bruce Momjian  [EMAIL PROTECTED]  http://momjian.us
  EnterpriseDB   http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PATCHES] [HACKERS] Dead code in _bt_split?

2007-02-08 Thread Heikki Linnakangas

Tom Lane wrote:

While testing it I realized that there seems to be a nearby bug in
_bt_findsplitloc: it fails to consider the possibility of moving all the
extant items to the left side.  It will always return a firstright =
maxoff.  ISTM this would mean that it could choose a bad split if the
incoming item goes at the end and both it and the last extant item are
large: in this case they should be split apart, but they won't be.

Heikki, do you feel like looking at that, or shall I?


I refactored findsplitloc and checksplitloc so that the division of 
labor is more clear IMO. I pushed all the space calculation inside the 
loop to checksplitloc.


I also fixed the off by 4 in free space calculation caused by 
PageGetFreeSpace subtracting sizeof(ItemIdData), even though it was 
harmless, because it was distracting and I felt it might come back to 
bite us in the future if we change the page layout or alignments. 
There's now a new function PageGetExactFreeSpace that doesn't do the 
subtraction.


findsplitloc now tries the just the new item to right page split as 
well. If people don't like the refactoring, I can write a patch to just 
add that.


Some of the long variable names look ugly. camelCase or underscores 
between words would be more readable, but I retained the old style for 
the sake of consistency.


--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
Index: src/backend/access/nbtree/nbtinsert.c
===
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/nbtree/nbtinsert.c,v
retrieving revision 1.150
diff -c -r1.150 nbtinsert.c
*** src/backend/access/nbtree/nbtinsert.c	8 Feb 2007 05:05:53 -	1.150
--- src/backend/access/nbtree/nbtinsert.c	8 Feb 2007 13:24:50 -
***
*** 29,34 
--- 29,38 
  	int			fillfactor;		/* needed when splitting rightmost page */
  	bool		is_leaf;		/* T if splitting a leaf page */
  	bool		is_rightmost;	/* T if splitting a rightmost page */
+ 	OffsetNumber newitemoff;	/* where the new item is to be inserted */
+ 	int			leftspace;		/* space available for items on left page */
+ 	int			rightspace;		/* space available for items on right page */
+ 	int			olddataitemstotal; /* space taken by old items */
  
  	bool		have_split;		/* found a valid split? */
  
***
*** 57,65 
   OffsetNumber newitemoff,
   Size newitemsz,
   bool *newitemonleft);
! static void _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
!   int leftfree, int rightfree,
!   bool newitemonleft, Size firstrightitemsz);
  static void _bt_pgaddtup(Relation rel, Page page,
  			 Size itemsize, IndexTuple itup,
  			 OffsetNumber itup_off, const char *where);
--- 61,69 
   OffsetNumber newitemoff,
   Size newitemsz,
   bool *newitemonleft);
! static void _bt_checksplitloc(FindSplitData *state, 
!   OffsetNumber firstoldonright, bool newitemonleft,
!   int dataitemstoleft, Size firstoldonrightsz);
  static void _bt_pgaddtup(Relation rel, Page page,
  			 Size itemsize, IndexTuple itup,
  			 OffsetNumber itup_off, const char *where);
***
*** 1101,1113 
  	int			leftspace,
  rightspace,
  goodenough,
! dataitemtotal,
! dataitemstoleft;
  
  	opaque = (BTPageOpaque) PageGetSpecialPointer(page);
  
  	/* Passed-in newitemsz is MAXALIGNED but does not include line pointer */
  	newitemsz += sizeof(ItemIdData);
  	state.newitemsz = newitemsz;
  	state.is_leaf = P_ISLEAF(opaque);
  	state.is_rightmost = P_RIGHTMOST(opaque);
--- 1105,1135 
  	int			leftspace,
  rightspace,
  goodenough,
! olddataitemstotal,
! olddataitemstoleft;
! 	bool		goodenoughfound;
  
  	opaque = (BTPageOpaque) PageGetSpecialPointer(page);
  
  	/* Passed-in newitemsz is MAXALIGNED but does not include line pointer */
  	newitemsz += sizeof(ItemIdData);
+ 
+ 	/* Total free space available on a btree page, after fixed overhead */
+ 	leftspace = rightspace =
+ 		PageGetPageSize(page) - SizeOfPageHeaderData -
+ 		MAXALIGN(sizeof(BTPageOpaqueData));
+ 
+ 	/* The right page will have the same high key as the old page */
+ 	if (!P_RIGHTMOST(opaque))
+ 	{
+ 		itemid = PageGetItemId(page, P_HIKEY);
+ 		rightspace -= (int) (MAXALIGN(ItemIdGetLength(itemid)) +
+ 			 sizeof(ItemIdData));
+ 	}
+ 
+ 	/* Count up total space in data items without actually scanning 'em */
+ 	olddataitemstotal = rightspace - (int) PageGetExactFreeSpace(page);
+ 
  	state.newitemsz = newitemsz;
  	state.is_leaf = P_ISLEAF(opaque);
  	state.is_rightmost = P_RIGHTMOST(opaque);
***
*** 1120,1130 
  	state.newitemonleft = false;	/* these just to keep compiler quiet */
  	state.firstright = 0;
  	state.best_delta = 0;
! 
! 	/* Total free space available on a btree page, after fixed overhead */
! 	leftspace = rightspace =
! 		PageGetPageSize(page) - SizeOfPageHeaderData -
! 		MAXALIGN(sizeof(BTPageOpaqueData));
  
  	/*
  	 *