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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user