1798 GistEntryVector *entryvec = (GistEntryVector*) PG_GETARG_POINTER(0);
1800 GIST_SPLITVEC *v = (GIST_SPLITVEC*) PG_GETARG_POINTER(1);
1805 OffsetNumber **list;
1808 GIDX *box_pageunion;
1811 bool all_entries_equal =
true;
1812 OffsetNumber max_offset;
1813 int nbytes, ndims_pageunion, d;
1814 int posmin = entryvec->n;
1816 POSTGIS_DEBUG(4,
"[GIST] 'picksplit' function called");
1822 max_offset = entryvec->n - 1;
1823 box_current = (GIDX*) DatumGetPointer(entryvec->vector[FirstOffsetNumber].key);
1827 for ( i = OffsetNumberNext(FirstOffsetNumber); i <= max_offset; i = OffsetNumberNext(i) )
1829 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1831 if ( all_entries_equal ==
true && !
gidx_equals (box_pageunion, box_current) )
1832 all_entries_equal =
false;
1837 POSTGIS_DEBUGF(3,
"[GIST] box_pageunion: %s", gidx_to_string(box_pageunion));
1840 if ( all_entries_equal )
1842 POSTGIS_DEBUG(4,
"[GIST] picksplit finds all entries equal!");
1844 PG_RETURN_POINTER(v);
1848 nbytes = (max_offset + 2) *
sizeof(OffsetNumber);
1849 ndims_pageunion = GIDX_NDIMS(box_pageunion);
1850 POSTGIS_DEBUGF(4,
"[GIST] ndims_pageunion == %d", ndims_pageunion);
1851 pos = palloc(2*ndims_pageunion *
sizeof(
int));
1852 list = palloc(2*ndims_pageunion *
sizeof(OffsetNumber*));
1853 box_union = palloc(2*ndims_pageunion *
sizeof(GIDX*));
1854 for ( d = 0; d < ndims_pageunion; d++ )
1856 list[
BELOW(d)] = (OffsetNumber*) palloc(nbytes);
1857 list[
ABOVE(d)] = (OffsetNumber*) palloc(nbytes);
1858 box_union[
BELOW(d)] = gidx_new(ndims_pageunion);
1859 box_union[
ABOVE(d)] = gidx_new(ndims_pageunion);
1869 POSTGIS_DEBUG(4,
"[GIST] 'picksplit' calculating best split axis");
1870 for ( i = FirstOffsetNumber; i <= max_offset; i = OffsetNumberNext(i) )
1872 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1874 for ( d = 0; d < ndims_pageunion; d++ )
1876 if ( GIDX_GET_MIN(box_current,d)-GIDX_GET_MIN(box_pageunion,d) < GIDX_GET_MAX(box_pageunion,d)-GIDX_GET_MAX(box_current,d) )
1902 double *avgCenter = palloc(ndims_pageunion *
sizeof(
double));
1904 for ( d = 0; d < ndims_pageunion; d++ )
1909 POSTGIS_DEBUG(4,
"[GIST] picksplit can't find good split axis, trying center point method");
1911 for ( i = FirstOffsetNumber; i <= max_offset; i = OffsetNumberNext(i) )
1913 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1914 for ( d = 0; d < ndims_pageunion; d++ )
1916 avgCenter[d] += (GIDX_GET_MAX(box_current,d) + GIDX_GET_MIN(box_current,d)) / 2.0;
1919 for ( d = 0; d < ndims_pageunion; d++ )
1921 avgCenter[d] /= max_offset;
1923 POSTGIS_DEBUGF(4,
"[GIST] picksplit average center point[%d] = %.12g", d, avgCenter[d]);
1927 for ( i = FirstOffsetNumber; i <= max_offset; i = OffsetNumberNext(i) )
1930 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1932 for ( d = 0; d < ndims_pageunion; d++ )
1934 center = (GIDX_GET_MIN(box_current,d)+GIDX_GET_MAX(box_current,d))/2.0;
1935 if ( center < avgCenter[d] )
1937 else if (
FPeq(center, avgCenter[d]) )
1951 POSTGIS_DEBUG(4,
"[GIST] picksplit still cannot find a good split! just cutting the node in half");
1953 PG_RETURN_POINTER(v);
1965 for ( d = 0; d < ndims_pageunion; d++ )
1968 if ( posd < posmin )
1974 if ( direction == -1 || posmin == entryvec->n )
1977 elog(ERROR,
"Error in building split, unable to determine split direction.");
1980 POSTGIS_DEBUGF(3,
"[GIST] 'picksplit' splitting on axis %d", direction);
1983 pos[
BELOW(direction)],
1984 &(box_union[
BELOW(direction)]),
1985 list[
ABOVE(direction)],
1986 pos[
ABOVE(direction)],
1987 &(box_union[
ABOVE(direction)]) );
1989 POSTGIS_DEBUGF(4,
"[GIST] spl_ldatum: %s", gidx_to_string((GIDX*)v->spl_ldatum));
1990 POSTGIS_DEBUGF(4,
"[GIST] spl_rdatum: %s", gidx_to_string((GIDX*)v->spl_rdatum));
1992 POSTGIS_DEBUGF(4,
"[GIST] axis %d: parent range (%.12g, %.12g) left range (%.12g, %.12g), right range (%.12g, %.12g)",
1994 GIDX_GET_MIN(box_pageunion, direction), GIDX_GET_MAX(box_pageunion, direction),
1995 GIDX_GET_MIN((GIDX*)v->spl_ldatum, direction), GIDX_GET_MAX((GIDX*)v->spl_ldatum, direction),
1996 GIDX_GET_MIN((GIDX*)v->spl_rdatum, direction), GIDX_GET_MAX((GIDX*)v->spl_rdatum, direction) );
1998 PG_RETURN_POINTER(v);
static void gidx_merge(GIDX **b_union, GIDX *b_new)
static GIDX * gidx_copy(GIDX *b)
static void gserialized_gist_picksplit_constructsplit(GIST_SPLITVEC *v, OffsetNumber *list1, int nlist1, GIDX **union1, OffsetNumber *list2, int nlist2, GIDX **union2)
static bool gidx_equals(GIDX *a, GIDX *b)
static bool gserialized_gist_picksplit_badratios(int *pos, int dims)
static void gserialized_gist_picksplit_fallback(GistEntryVector *entryvec, GIST_SPLITVEC *v)
static void gserialized_gist_picksplit_addlist(OffsetNumber *list, GIDX **box_union, GIDX *box_current, int *pos, int num)