function hashCode($s) { $h = 0; $len = strlen($s); for ($i = 0; $i < $len; $i++) { $h = overflow32(31 * $h + ord($s[$i])); } return $h; }
/** * Efficient method to check if a range of bits is set, or not set. * * @param start start of range, inclusive. * @param end end of range, exclusive * @param value if true, checks that bits in range are set, otherwise checks that they are not set * @return true iff all bits are set or not set in range, according to value argument * @throws InvalidArgumentException if end is less than or equal to start */ public function isRange($start, $end, $value) { if ($end < $start) { throw new InvalidArgumentException(); } if ($end == $start) { return true; // empty range matches } $end--; // will be easier to treat this as the last actually set bit -- inclusive $firstInt = intval($start / 32); $lastInt = intval($end / 32); for ($i = $firstInt; $i <= $lastInt; $i++) { $firstBit = $i > $firstInt ? 0 : $start & 0x1f; $lastBit = $i < $lastInt ? 31 : $end & 0x1f; $mask = 0; if ($firstBit == 0 && $lastBit == 31) { $mask = -1; } else { $mask = 0; for ($j = $firstBit; $j <= $lastBit; $j++) { $mask = overflow32($mask | 1 << $j); } } // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is, // equals the mask, or we're looking for 0s and the masked portion is not all 0s if (($this->bits[$i] & $mask) != ($value ? $mask : 0)) { return false; } } return true; }
/** * <p>Sets a square region of the bit matrix to true.</p> * * @param $left; The horizontal position to begin at (inclusive) * @param $top; The vertical position to begin at (inclusive) * @param $width; The width of the region * @param $height; The height of the region */ public function setRegion($left, $top, $width, $height) { if ($top < 0 || $left < 0) { throw new InvalidArgumentException("Left and top must be nonnegative"); } if ($height < 1 || $width < 1) { throw new InvalidArgumentException("Height and width must be at least 1"); } $right = $left + $width; $bottom = $top + $height; if ($bottom > $this->height || $right > $this->width) { //> this.height || right > this.width throw new InvalidArgumentException("The region must fit inside the matrix"); } for ($y = $top; $y < $bottom; $y++) { $offset = $y * $this->rowSize; for ($x = $left; $x < $right; $x++) { $this->bits[$offset + intval($x / 32)] = overflow32($this->bits[$offset + intval($x / 32)] |= 1 << ($x & 0x1f)); } } }