/** * Search the sorted array of result set for key object created from the * skip token key values and returns index of first entry in the next * page. * * @param array(mixed) &$searchArray The sorted array to search. * * @return int (1) If the array is empty then return -1, * (2) If the key object found then return index of first record * in the next page, * (3) If partial matching found (means found matching for first * m keys where m < n, where n is total number of positional * keys, then return the index of the object which has most * matching. * * @throws InvalidArgumentException */ public function getIndexOfFirstEntryInTheNextPage(&$searchArray) { if (!is_array($searchArray)) { throw new \InvalidArgumentException(Messages::internalSkipTokenInfoBinarySearchRequireArray('searchArray')); } if (empty($searchArray)) { return -1; } $comparer = $this->_internalOrderByInfo->getSorterFunction()->getReference(); //Gets the key object initialized from skiptoken $keyObject = $this->getKeyObject(); $low = 0; $searcArraySize = count($searchArray) - 1; $mid = 0; $high = $searcArraySize; do { $matchLevel = 0; $mid = $low + round(($high - $low) / 2); $result = $comparer($keyObject, $searchArray[$mid]); if ($result > 0) { $low = $mid + 1; } else { if ($result < 0) { $high = $mid - 1; } else { //Now we found record the matches with skiptoken value, //so first record of next page will at $mid + 1 if ($mid == $searcArraySize) { //Check skiptoken points to last record, in this //case no more records available for next page return -1; } return $mid + 1; } } } while ($low <= $high); if ($mid >= $searcArraySize) { //If key object does not match with last object, then //no more page return -1; } else { if ($mid <= 0) { //If key object is less than first object, then paged //result start from 0 return 0; } } //return index of the most matching object return $mid; }