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 {
public:
Heap();
Heap(int initialSize);
~Heap();
inline Element* PeekRoot();
@@ -87,7 +88,7 @@ public:
inline status_t Insert(Element* element, Key key);
private:
status_t _GrowHeap();
status_t _GrowHeap(int minimalSize = 0);
void _MoveUp(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_CLASS_NAME::~Heap()
{
@@ -204,7 +216,7 @@ HEAP_CLASS_NAME::ModifyKey(Element* element, Key newKey)
if (sCompare(newKey, oldKey))
_MoveUp(link);
else
else if (sCompare(oldKey, newKey))
_MoveDown(link);
}
@@ -256,9 +268,10 @@ HEAP_CLASS_NAME::Insert(Element* element, Key key)
HEAP_TEMPLATE_LIST
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*);
Element** newBuffer
+22 -4
View File
@@ -70,6 +70,7 @@ template<typename Element, typename Key,
class MinMaxHeap {
public:
MinMaxHeap();
MinMaxHeap(int initialSize);
~MinMaxHeap();
inline Element* PeekMinimum();
@@ -84,8 +85,9 @@ public:
inline status_t Insert(Element* element, Key key);
status_t GrowHeap(int minimalSize = 0);
private:
status_t _GrowHeap(int minimalSize = 0);
void _MoveUp(MinMaxHeapLink<Element, Key>* link);
void _MoveDown(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_CLASS_NAME::~MinMaxHeap()
{
@@ -220,7 +235,10 @@ MIN_MAX_HEAP_CLASS_NAME::ModifyKey(Element* element, Key newKey)
Key oldKey = link->fKey;
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);
else
_MoveDown(link);
@@ -273,7 +291,7 @@ MIN_MAX_HEAP_CLASS_NAME::Insert(Element* element, Key key)
{
if (min_c(fMinLastElement, fMaxLastElement) == fSize) {
ASSERT(max_c(fMinLastElement, fMaxLastElement) == fSize);
status_t result = GrowHeap();
status_t result = _GrowHeap();
if (result != B_OK)
return result;
}
@@ -300,7 +318,7 @@ MIN_MAX_HEAP_CLASS_NAME::Insert(Element* element, Key key)
MIN_MAX_HEAP_TEMPLATE_LIST
status_t
MIN_MAX_HEAP_CLASS_NAME::GrowHeap(int minimalSize)
MIN_MAX_HEAP_CLASS_NAME::_GrowHeap(int minimalSize)
{
minimalSize = minimalSize % 2 ? minimalSize : minimalSize + 1;
int newSize = max_c(max_c(fSize * 4, 4), minimalSize);