kernel/util: Minor improvements in Heap and MinMaxHeap

* [MinMax]Heap::ModifyKey(): Do not attempt to move node if the key
   actually hasn't changed.
 * Allow allocating initial array at construction.
This commit is contained in:
Pawel Dziepak
2013-10-21 21:24:05 +02:00
parent afe1735d7d
commit 5cf9b69b49
2 changed files with 39 additions and 8 deletions
+17 -4
View File
@@ -75,6 +75,7 @@ template<typename Element, typename Key,
class Heap { class Heap {
public: public:
Heap(); Heap();
Heap(int initialSize);
~Heap(); ~Heap();
inline Element* PeekRoot(); inline Element* PeekRoot();
@@ -87,7 +88,7 @@ public:
inline status_t Insert(Element* element, Key key); inline status_t Insert(Element* element, Key key);
private: private:
status_t _GrowHeap(); status_t _GrowHeap(int minimalSize = 0);
void _MoveUp(HeapLink<Element, Key>* link); void _MoveUp(HeapLink<Element, Key>* link);
void _MoveDown(HeapLink<Element, Key>* link); void _MoveDown(HeapLink<Element, Key>* link);
@@ -167,6 +168,17 @@ HEAP_CLASS_NAME::Heap()
} }
HEAP_TEMPLATE_LIST
HEAP_CLASS_NAME::Heap(int initialSize)
:
fElements(NULL),
fLastElement(0),
fSize(0)
{
_GrowHeap(initialSize);
}
HEAP_TEMPLATE_LIST HEAP_TEMPLATE_LIST
HEAP_CLASS_NAME::~Heap() HEAP_CLASS_NAME::~Heap()
{ {
@@ -204,7 +216,7 @@ HEAP_CLASS_NAME::ModifyKey(Element* element, Key newKey)
if (sCompare(newKey, oldKey)) if (sCompare(newKey, oldKey))
_MoveUp(link); _MoveUp(link);
else else if (sCompare(oldKey, newKey))
_MoveDown(link); _MoveDown(link);
} }
@@ -256,9 +268,10 @@ HEAP_CLASS_NAME::Insert(Element* element, Key key)
HEAP_TEMPLATE_LIST HEAP_TEMPLATE_LIST
status_t status_t
HEAP_CLASS_NAME::_GrowHeap() HEAP_CLASS_NAME::_GrowHeap(int minimalSize)
{ {
int newSize = max_c(fSize * 2, 4); minimalSize = minimalSize % 2 ? minimalSize : minimalSize + 1;
int newSize = max_c(max_c(fSize * 2, 4), minimalSize);
size_t arraySize = newSize * sizeof(Element*); size_t arraySize = newSize * sizeof(Element*);
Element** newBuffer Element** newBuffer
+22 -4
View File
@@ -70,6 +70,7 @@ template<typename Element, typename Key,
class MinMaxHeap { class MinMaxHeap {
public: public:
MinMaxHeap(); MinMaxHeap();
MinMaxHeap(int initialSize);
~MinMaxHeap(); ~MinMaxHeap();
inline Element* PeekMinimum(); inline Element* PeekMinimum();
@@ -84,8 +85,9 @@ public:
inline status_t Insert(Element* element, Key key); inline status_t Insert(Element* element, Key key);
status_t GrowHeap(int minimalSize = 0);
private: private:
status_t _GrowHeap(int minimalSize = 0);
void _MoveUp(MinMaxHeapLink<Element, Key>* link); void _MoveUp(MinMaxHeapLink<Element, Key>* link);
void _MoveDown(MinMaxHeapLink<Element, Key>* link); void _MoveDown(MinMaxHeapLink<Element, Key>* link);
bool _ChangeTree(MinMaxHeapLink<Element, Key>* link); bool _ChangeTree(MinMaxHeapLink<Element, Key>* link);
@@ -166,6 +168,19 @@ MIN_MAX_HEAP_CLASS_NAME::MinMaxHeap()
} }
MIN_MAX_HEAP_TEMPLATE_LIST
MIN_MAX_HEAP_CLASS_NAME::MinMaxHeap(int initialSize)
:
fMinElements(NULL),
fMinLastElement(0),
fMaxElements(NULL),
fMaxLastElement(0),
fSize(0)
{
_GrowHeap(initialSize);
}
MIN_MAX_HEAP_TEMPLATE_LIST MIN_MAX_HEAP_TEMPLATE_LIST
MIN_MAX_HEAP_CLASS_NAME::~MinMaxHeap() MIN_MAX_HEAP_CLASS_NAME::~MinMaxHeap()
{ {
@@ -220,7 +235,10 @@ MIN_MAX_HEAP_CLASS_NAME::ModifyKey(Element* element, Key newKey)
Key oldKey = link->fKey; Key oldKey = link->fKey;
link->fKey = newKey; link->fKey = newKey;
if (sCompare(newKey, oldKey) && link->fMinTree) if (!sCompare(newKey, oldKey) && !sCompare(oldKey, newKey))
return;
if (sCompare(newKey, oldKey) ^ !link->fMinTree)
_MoveUp(link); _MoveUp(link);
else else
_MoveDown(link); _MoveDown(link);
@@ -273,7 +291,7 @@ MIN_MAX_HEAP_CLASS_NAME::Insert(Element* element, Key key)
{ {
if (min_c(fMinLastElement, fMaxLastElement) == fSize) { if (min_c(fMinLastElement, fMaxLastElement) == fSize) {
ASSERT(max_c(fMinLastElement, fMaxLastElement) == fSize); ASSERT(max_c(fMinLastElement, fMaxLastElement) == fSize);
status_t result = GrowHeap(); status_t result = _GrowHeap();
if (result != B_OK) if (result != B_OK)
return result; return result;
} }
@@ -300,7 +318,7 @@ MIN_MAX_HEAP_CLASS_NAME::Insert(Element* element, Key key)
MIN_MAX_HEAP_TEMPLATE_LIST MIN_MAX_HEAP_TEMPLATE_LIST
status_t status_t
MIN_MAX_HEAP_CLASS_NAME::GrowHeap(int minimalSize) MIN_MAX_HEAP_CLASS_NAME::_GrowHeap(int minimalSize)
{ {
minimalSize = minimalSize % 2 ? minimalSize : minimalSize + 1; minimalSize = minimalSize % 2 ? minimalSize : minimalSize + 1;
int newSize = max_c(max_c(fSize * 4, 4), minimalSize); int newSize = max_c(max_c(fSize * 4, 4), minimalSize);