private void initIter(Shape filter) { cellNumber = -1; if (filter instanceof UnitNRShape && ((UnitNRShape) filter).getLevel() == 0) filter = null; // world means everything -- no filter iterFilter = filter; NRCell parent = getShapeAtLevel(getLevel() - 1); // Initialize iter* members. // no filter means all subcells if (filter == null) { iterFirstCellNumber = 0; iterFirstIsIntersects = false; iterLastCellNumber = getNumSubCells(parent) - 1; iterLastIsIntersects = false; return; } final UnitNRShape minLV; final UnitNRShape maxLV; final int lastLevelInCommon; // between minLV & maxLV if (filter instanceof SpanUnitsNRShape) { SpanUnitsNRShape spanShape = (SpanUnitsNRShape) iterFilter; minLV = spanShape.getMinUnit(); maxLV = spanShape.getMaxUnit(); lastLevelInCommon = spanShape.getLevelsInCommon(); } else { minLV = (UnitNRShape) iterFilter; maxLV = minLV; lastLevelInCommon = minLV.getLevel(); } // fast path optimization that is usually true, but never first level if (iterFilter == parent.iterFilter && (getLevel() <= lastLevelInCommon || parent.iterFirstCellNumber != parent.iterLastCellNumber)) { // TODO benchmark if this optimization pays off. We avoid two comparePrefixLV calls. if (parent.iterFirstIsIntersects && parent.cellNumber == parent.iterFirstCellNumber && minLV.getLevel() >= getLevel()) { iterFirstCellNumber = minLV.getValAtLevel(getLevel()); iterFirstIsIntersects = (minLV.getLevel() > getLevel()); } else { iterFirstCellNumber = 0; iterFirstIsIntersects = false; } if (parent.iterLastIsIntersects && parent.cellNumber == parent.iterLastCellNumber && maxLV.getLevel() >= getLevel()) { iterLastCellNumber = maxLV.getValAtLevel(getLevel()); iterLastIsIntersects = (maxLV.getLevel() > getLevel()); } else { iterLastCellNumber = getNumSubCells(parent) - 1; iterLastIsIntersects = false; } if (iterFirstCellNumber == iterLastCellNumber) { if (iterLastIsIntersects) iterFirstIsIntersects = true; else if (iterFirstIsIntersects) iterLastIsIntersects = true; } return; } // not common to get here, except for level 1 which always happens int startCmp = comparePrefix(minLV, parent); if (startCmp > 0) { // start comes after this cell iterFirstCellNumber = 0; iterFirstIsIntersects = false; iterLastCellNumber = -1; // so ends early (no cells) iterLastIsIntersects = false; return; } int endCmp = comparePrefix(maxLV, parent); // compare to end cell if (endCmp < 0) { // end comes before this cell iterFirstCellNumber = 0; iterFirstIsIntersects = false; iterLastCellNumber = -1; // so ends early (no cells) iterLastIsIntersects = false; return; } if (startCmp < 0 || minLV.getLevel() < getLevel()) { // start comes before... iterFirstCellNumber = 0; iterFirstIsIntersects = false; } else { iterFirstCellNumber = minLV.getValAtLevel(getLevel()); iterFirstIsIntersects = (minLV.getLevel() > getLevel()); } if (endCmp > 0 || maxLV.getLevel() < getLevel()) { // end comes after... iterLastCellNumber = getNumSubCells(parent) - 1; iterLastIsIntersects = false; } else { iterLastCellNumber = maxLV.getValAtLevel(getLevel()); iterLastIsIntersects = (maxLV.getLevel() > getLevel()); } if (iterFirstCellNumber == iterLastCellNumber) { if (iterLastIsIntersects) iterFirstIsIntersects = true; else if (iterFirstIsIntersects) iterLastIsIntersects = true; } }