- /**
- * @param float $position
- * @param array[] $ring Either the base or live ring
- * @return int
- */
- private function guessNodeIndexForPosition( $position, $ring ) {
- $arcRatio = $position / self::RING_SIZE; // range is [0.0, 1.0)
- $maxIndex = count( $ring ) - 1;
- $guessIndex = intval( $maxIndex * $arcRatio );
-
- $displacement = $ring[$guessIndex][self::KEY_POS] - $position;
- $aveSize = self::RING_SIZE / count( $ring );
- $shift = intval( $displacement / $aveSize );
-
- $guessIndex -= $shift;
- if ( $guessIndex < 0 ) {
- $guessIndex = max( $maxIndex + $guessIndex, 0 ); // roll-over
- } elseif ( $guessIndex > $maxIndex ) {
- $guessIndex = min( $guessIndex - $maxIndex, 0 ); // roll-over
- }
-
- return $guessIndex;
- }
-
- /**
- * @param float $position
- * @param int $guessIndex Node index to start scanning
- * @param array[] $ring Either the base or live ring
- * @return int|null
- */
- private function findNodeIndexForPosition( $position, $guessIndex, $ring ) {
- $mainNodeIndex = null; // first matching node index
-
- $this->lastNodeScanSize = 0;
-
- if ( $ring[$guessIndex][self::KEY_POS] >= $position ) {
- // Walk the nodes counter-clockwise until reaching a node at/before $position
- do {
- $priorIndex = $guessIndex;
- $guessIndex = $this->getPrevClockwiseNodeIndex( $guessIndex, $ring );
- $nodePosition = $ring[$guessIndex][self::KEY_POS];
- if ( $nodePosition < $position || $guessIndex > $priorIndex ) {
- $mainNodeIndex = $priorIndex; // includes roll-over case
- } elseif ( $nodePosition === $position ) {
- $mainNodeIndex = $guessIndex;
- }
- ++$this->lastNodeScanSize;
- } while ( $mainNodeIndex === null );
- } else {
- // Walk the nodes clockwise until reaching a node at/after $position
- do {
- $priorIndex = $guessIndex;
- $guessIndex = $this->getNextClockwiseNodeIndex( $guessIndex, $ring );
- $nodePosition = $ring[$guessIndex][self::KEY_POS];
- if ( $nodePosition >= $position || $guessIndex < $priorIndex ) {
- $mainNodeIndex = $guessIndex; // includes roll-over case
- }
- ++$this->lastNodeScanSize;
- } while ( $mainNodeIndex === null );
- }
-
- return $mainNodeIndex;
- }
-