1783 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
1784 GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
1788 BOX2DF *leftBox, *rightBox;
1796 POSTGIS_DEBUG(3,
"[GIST] 'picksplit' entered");
1800 maxoff = entryvec->n - 1;
1801 nentries = context.
entriesCount = maxoff - FirstOffsetNumber + 1;
1810 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
1812 BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[i].key);
1813 if (i == FirstOffsetNumber)
1825 context.
first =
true;
1826 for (dim = 0; dim < 2; dim++)
1834 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
1836 BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[i].key);
1839 intervalsLower[i - FirstOffsetNumber].
lower = box->xmin;
1840 intervalsLower[i - FirstOffsetNumber].
upper = box->xmax;
1844 intervalsLower[i - FirstOffsetNumber].
lower = box->ymin;
1845 intervalsLower[i - FirstOffsetNumber].
upper = box->ymax;
1853 memcpy(intervalsUpper, intervalsLower,
1896 rightLower = intervalsLower[i1].
lower;
1897 leftUpper = intervalsUpper[i2].
lower;
1903 while (i1 < nentries && (rightLower == intervalsLower[i1].lower ||
1904 isnan(intervalsLower[i1].lower)))
1906 leftUpper = Max(leftUpper, intervalsLower[i1].upper);
1911 rightLower = intervalsLower[i1].
lower;
1917 while (i2 < nentries && intervalsUpper[i2].upper <= leftUpper)
1932 rightLower = intervalsLower[i1].
upper;
1933 leftUpper = intervalsUpper[i2].
upper;
1939 while (i2 >= 0 && (leftUpper == intervalsUpper[i2].upper ||
1940 isnan(intervalsUpper[i2].upper)))
1942 rightLower = Min(rightLower, intervalsUpper[i2].lower);
1947 leftUpper = intervalsUpper[i2].
upper;
1953 while (i1 >= 0 && intervalsLower[i1].lower >= rightLower)
1960 rightLower, i1 + 1, leftUpper, i2 + 1);
1969 POSTGIS_DEBUG(4,
"no acceptable splits, trivial split");
1971 PG_RETURN_POINTER(v);
1982 POSTGIS_DEBUGF(4,
"split direction: %d", context.
dim);
1985 v->spl_left = (OffsetNumber *) palloc(nentries *
sizeof(OffsetNumber));
1986 v->spl_right = (OffsetNumber *) palloc(nentries *
sizeof(OffsetNumber));
1991 leftBox = palloc0(
sizeof(BOX2DF));
1992 rightBox = palloc0(
sizeof(BOX2DF));
1998 commonEntriesCount = 0;
2002 #define PLACE_LEFT(box, off) \
2004 if (v->spl_nleft > 0) \
2005 adjustBox(leftBox, box); \
2007 *leftBox = *(box); \
2008 v->spl_left[v->spl_nleft++] = off; \
2011 #define PLACE_RIGHT(box, off) \
2013 if (v->spl_nright > 0) \
2014 adjustBox(rightBox, box); \
2016 *rightBox = *(box); \
2017 v->spl_right[v->spl_nright++] = off; \
2024 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
2032 BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[i].key);
2033 if (context.
dim == 0)
2044 if (upper <= context.
leftUpper || isnan(upper))
2047 if (lower >= context.
rightLower || isnan(lower))
2050 commonEntries[commonEntriesCount++].
index = i;
2078 if (commonEntriesCount > 0)
2089 for (i = 0; i < (OffsetNumber)commonEntriesCount; i++)
2091 BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[commonEntries[i].index].key);
2093 if (v->spl_nright > 0 && v->spl_nleft > 0)
2096 commonEntries[i].
delta =
2110 for (i = 0; i < (OffsetNumber)commonEntriesCount; i++)
2112 bool place_right =
true;
2113 BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[commonEntries[i].index].key);
2120 if (v->spl_nright == 0 && v->spl_nleft > 0)
2122 else if (v->spl_nleft == 0 && v->spl_nright > 0)
2123 place_right =
false;
2125 else if (v->spl_nleft + (commonEntriesCount - i) <= m)
2126 place_right =
false;
2127 else if (v->spl_nright + (commonEntriesCount - i) <= m)
2130 else if (left_penalty < right_penalty)
2131 place_right =
false;
2132 else if (right_penalty < left_penalty)
2135 else if (v->spl_nleft < v->spl_nright)
2136 place_right =
false;
2146 v->spl_ldatum = PointerGetDatum(leftBox);
2147 v->spl_rdatum = PointerGetDatum(rightBox);
2149 POSTGIS_DEBUG(4,
"[GIST] 'picksplit' completed");
2151 PG_RETURN_POINTER(v);
static char * box2df_to_string(const BOX2DF *a)
static void fallbackSplit(GistEntryVector *entryvec, GIST_SPLITVEC *v)
#define INDEX_TUPLES_PER_PAGE
static int interval_cmp_upper(const void *i1, const void *i2)
#define PLACE_RIGHT(box, off)
static float box2df_penalty_single(const BOX2DF *box)
static void g_box_consider_split(ConsiderSplitContext *context, int dimNum, float rightLower, int minLeftCount, float leftUpper, int maxLeftCount)
static int interval_cmp_lower(const void *i1, const void *i2)
static int common_entry_cmp(const void *i1, const void *i2)
#define PLACE_LEFT(box, off)
static float box2df_penalty(const BOX2DF *b1, const BOX2DF *b2)
static void adjustBox(BOX2DF *b, BOX2DF *addon)