diff --git a/hphp/system/classes/splheap.php b/hphp/system/classes/splheap.php new file mode 100644 index 000000000..198a68671 --- /dev/null +++ b/hphp/system/classes/splheap.php @@ -0,0 +1,357 @@ +checkNotCorrupted(); + if ($this->isEmpty()) { + throw new RuntimeException( + 'Can\'t extract from an empty heap' + ); + } + + $result = $this->top(); + $end = $this->highestUsedIndex(); + $this->swapElements(0, $end); + unset($this->heap[$end]); + + try { + $this->heapifyDown(0); + } catch (Exception $e) { + $this->isCorrupted = true; + throw $e; + } + return $result; + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.insert.php ) + * + * Insert value in the heap. + * + * @value mixed The value to insert. + * + * @return mixed No value is returned. + */ + public function insert($value) { + $this->checkNotCorrupted(); + $index = $this->lowestFreeIndex(); + $this->heap[$index] = $value; + + try { + $this->heapifyUp($index); + } catch (Exception $e) { + $this->isCorrupted = true; + throw $e; + } + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.isempty.php ) + * + * + * @return mixed Returns whether the heap is empty. + */ + public function isEmpty() { + return $this->count() == 0; + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from + * http://php.net/manual/en/splheap.recoverfromcorruption.php ) + * + * + * @return mixed No value is returned. + */ + public function recoverFromCorruption() { + $this->isCorrupted = false; + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.count.php ) + * + * + * @return mixed Returns the number of elements in the heap. + */ + public function count() { + return count($this->heap); + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.current.php ) + * + * Get the current datastructure node. + * + * @return mixed The current node value. + */ + public function current() { + return $this->isEmpty() ? null : $this->top(); + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.key.php ) + * + * This function returns the current node index + * + * @return mixed The current node index. + */ + public function key() { + return $this->highestUsedIndex(); + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.next.php ) + * + * Move to the next node. + * + * @return mixed No value is returned. + */ + public function next() { + if ($this->isEmpty()) { + // don't error, just silently stop + return; + } + $this->extract(); + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.rewind.php ) + * + * This rewinds the iterator to the beginning. This is a no-op for heaps + * as the iterator is virtual and in fact never moves from the top of the + * heap. + * + * @return mixed No value is returned. + */ + public function rewind() { + // Do nothing, the iterator always points to the top element + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.top.php ) + * + * + * @return mixed The value of the node on the top. + */ + public function top() { + $this->checkNotCorrupted(); + if ($this->isEmpty()) { + throw new RuntimeException( + 'Can\'t peak at an empty heap' + ); + } + + return $this->heap[0]; + } + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splheap.valid.php ) + * + * Checks if the heap contains any more nodes. + * + * @return mixed Returns TRUE if the heap contains any more nodes, + * FALSE otherwise. + */ + public function valid() { + return !$this->isEmpty(); + } + + private function heapifyUp($index) { + if ($index != 0) { + $parentIndex = self::parentIndex($index); + if ($this->compare($this->heap[$index], + $this->heap[$parentIndex]) > 0) { + $this->swapElements($parentIndex, $index); + $this->heapifyUp($parentIndex); + } + } + } + + private function heapifyDown($index) { + $highestChildIndex = $this->getHighestChildIndex($index); + if ($highestChildIndex !== null && + $this->compare($this->heap[$highestChildIndex], + $this->heap[$index]) > 0) { + $this->swapElements($index, $highestChildIndex); + $this->heapifyDown($highestChildIndex); + } + } + + private function getHighestChildIndex($index) { + if (isset($this->heap[self::leftChildIndex($index)])) { + if (isset($this->heap[self::rightChildIndex($index)])) { + if ($this->compare($this->heap[self::rightChildIndex($index)], + $this->heap[self::leftChildIndex($index)]) > 0) { + return self::rightChildIndex($index); + } else { + return self::leftChildIndex($index); + } + } else { + return self::leftChildIndex($index); + } + } else { + return null; + } + } + + private function swapElements($firstIndex, $secondIndex) { + $temporary = $this->heap[$firstIndex]; + $this->heap[$firstIndex] = $this->heap[$secondIndex]; + $this->heap[$secondIndex] = $temporary; + } + + private function lowestFreeIndex() { + return $this->count(); + } + + private function highestUsedIndex() { + return $this->count() - 1; + } + + private function checkNotCorrupted() { + if ($this->isCorrupted) { + throw new RuntimeException( + 'Heap is corrupted, heap properties are no longer ensured.' + ); + } + } + + private static function leftChildIndex($rootIndex) { + return 2 * $rootIndex + 1; + } + + private static function rightChildIndex($rootIndex) { + return 2 * $rootIndex + 2; + } + + private static function parentIndex($childIndex) { + return floor(($childIndex - 1) / 2); + } + +} + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/class.splmaxheap.php ) + * + * The SplMaxHeap class provides the main functionalities of a heap, + * keeping the maximum on the top. + * + */ +class SplMaxHeap extends SplHeap implements Iterator, Countable { +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splmaxheap.compare.php ) + * + * Compare value1 with value2. + * + * @value1 mixed The value of the first node being compared. + * @value2 mixed The value of the second node being compared. + * + * @return mixed Result of the comparison, positive integer if value1 + * is greater than value2, 0 if they are equal, + * negative integer otherwise. + * + * Having multiple elements with the same value in a + * Heap is not recommended. They will end up in an + * arbitrary relative position. + */ + function compare($value1, $value2) { + return $value1 - $value2; + } +} + +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/class.splminheap.php ) + * + * The SplMinHeap class provides the main functionalities of a heap, + * keeping the minimum on the top. + * + */ +class SplMinHeap extends SplHeap implements Iterator, Countable { +// This doc comment block generated by idl/sysdoc.php +/** + * ( excerpt from http://php.net/manual/en/splminheap.compare.php ) + * + * Compare value1 with value2. + * + * @value1 mixed The value of the first node being compared. + * @value2 mixed The value of the second node being compared. + * + * @return mixed Result of the comparison, positive integer if value1 + * is lower than value2, 0 if they are equal, negative + * integer otherwise. + * + * Having multiple elements with the same value in a + * Heap is not recommended. They will end up in an + * arbitrary relative position. + */ + function compare($value1, $value2) { + return $value2 - $value1; + } +} diff --git a/hphp/test/zend/bad/ext-spl/SplHeap_isEmpty.php b/hphp/test/zend/good/ext-spl/SplHeap_isEmpty.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/SplHeap_isEmpty.php rename to hphp/test/zend/good/ext-spl/SplHeap_isEmpty.php diff --git a/hphp/test/zend/bad/ext-spl/SplHeap_isEmpty.php.expectf b/hphp/test/zend/good/ext-spl/SplHeap_isEmpty.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/SplHeap_isEmpty.php.expectf rename to hphp/test/zend/good/ext-spl/SplHeap_isEmpty.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/bug62073.php b/hphp/test/zend/good/ext-spl/bug62073.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/bug62073.php rename to hphp/test/zend/good/ext-spl/bug62073.php diff --git a/hphp/test/zend/bad/ext-spl/bug62073.php.expectf b/hphp/test/zend/good/ext-spl/bug62073.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/bug62073.php.expectf rename to hphp/test/zend/good/ext-spl/bug62073.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_001.php b/hphp/test/zend/good/ext-spl/heap_001.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_001.php rename to hphp/test/zend/good/ext-spl/heap_001.php diff --git a/hphp/test/zend/bad/ext-spl/heap_001.php.expectf b/hphp/test/zend/good/ext-spl/heap_001.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_001.php.expectf rename to hphp/test/zend/good/ext-spl/heap_001.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_002.php b/hphp/test/zend/good/ext-spl/heap_002.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_002.php rename to hphp/test/zend/good/ext-spl/heap_002.php diff --git a/hphp/test/zend/bad/ext-spl/heap_002.php.expectf b/hphp/test/zend/good/ext-spl/heap_002.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_002.php.expectf rename to hphp/test/zend/good/ext-spl/heap_002.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_003.php b/hphp/test/zend/good/ext-spl/heap_003.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_003.php rename to hphp/test/zend/good/ext-spl/heap_003.php diff --git a/hphp/test/zend/bad/ext-spl/heap_003.php.expectf b/hphp/test/zend/good/ext-spl/heap_003.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_003.php.expectf rename to hphp/test/zend/good/ext-spl/heap_003.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_004.php b/hphp/test/zend/good/ext-spl/heap_004.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_004.php rename to hphp/test/zend/good/ext-spl/heap_004.php diff --git a/hphp/test/zend/bad/ext-spl/heap_004.php.expectf b/hphp/test/zend/good/ext-spl/heap_004.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_004.php.expectf rename to hphp/test/zend/good/ext-spl/heap_004.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_005.php b/hphp/test/zend/good/ext-spl/heap_005.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_005.php rename to hphp/test/zend/good/ext-spl/heap_005.php diff --git a/hphp/test/zend/bad/ext-spl/heap_005.php.expectf b/hphp/test/zend/good/ext-spl/heap_005.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_005.php.expectf rename to hphp/test/zend/good/ext-spl/heap_005.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_006.php b/hphp/test/zend/good/ext-spl/heap_006.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_006.php rename to hphp/test/zend/good/ext-spl/heap_006.php diff --git a/hphp/test/zend/bad/ext-spl/heap_006.php.expectf b/hphp/test/zend/good/ext-spl/heap_006.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_006.php.expectf rename to hphp/test/zend/good/ext-spl/heap_006.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_007.php b/hphp/test/zend/good/ext-spl/heap_007.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_007.php rename to hphp/test/zend/good/ext-spl/heap_007.php diff --git a/hphp/test/zend/bad/ext-spl/heap_007.php.expectf b/hphp/test/zend/good/ext-spl/heap_007.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_007.php.expectf rename to hphp/test/zend/good/ext-spl/heap_007.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_008.php b/hphp/test/zend/good/ext-spl/heap_008.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_008.php rename to hphp/test/zend/good/ext-spl/heap_008.php diff --git a/hphp/test/zend/bad/ext-spl/heap_008.php.expectf b/hphp/test/zend/good/ext-spl/heap_008.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_008.php.expectf rename to hphp/test/zend/good/ext-spl/heap_008.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_010.php b/hphp/test/zend/good/ext-spl/heap_010.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_010.php rename to hphp/test/zend/good/ext-spl/heap_010.php diff --git a/hphp/test/zend/bad/ext-spl/heap_010.php.expectf b/hphp/test/zend/good/ext-spl/heap_010.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_010.php.expectf rename to hphp/test/zend/good/ext-spl/heap_010.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_011.php b/hphp/test/zend/good/ext-spl/heap_011.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_011.php rename to hphp/test/zend/good/ext-spl/heap_011.php diff --git a/hphp/test/zend/bad/ext-spl/heap_011.php.expectf b/hphp/test/zend/good/ext-spl/heap_011.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_011.php.expectf rename to hphp/test/zend/good/ext-spl/heap_011.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_012.php b/hphp/test/zend/good/ext-spl/heap_012.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_012.php rename to hphp/test/zend/good/ext-spl/heap_012.php diff --git a/hphp/test/zend/bad/ext-spl/heap_012.php.expectf b/hphp/test/zend/good/ext-spl/heap_012.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_012.php.expectf rename to hphp/test/zend/good/ext-spl/heap_012.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_corruption.php b/hphp/test/zend/good/ext-spl/heap_corruption.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_corruption.php rename to hphp/test/zend/good/ext-spl/heap_corruption.php diff --git a/hphp/test/zend/bad/ext-spl/heap_corruption.php.expectf b/hphp/test/zend/good/ext-spl/heap_corruption.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_corruption.php.expectf rename to hphp/test/zend/good/ext-spl/heap_corruption.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_current_variation_001.php b/hphp/test/zend/good/ext-spl/heap_current_variation_001.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_current_variation_001.php rename to hphp/test/zend/good/ext-spl/heap_current_variation_001.php diff --git a/hphp/test/zend/bad/ext-spl/heap_current_variation_001.php.expectf b/hphp/test/zend/good/ext-spl/heap_current_variation_001.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_current_variation_001.php.expectf rename to hphp/test/zend/good/ext-spl/heap_current_variation_001.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_it_current_empty.php b/hphp/test/zend/good/ext-spl/heap_it_current_empty.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_it_current_empty.php rename to hphp/test/zend/good/ext-spl/heap_it_current_empty.php diff --git a/hphp/test/zend/bad/ext-spl/heap_it_current_empty.php.expectf b/hphp/test/zend/good/ext-spl/heap_it_current_empty.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_it_current_empty.php.expectf rename to hphp/test/zend/good/ext-spl/heap_it_current_empty.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/heap_top_variation_002.php b/hphp/test/zend/good/ext-spl/heap_top_variation_002.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_top_variation_002.php rename to hphp/test/zend/good/ext-spl/heap_top_variation_002.php diff --git a/hphp/test/zend/bad/ext-spl/heap_top_variation_002.php.expectf b/hphp/test/zend/good/ext-spl/heap_top_variation_002.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/heap_top_variation_002.php.expectf rename to hphp/test/zend/good/ext-spl/heap_top_variation_002.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/spl_heap_isempty.php b/hphp/test/zend/good/ext-spl/spl_heap_isempty.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/spl_heap_isempty.php rename to hphp/test/zend/good/ext-spl/spl_heap_isempty.php diff --git a/hphp/test/zend/bad/ext-spl/spl_heap_isempty.php.expectf b/hphp/test/zend/good/ext-spl/spl_heap_isempty.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/spl_heap_isempty.php.expectf rename to hphp/test/zend/good/ext-spl/spl_heap_isempty.php.expectf diff --git a/hphp/test/zend/bad/ext-spl/spl_heap_iteration_error.php b/hphp/test/zend/good/ext-spl/spl_heap_iteration_error.php similarity index 100% rename from hphp/test/zend/bad/ext-spl/spl_heap_iteration_error.php rename to hphp/test/zend/good/ext-spl/spl_heap_iteration_error.php diff --git a/hphp/test/zend/bad/ext-spl/spl_heap_iteration_error.php.expectf b/hphp/test/zend/good/ext-spl/spl_heap_iteration_error.php.expectf similarity index 100% rename from hphp/test/zend/bad/ext-spl/spl_heap_iteration_error.php.expectf rename to hphp/test/zend/good/ext-spl/spl_heap_iteration_error.php.expectf