CLucene - a full-featured, c++ search engine
API Documentation
00001 /*------------------------------------------------------------------------------ 00002 * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team 00003 * 00004 * Distributable under the terms of either the Apache License (Version 2.0) or 00005 * the GNU Lesser General Public License, as specified in the COPYING file. 00006 ------------------------------------------------------------------------------*/ 00007 #ifndef _lucene_util_PriorityQueue_ 00008 #define _lucene_util_PriorityQueue_ 00009 00010 #if defined(_LUCENE_PRAGMA_ONCE) 00011 # pragma once 00012 #endif 00013 CL_NS_DEF(util) 00014 00015 // A PriorityQueue maintains a partial ordering of its elements such that the 00016 // least element can always be found in constant time. Put()'s and pop()'s 00017 // require log(size) time. 00018 template <class _type,typename _valueDeletor> class PriorityQueue:LUCENE_BASE { 00019 private: 00020 _type* heap; //(was object[]) 00021 size_t _size; 00022 bool dk; 00023 size_t maxSize; 00024 00025 void upHeap(){ 00026 size_t i = _size; 00027 _type node = heap[i]; // save bottom node (WAS object) 00028 int32_t j = ((uint32_t)i) >> 1; 00029 while (j > 0 && lessThan(node,heap[j])) { 00030 heap[i] = heap[j]; // shift parents down 00031 i = j; 00032 j = ((uint32_t)j) >> 1; 00033 } 00034 heap[i] = node; // install saved node 00035 } 00036 void downHeap(){ 00037 size_t i = 1; 00038 _type node = heap[i]; // save top node 00039 size_t j = i << 1; // find smaller child 00040 size_t k = j + 1; 00041 if (k <= _size && lessThan(heap[k], heap[j])) { 00042 j = k; 00043 } 00044 while (j <= _size && lessThan(heap[j],node)) { 00045 heap[i] = heap[j]; // shift up child 00046 i = j; 00047 j = i << 1; 00048 k = j + 1; 00049 if (k <= _size && lessThan(heap[k], heap[j])) { 00050 j = k; 00051 } 00052 } 00053 heap[i] = node; // install saved node 00054 } 00055 00056 protected: 00057 PriorityQueue(){ 00058 this->_size = 0; 00059 this->dk = false; 00060 this->heap = NULL; 00061 this->maxSize = 0; 00062 } 00063 00064 // Determines the ordering of objects in this priority queue. Subclasses 00065 // must define this one method. 00066 virtual bool lessThan(_type a, _type b)=0; 00067 00068 // Subclass constructors must call this. 00069 void initialize(const int32_t maxSize, bool deleteOnClear){ 00070 _size = 0; 00071 dk = deleteOnClear; 00072 int32_t heapSize = maxSize + 1; 00073 heap = _CL_NEWARRAY(_type,heapSize); 00074 this->maxSize = maxSize; 00075 } 00076 00077 public: 00078 virtual ~PriorityQueue(){ 00079 clear(); 00080 _CLDELETE_ARRAY(heap); 00081 } 00082 00088 void put(_type element){ 00089 if ( _size>=maxSize ) 00090 _CLTHROWA(CL_ERR_IndexOutOfBounds,"add is out of bounds"); 00091 00092 ++_size; 00093 heap[_size] = element; 00094 upHeap(); 00095 } 00096 00103 bool insert(_type element){ 00104 if(_size < maxSize){ 00105 put(element); 00106 return true; 00107 }else if(_size > 0 && !lessThan(element, top())){ 00108 if ( dk ){ 00109 _valueDeletor::doDelete(heap[1]); 00110 } 00111 heap[1] = element; 00112 adjustTop(); 00113 return true; 00114 }else 00115 return false; 00116 } 00117 00121 _type top(){ 00122 if (_size > 0) 00123 return heap[1]; 00124 else 00125 return NULL; 00126 } 00127 00131 _type pop(){ 00132 if (_size > 0) { 00133 _type result = heap[1]; // save first value 00134 heap[1] = heap[_size]; // move last to first 00135 00136 heap[_size] = (_type)0; // permit GC of objects 00137 --_size; 00138 downHeap(); // adjust heap 00139 return result; 00140 } else 00141 return (_type)NULL; 00142 } 00143 00151 void adjustTop(){ 00152 downHeap(); 00153 } 00154 00155 00159 size_t size(){ 00160 return _size; 00161 } 00162 00166 void clear(){ 00167 for (size_t i = 1; i <= _size; ++i){ 00168 if ( dk ){ 00169 _valueDeletor::doDelete(heap[i]); 00170 } 00171 } 00172 _size = 0; 00173 } 00174 }; 00175 00176 CL_NS_END 00177 #endif