diff -r 5b37998e522e -r 162c1de6545a web/lib/Zend/Search/Lucene/PriorityQueue.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/Zend/Search/Lucene/PriorityQueue.php Fri Mar 11 15:05:35 2011 +0100 @@ -0,0 +1,171 @@ +_heap); + $parentId = ($nodeId-1) >> 1; // floor( ($nodeId-1)/2 ) + + while ($nodeId != 0 && $this->_less($element, $this->_heap[$parentId])) { + // Move parent node down + $this->_heap[$nodeId] = $this->_heap[$parentId]; + + // Move pointer to the next level of tree + $nodeId = $parentId; + $parentId = ($nodeId-1) >> 1; // floor( ($nodeId-1)/2 ) + } + + // Put new node into the tree + $this->_heap[$nodeId] = $element; + } + + + /** + * Return least element of the queue + * + * Constant time + * + * @return mixed + */ + public function top() + { + if (count($this->_heap) == 0) { + return null; + } + + return $this->_heap[0]; + } + + + /** + * Removes and return least element of the queue + * + * O(log(N)) time + * + * @return mixed + */ + public function pop() + { + if (count($this->_heap) == 0) { + return null; + } + + $top = $this->_heap[0]; + $lastId = count($this->_heap) - 1; + + /** + * Find appropriate position for last node + */ + $nodeId = 0; // Start from a top + $childId = 1; // First child + + // Choose smaller child + if ($lastId > 2 && $this->_less($this->_heap[2], $this->_heap[1])) { + $childId = 2; + } + + while ($childId < $lastId && + $this->_less($this->_heap[$childId], $this->_heap[$lastId]) + ) { + // Move child node up + $this->_heap[$nodeId] = $this->_heap[$childId]; + + $nodeId = $childId; // Go down + $childId = ($nodeId << 1) + 1; // First child + + // Choose smaller child + if (($childId+1) < $lastId && + $this->_less($this->_heap[$childId+1], $this->_heap[$childId]) + ) { + $childId++; + } + } + + // Move last element to the new position + $this->_heap[$nodeId] = $this->_heap[$lastId]; + unset($this->_heap[$lastId]); + + return $top; + } + + + /** + * Clear queue + */ + public function clear() + { + $this->_heap = array(); + } + + + /** + * Compare elements + * + * Returns true, if $el1 is less than $el2; else otherwise + * + * @param mixed $el1 + * @param mixed $el2 + * @return boolean + */ + abstract protected function _less($el1, $el2); +} +