1799 GistEntryVector *entryvec = (GistEntryVector*) PG_GETARG_POINTER(0);
1801 GIST_SPLITVEC *v = (GIST_SPLITVEC*) PG_GETARG_POINTER(1);
1806 OffsetNumber **list;
1809 GIDX *box_pageunion;
1812 bool all_entries_equal =
true;
1813 OffsetNumber max_offset;
1814 int nbytes, ndims_pageunion, d;
1815 int posmin = entryvec->n;
1817 POSTGIS_DEBUG(4,
"[GIST] 'picksplit' function called");
1823 max_offset = entryvec->n - 1;
1824 box_current = (GIDX*) DatumGetPointer(entryvec->vector[FirstOffsetNumber].key);
1828 for ( i = OffsetNumberNext(FirstOffsetNumber); i <= max_offset; i = OffsetNumberNext(i) )
1830 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1832 if ( all_entries_equal ==
true && !
gidx_equals (box_pageunion, box_current) )
1833 all_entries_equal =
false;
1838 POSTGIS_DEBUGF(3,
"[GIST] box_pageunion: %s", gidx_to_string(box_pageunion));
1841 if ( all_entries_equal )
1843 POSTGIS_DEBUG(4,
"[GIST] picksplit finds all entries equal!");
1845 PG_RETURN_POINTER(v);
1849 nbytes = (max_offset + 2) *
sizeof(OffsetNumber);
1850 ndims_pageunion = GIDX_NDIMS(box_pageunion);
1851 POSTGIS_DEBUGF(4,
"[GIST] ndims_pageunion == %d", ndims_pageunion);
1852 pos = palloc(2*ndims_pageunion *
sizeof(
int));
1853 list = palloc(2*ndims_pageunion *
sizeof(OffsetNumber*));
1854 box_union = palloc(2*ndims_pageunion *
sizeof(GIDX*));
1855 for ( d = 0; d < ndims_pageunion; d++ )
1857 list[
BELOW(d)] = (OffsetNumber*) palloc(nbytes);
1858 list[
ABOVE(d)] = (OffsetNumber*) palloc(nbytes);
1859 box_union[
BELOW(d)] = gidx_new(ndims_pageunion);
1860 box_union[
ABOVE(d)] = gidx_new(ndims_pageunion);
1870 POSTGIS_DEBUG(4,
"[GIST] 'picksplit' calculating best split axis");
1871 for ( i = FirstOffsetNumber; i <= max_offset; i = OffsetNumberNext(i) )
1873 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1875 for ( d = 0; d < ndims_pageunion; d++ )
1877 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) )
1903 double *avgCenter = palloc(ndims_pageunion *
sizeof(
double));
1905 for ( d = 0; d < ndims_pageunion; d++ )
1910 POSTGIS_DEBUG(4,
"[GIST] picksplit can't find good split axis, trying center point method");
1912 for ( i = FirstOffsetNumber; i <= max_offset; i = OffsetNumberNext(i) )
1914 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1915 for ( d = 0; d < ndims_pageunion; d++ )
1917 avgCenter[d] += (GIDX_GET_MAX(box_current,d) + GIDX_GET_MIN(box_current,d)) / 2.0;
1920 for ( d = 0; d < ndims_pageunion; d++ )
1922 avgCenter[d] /= max_offset;
1924 POSTGIS_DEBUGF(4,
"[GIST] picksplit average center point[%d] = %.12g", d, avgCenter[d]);
1928 for ( i = FirstOffsetNumber; i <= max_offset; i = OffsetNumberNext(i) )
1931 box_current = (GIDX*) DatumGetPointer(entryvec->vector[i].key);
1933 for ( d = 0; d < ndims_pageunion; d++ )
1935 center = (GIDX_GET_MIN(box_current,d)+GIDX_GET_MAX(box_current,d))/2.0;
1936 if ( center < avgCenter[d] )
1938 else if ( FPeq(center, avgCenter[d]) )
1952 POSTGIS_DEBUG(4,
"[GIST] picksplit still cannot find a good split! just cutting the node in half");
1954 PG_RETURN_POINTER(v);
1966 for ( d = 0; d < ndims_pageunion; d++ )
1969 if ( posd < posmin )
1975 if ( direction == -1 || posmin == entryvec->n )
1978 elog(ERROR,
"Error in building split, unable to determine split direction.");
1981 POSTGIS_DEBUGF(3,
"[GIST] 'picksplit' splitting on axis %d", direction);
1984 pos[
BELOW(direction)],
1985 &(box_union[
BELOW(direction)]),
1986 list[
ABOVE(direction)],
1987 pos[
ABOVE(direction)],
1988 &(box_union[
ABOVE(direction)]) );
1990 POSTGIS_DEBUGF(4,
"[GIST] spl_ldatum: %s", gidx_to_string((GIDX*)v->spl_ldatum));
1991 POSTGIS_DEBUGF(4,
"[GIST] spl_rdatum: %s", gidx_to_string((GIDX*)v->spl_rdatum));
1993 POSTGIS_DEBUGF(4,
"[GIST] axis %d: parent range (%.12g, %.12g) left range (%.12g, %.12g), right range (%.12g, %.12g)",
1995 GIDX_GET_MIN(box_pageunion, direction), GIDX_GET_MAX(box_pageunion, direction),
1996 GIDX_GET_MIN((GIDX*)v->spl_ldatum, direction), GIDX_GET_MAX((GIDX*)v->spl_ldatum, direction),
1997 GIDX_GET_MIN((GIDX*)v->spl_rdatum, direction), GIDX_GET_MAX((GIDX*)v->spl_rdatum, direction) );
1999 PG_RETURN_POINTER(v);
static void gserialized_gist_picksplit_constructsplit(GIST_SPLITVEC *v, OffsetNumber *list1, int nlist1, GIDX **union1, OffsetNumber *list2, int nlist2, GIDX **union2)
static bool gserialized_gist_picksplit_badratios(int *pos, int dims)
static void gserialized_gist_picksplit_addlist(OffsetNumber *list, GIDX **box_union, GIDX *box_current, int *pos, int num)
GIDX * gidx_copy(GIDX *b)
static bool gidx_equals(GIDX *a, GIDX *b)
static void gserialized_gist_picksplit_fallback(GistEntryVector *entryvec, GIST_SPLITVEC *v)
void gidx_merge(GIDX **b_union, GIDX *b_new)