PostGIS 3.6.2dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ g_box_consider_split()

static void g_box_consider_split ( ConsiderSplitContext context,
int  dimNum,
float  rightLower,
int  minLeftCount,
float  leftUpper,
int  maxLeftCount 
)
inlinestatic

Definition at line 1607 of file gserialized_gist_2d.c.

1610{
1611 int leftCount,
1612 rightCount;
1613 float4 ratio,
1614 overlap;
1615 float range;
1616
1617 POSTGIS_DEBUGF(5, "consider split: dimNum = %d, rightLower = %f, "
1618 "minLeftCount = %d, leftUpper = %f, maxLeftCount = %d ",
1619 dimNum, rightLower, minLeftCount, leftUpper, maxLeftCount);
1620
1621 /*
1622 * Calculate entries distribution ratio assuming most uniform distribution
1623 * of common entries.
1624 */
1625 if (minLeftCount >= (context->entriesCount + 1) / 2)
1626 {
1627 leftCount = minLeftCount;
1628 }
1629 else
1630 {
1631 if (maxLeftCount <= context->entriesCount / 2)
1632 leftCount = maxLeftCount;
1633 else
1634 leftCount = context->entriesCount / 2;
1635 }
1636 rightCount = context->entriesCount - leftCount;
1637
1638 /*
1639 * Ratio of split - quotient between size of lesser group and total
1640 * entries count.
1641 */
1642 ratio = ((float4) Min(leftCount, rightCount)) /
1643 ((float4) context->entriesCount);
1644
1645 if (ratio > LIMIT_RATIO)
1646 {
1647 bool selectthis = false;
1648
1649 /*
1650 * The ratio is acceptable, so compare current split with previously
1651 * selected one. Between splits of one dimension we search for minimal
1652 * overlap (allowing negative values) and minimal ration (between same
1653 * overlaps. We switch dimension if find less overlap (non-negative)
1654 * or less range with same overlap.
1655 */
1656 if (dimNum == 0)
1657 range = context->boundingBox.xmax - context->boundingBox.xmin;
1658 else
1659 range = context->boundingBox.ymax - context->boundingBox.ymin;
1660
1661 overlap = (leftUpper - rightLower) / range;
1662
1663 /* If there is no previous selection, select this */
1664 if (context->first)
1665 selectthis = true;
1666 else if (context->dim == dimNum)
1667 {
1668 /*
1669 * Within the same dimension, choose the new split if it has a
1670 * smaller overlap, or same overlap but better ratio.
1671 */
1672 if (overlap < context->overlap ||
1673 (overlap == context->overlap && ratio > context->ratio))
1674 selectthis = true;
1675 }
1676 else
1677 {
1678 /*
1679 * Across dimensions, choose the new split if it has a smaller
1680 * *non-negative* overlap, or same *non-negative* overlap but
1681 * bigger range. This condition differs from the one described in
1682 * the article. On the datasets where leaf MBRs don't overlap
1683 * themselves, non-overlapping splits (i.e. splits which have zero
1684 * *non-negative* overlap) are frequently possible. In this case
1685 * splits tends to be along one dimension, because most distant
1686 * non-overlapping splits (i.e. having lowest negative overlap)
1687 * appears to be in the same dimension as in the previous split.
1688 * Therefore MBRs appear to be very prolonged along another
1689 * dimension, which leads to bad search performance. Using range
1690 * as the second split criteria makes MBRs more quadratic. Using
1691 * *non-negative* overlap instead of overlap as the first split
1692 * criteria gives to range criteria a chance to matter, because
1693 * non-overlapping splits are equivalent in this criteria.
1694 */
1695 if (non_negative(overlap) < non_negative(context->overlap) ||
1696 (range > context->range &&
1697 non_negative(overlap) <= non_negative(context->overlap)))
1698 selectthis = true;
1699 }
1700
1701 if (selectthis)
1702 {
1703 /* save information about selected split */
1704 context->first = false;
1705 context->ratio = ratio;
1706 context->range = range;
1707 context->overlap = overlap;
1708 context->rightLower = rightLower;
1709 context->leftUpper = leftUpper;
1710 context->dim = dimNum;
1711 POSTGIS_DEBUG(5, "split selected");
1712 }
1713 }
1714}
#define LIMIT_RATIO
static float non_negative(float val)

References ConsiderSplitContext::boundingBox, ConsiderSplitContext::dim, ConsiderSplitContext::entriesCount, ConsiderSplitContext::first, ConsiderSplitContext::leftUpper, LIMIT_RATIO, non_negative(), ConsiderSplitContext::overlap, ConsiderSplitContext::range, ConsiderSplitContext::ratio, and ConsiderSplitContext::rightLower.

Referenced by gserialized_gist_picksplit_2d().

Here is the call graph for this function:
Here is the caller graph for this function: