64 int olddataitemstoleft,
65 Size firstrightofforigpagetuplesz);
68 static int _bt_splitcmp(
const void *arg1,
const void *arg2);
70 int leaffillfactor,
bool *usemult);
149 double fillfactormult;
158 leftspace = rightspace =
177 state.origpage = origpage;
178 state.newitem = newitem;
179 state.newitemsz = newitemsz;
182 state.leftspace = leftspace;
183 state.rightspace = rightspace;
184 state.olddataitemstotal = olddataitemstotal;
185 state.minfirstrightsz = SIZE_MAX;
186 state.newitemoff = newitemoff;
198 state.maxsplits = maxoff;
206 olddataitemstoleft = 0;
224 if (offnum < newitemoff)
226 else if (offnum > newitemoff)
243 olddataitemstoleft += itemsz;
251 Assert(olddataitemstoleft == olddataitemstotal);
252 if (newitemoff > maxoff)
259 if (
state.nsplits == 0)
260 elog(
ERROR,
"could not find a feasible split point for index \"%s\"",
283 usemult =
state.is_rightmost;
286 else if (
state.is_rightmost)
290 fillfactormult = leaffillfactor / 100.0;
303 fillfactormult = leaffillfactor / 100.0;
308 for (
int i = 0;
i <
state.nsplits;
i++)
316 *newitemonleft =
true;
326 fillfactormult = 0.50;
334 fillfactormult = 0.50;
341 leftpage =
state.splits[0];
427 return firstrightoff;
452 int olddataitemstoleft,
453 Size firstrightofforigpagetuplesz)
459 bool newitemisfirstright;
462 newitemisfirstright = (firstrightoff ==
state->newitemoff &&
465 if (newitemisfirstright)
466 firstrightsz =
state->newitemsz;
469 firstrightsz = firstrightofforigpagetuplesz;
481 if (
state->is_leaf && firstrightsz > 64)
496 leftfree =
state->leftspace - olddataitemstoleft;
497 rightfree =
state->rightspace -
498 (
state->olddataitemstotal - olddataitemstoleft);
524 leftfree -= (
int16) (firstrightsz +
528 leftfree -= (
int16) firstrightsz;
541 rightfree += (
int16) firstrightsz -
545 if (leftfree >= 0 && rightfree >= 0)
550 state->minfirstrightsz =
Min(
state->minfirstrightsz, firstrightsz);
553 state->splits[
state->nsplits].leftfree = leftfree;
554 state->splits[
state->nsplits].rightfree = rightfree;
555 state->splits[
state->nsplits].firstrightoff = firstrightoff;
556 state->splits[
state->nsplits].newitemonleft = newitemonleft;
569 for (
int i = 0;
i <
state->nsplits;
i++)
575 delta = fillfactormult * split->
leftfree -
576 (1.0 - fillfactormult) * split->
rightfree;
631 int leaffillfactor,
bool *usemult)
662 if (
state->newitemsz !=
state->minfirstrightsz)
664 if (
state->newitemsz * (maxoff - 1) !=
state->olddataitemstotal)
672 if (
state->newitemsz >
686 if (
state->newitemoff > maxoff)
692 if (keepnatts > 1 && keepnatts <= nkeyatts)
723 if (keepnatts > 1 && keepnatts <= nkeyatts)
725 double interp = (double)
state->newitemoff / ((
double) maxoff + 1);
726 double leaffillfactormult = (double) leaffillfactor / 100.0;
733 *usemult = interp > leaffillfactormult;
758 if (lowblk == highblk)
762 if (lowblk + 1 == highblk &&
796 bestpenalty = INT_MAX;
798 for (
int i = lowsplit;
i < highsplit;
i++)
804 if (penalty < bestpenalty)
806 bestpenalty = penalty;
810 if (penalty <= perfectpenalty)
814 final = &
state->splits[lowsplit];
842 final = &
state->splits[0];
845 *newitemonleft =
final->newitemonleft;
846 return final->firstrightoff;
849 #define LEAF_SPLIT_DISTANCE 0.050
850 #define INTERNAL_SPLIT_DISTANCE 0.075
898 spaceoptimal =
state->splits;
899 lowleftfree = spaceoptimal->
leftfree - tolerance;
900 lowrightfree = spaceoptimal->
rightfree - tolerance;
901 highleftfree = spaceoptimal->
leftfree + tolerance;
902 highrightfree = spaceoptimal->
rightfree + tolerance;
909 for (
int i = 1;
i <
state->nsplits;
i++)
919 return state->nsplits;
955 return state->minfirstrightsz;
971 if (perfectpenalty <= indnkeyatts)
972 return perfectpenalty;
992 if (perfectpenalty <= indnkeyatts)
1020 else if (
state->is_rightmost)
1031 if (perfectpenalty <= indnkeyatts)
1043 return perfectpenalty;
1058 deltaoptimal =
state->splits;
1059 *leftinterval = NULL;
1060 *rightinterval = NULL;
1067 for (
int i = highsplit - 1;
i >= 0;
i--)
1073 if (*leftinterval == NULL)
1074 *leftinterval = distant;
1078 if (*rightinterval == NULL)
1079 *rightinterval = distant;
1088 if (*leftinterval == NULL)
1089 *leftinterval = distant;
1098 if (*rightinterval == NULL)
1099 *rightinterval = distant;
1104 Assert(distant == deltaoptimal);
1105 if (*leftinterval == NULL)
1106 *leftinterval = distant;
1107 if (*rightinterval == NULL)
1108 *rightinterval = distant;
1111 if (*leftinterval && *rightinterval)
1136 if (!
state->is_leaf)
1142 return state->newitemsz;
1164 return state->newitem;
1180 return state->newitem;
Size PageGetExactFreeSpace(Page page)
static Item PageGetItem(Page page, ItemId itemId)
static Size PageGetPageSize(Page page)
#define SizeOfPageHeaderData
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define Assert(condition)
static int pg_cmp_s16(int16 a, int16 b)
if(TABLE==NULL||TABLE_index==NULL)
#define ItemIdGetLength(itemId)
struct ItemIdData ItemIdData
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
void pfree(void *pointer)
#define BTREE_SINGLEVAL_FILLFACTOR
#define BTPageGetOpaque(page)
#define P_FIRSTDATAKEY(opaque)
static uint32 BTreeTupleGetPostingOffset(IndexTuple posting)
#define P_RIGHTMOST(opaque)
static bool BTreeTupleIsPosting(IndexTuple itup)
#define BTGetFillFactor(relation)
#define BTREE_NONLEAF_FILLFACTOR
OffsetNumber _bt_findsplitloc(Relation rel, Page origpage, OffsetNumber newitemoff, Size newitemsz, IndexTuple newitem, bool *newitemonleft)
#define LEAF_SPLIT_DISTANCE
static int _bt_split_penalty(FindSplitData *state, SplitPoint *split)
#define INTERNAL_SPLIT_DISTANCE
static void _bt_deltasortsplits(FindSplitData *state, double fillfactormult, bool usemult)
static int _bt_strategy(FindSplitData *state, SplitPoint *leftpage, SplitPoint *rightpage, FindSplitStrat *strategy)
static bool _bt_afternewitemoff(FindSplitData *state, OffsetNumber maxoff, int leaffillfactor, bool *usemult)
static int _bt_splitcmp(const void *arg1, const void *arg2)
static IndexTuple _bt_split_lastleft(FindSplitData *state, SplitPoint *split)
static void _bt_recsplitloc(FindSplitData *state, OffsetNumber firstrightoff, bool newitemonleft, int olddataitemstoleft, Size firstrightofforigpagetuplesz)
static OffsetNumber _bt_bestsplitloc(FindSplitData *state, int perfectpenalty, bool *newitemonleft, FindSplitStrat strategy)
static int _bt_defaultinterval(FindSplitData *state)
static void _bt_interval_edges(FindSplitData *state, SplitPoint **leftinterval, SplitPoint **rightinterval)
static IndexTuple _bt_split_firstright(FindSplitData *state, SplitPoint *split)
static bool _bt_adjacenthtid(ItemPointer lowhtid, ItemPointer highhtid)
int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
#define OffsetNumberPrev(offsetNumber)
#define qsort(a, b, c, d)
#define RelationGetRelationName(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
OffsetNumber firstrightoff