8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.85 2001/08/23 23:06:37 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.86 2001/09/29 23:49:51 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -24,7 +24,8 @@ typedef struct
24
24
{
25
25
/* context data for _bt_checksplitloc */
26
26
Size newitemsz ; /* size of new item to be inserted */
27
- bool non_leaf ; /* T if splitting an internal node */
27
+ bool is_leaf ; /* T if splitting a leaf page */
28
+ bool is_rightmost ; /* T if splitting a rightmost page */
28
29
29
30
bool have_split ; /* found a valid split? */
30
31
@@ -940,6 +941,16 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
940
941
* for it, we might find ourselves with too little room on the page that
941
942
* it needs to go into!)
942
943
*
944
+ * If the page is the rightmost page on its level, we instead try to arrange
945
+ * for twice as much free space on the right as on the left. In this way,
946
+ * when we are inserting successively increasing keys (consider sequences,
947
+ * timestamps, etc) we will end up with a tree whose pages are about 67% full,
948
+ * instead of the 50% full result that we'd get without this special case.
949
+ * (We could bias it even further to make the initially-loaded tree more full.
950
+ * But since the steady-state load for a btree is about 70%, we'd likely just
951
+ * be making more page-splitting work for ourselves later on, when we start
952
+ * seeing updates to existing tuples.)
953
+ *
943
954
* We are passed the intended insert position of the new tuple, expressed as
944
955
* the offsetnumber of the tuple it must go in front of. (This could be
945
956
* maxoff+1 if the tuple is to go at the end.)
@@ -972,7 +983,8 @@ _bt_findsplitloc(Relation rel,
972
983
/* Passed-in newitemsz is MAXALIGNED but does not include line pointer */
973
984
newitemsz += sizeof (ItemIdData );
974
985
state .newitemsz = newitemsz ;
975
- state .non_leaf = !P_ISLEAF (opaque );
986
+ state .is_leaf = P_ISLEAF (opaque );
987
+ state .is_rightmost = P_RIGHTMOST (opaque );
976
988
state .have_split = false;
977
989
978
990
/* Total free space available on a btree page, after fixed overhead */
@@ -1076,7 +1088,6 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
1076
1088
int leftfree , int rightfree ,
1077
1089
bool newitemonleft , Size firstrightitemsz )
1078
1090
{
1079
-
1080
1091
/*
1081
1092
* Account for the new item on whichever side it is to be put.
1082
1093
*/
@@ -1089,7 +1100,7 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
1089
1100
* If we are not on the leaf level, we will be able to discard the key
1090
1101
* data from the first item that winds up on the right page.
1091
1102
*/
1092
- if (state -> non_leaf )
1103
+ if (! state -> is_leaf )
1093
1104
rightfree += (int ) firstrightitemsz -
1094
1105
(int ) (MAXALIGN (sizeof (BTItemData )) + sizeof (ItemIdData ));
1095
1106
@@ -1098,7 +1109,21 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
1098
1109
*/
1099
1110
if (leftfree >= 0 && rightfree >= 0 )
1100
1111
{
1101
- int delta = leftfree - rightfree ;
1112
+ int delta ;
1113
+
1114
+ if (state -> is_rightmost )
1115
+ {
1116
+ /*
1117
+ * On a rightmost page, try to equalize right free space with
1118
+ * twice the left free space. See comments for _bt_findsplitloc.
1119
+ */
1120
+ delta = (2 * leftfree ) - rightfree ;
1121
+ }
1122
+ else
1123
+ {
1124
+ /* Otherwise, aim for equal free space on both sides */
1125
+ delta = leftfree - rightfree ;
1126
+ }
1102
1127
1103
1128
if (delta < 0 )
1104
1129
delta = - delta ;
0 commit comments