65 int olddataitemstoleft,
66 Size firstrightofforigpagetuplesz);
69static int _bt_splitcmp(
const void *arg1,
const void *arg2);
71 int leaffillfactor,
bool *usemult);
150 double fillfactormult;
159 leftspace = rightspace =
178 state.origpage = origpage;
179 state.newitem = newitem;
180 state.newitemsz = newitemsz;
183 state.leftspace = leftspace;
184 state.rightspace = rightspace;
185 state.olddataitemstotal = olddataitemstotal;
186 state.minfirstrightsz = SIZE_MAX;
187 state.newitemoff = newitemoff;
199 state.maxsplits = maxoff;
207 olddataitemstoleft = 0;
225 if (offnum < newitemoff)
227 else if (offnum > newitemoff)
244 olddataitemstoleft += itemsz;
252 Assert(olddataitemstoleft == olddataitemstotal);
253 if (newitemoff > maxoff)
260 if (
state.nsplits == 0)
261 elog(
ERROR,
"could not find a feasible split point for index \"%s\"",
284 usemult =
state.is_rightmost;
287 else if (
state.is_rightmost)
291 fillfactormult = leaffillfactor / 100.0;
304 fillfactormult = leaffillfactor / 100.0;
309 for (
int i = 0;
i <
state.nsplits;
i++)
317 *newitemonleft =
true;
327 fillfactormult = 0.50;
335 fillfactormult = 0.50;
342 leftpage =
state.splits[0];
428 return firstrightoff;
453 int olddataitemstoleft,
454 Size firstrightofforigpagetuplesz)
460 bool newitemisfirstright;
463 newitemisfirstright = (firstrightoff ==
state->newitemoff &&
466 if (newitemisfirstright)
467 firstrightsz =
state->newitemsz;
470 firstrightsz = firstrightofforigpagetuplesz;
482 if (
state->is_leaf && firstrightsz > 64)
497 leftfree =
state->leftspace - olddataitemstoleft;
498 rightfree =
state->rightspace -
499 (
state->olddataitemstotal - olddataitemstoleft);
525 leftfree -= (
int16) (firstrightsz +
529 leftfree -= (
int16) firstrightsz;
542 rightfree += (
int16) firstrightsz -
546 if (leftfree >= 0 && rightfree >= 0)
551 state->minfirstrightsz =
Min(
state->minfirstrightsz, firstrightsz);
554 state->splits[
state->nsplits].leftfree = leftfree;
555 state->splits[
state->nsplits].rightfree = rightfree;
556 state->splits[
state->nsplits].firstrightoff = firstrightoff;
557 state->splits[
state->nsplits].newitemonleft = newitemonleft;
570 for (
int i = 0;
i <
state->nsplits;
i++)
576 delta = fillfactormult * split->
leftfree -
577 (1.0 - fillfactormult) * split->
rightfree;
632 int leaffillfactor,
bool *usemult)
663 if (
state->newitemsz !=
state->minfirstrightsz)
665 if (
state->newitemsz * (maxoff - 1) !=
state->olddataitemstotal)
673 if (
state->newitemsz >
687 if (
state->newitemoff > maxoff)
693 if (keepnatts > 1 && keepnatts <= nkeyatts)
724 if (keepnatts > 1 && keepnatts <= nkeyatts)
726 double interp = (double)
state->newitemoff / ((
double) maxoff + 1);
727 double leaffillfactormult = (double) leaffillfactor / 100.0;
734 *usemult = interp > leaffillfactormult;
759 if (lowblk == highblk)
763 if (lowblk + 1 == highblk &&
797 bestpenalty = INT_MAX;
799 for (
int i = lowsplit;
i < highsplit;
i++)
805 if (penalty < bestpenalty)
807 bestpenalty = penalty;
811 if (penalty <= perfectpenalty)
815 final = &
state->splits[lowsplit];
843 final = &
state->splits[0];
846 *newitemonleft =
final->newitemonleft;
847 return final->firstrightoff;
850#define LEAF_SPLIT_DISTANCE 0.050
851#define INTERNAL_SPLIT_DISTANCE 0.075
899 spaceoptimal =
state->splits;
900 lowleftfree = spaceoptimal->
leftfree - tolerance;
901 lowrightfree = spaceoptimal->
rightfree - tolerance;
902 highleftfree = spaceoptimal->
leftfree + tolerance;
903 highrightfree = spaceoptimal->
rightfree + tolerance;
910 for (
int i = 1;
i <
state->nsplits;
i++)
920 return state->nsplits;
956 return state->minfirstrightsz;
972 if (perfectpenalty <= indnkeyatts)
973 return perfectpenalty;
993 if (perfectpenalty <= indnkeyatts)
1021 else if (
state->is_rightmost)
1032 if (perfectpenalty <= indnkeyatts)
1044 return perfectpenalty;
1059 deltaoptimal =
state->splits;
1060 *leftinterval = NULL;
1061 *rightinterval = NULL;
1068 for (
int i = highsplit - 1;
i >= 0;
i--)
1074 if (*leftinterval == NULL)
1075 *leftinterval = distant;
1079 if (*rightinterval == NULL)
1080 *rightinterval = distant;
1089 if (*leftinterval == NULL)
1090 *leftinterval = distant;
1099 if (*rightinterval == NULL)
1100 *rightinterval = distant;
1105 Assert(distant == deltaoptimal);
1106 if (*leftinterval == NULL)
1107 *leftinterval = distant;
1108 if (*rightinterval == NULL)
1109 *rightinterval = distant;
1112 if (*leftinterval && *rightinterval)
1137 if (!
state->is_leaf)
1143 return state->newitemsz;
1165 return state->newitem;
1181 return state->newitem;
Size PageGetExactFreeSpace(const PageData *page)
static Size PageGetPageSize(const PageData *page)
static void * PageGetItem(const PageData *page, const ItemIdData *itemId)
#define SizeOfPageHeaderData
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
Assert(PointerIsAligned(start, uint64))
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
static Size IndexTupleSize(const IndexTupleData *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)
static bool _bt_adjacenthtid(const ItemPointerData *lowhtid, const ItemPointerData *highhtid)
#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)
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