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