/** * Searches a range * * @param Range $range * * @return RangeIterator */ public function searchRange(Range $range) { $iterator = $this->getIterator(); // find start $start = null; $binarySearch = new BinarySearch($this); $startHint = $binarySearch->search($range->getMin()); if ($startHint == null) { return new RangeIterator($iterator, Range::getEmptyRange()); } $iterator->setOffset($startHint->getOffset(), Parser::HINT_RESULT_BOUNDARY); if (!$range->contains($startHint->getKey()) && $startHint->getKey() <= $range->getMin()) { // shift $startHint higher foreach ($iterator as $result) { if ($range->contains($result->getKey())) { $start = $result; break; } } } else { // shift $startHint lower if ($range->contains($startHint->getKey())) { $start = $startHint; } $iterator->setDirection(KeyReader::DIRECTION_BACKWARD); foreach ($iterator as $result) { // Skip everything which is too big if (!$range->contains($result->getKey() && $result->getKey() >= $range->getMax())) { continue; } // shift the start left until no more key is included if ($range->contains($result->getKey())) { $start = $result; } else { break; } } } if (is_null($start)) { return new RangeIterator($iterator, Range::getEmptyRange()); } $iterator = $this->getIterator(); $iterator->setOffset($start->getOffset(), Parser::HINT_RESULT_BOUNDARY); return new RangeIterator($iterator, $range); }