* Removed the non-STL version of the code.
* Removed the _PointerList_ definition -- instead include <ObjectList.h>. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30291 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e55653ec19
commit
113a493073
|
@ -16,59 +16,25 @@
|
||||||
|
|
||||||
// Note: Method Owning() is inlined in header file ObjectList.h
|
// Note: Method Owning() is inlined in header file ObjectList.h
|
||||||
|
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// If USE_STL is 1 binary search and sort are used from STL.
|
|
||||||
// The implementation of _PointerList_ should be completely rewritten to
|
// TODO: The implementation of _PointerList_ should be completely rewritten to
|
||||||
// use STL in a more efficent way!
|
// use STL in a more efficent way!
|
||||||
#define USE_STL 1
|
|
||||||
|
|
||||||
// Declaration of class _PointerList_ is inlined to be independent of the
|
|
||||||
// header file ObjectList.h
|
|
||||||
|
|
||||||
#ifndef __OBJECT_LIST__
|
|
||||||
class _PointerList_ : public BList {
|
|
||||||
public:
|
|
||||||
_PointerList_(const _PointerList_ &list);
|
|
||||||
_PointerList_(int32 itemsPerBlock = 20, bool owning = false);
|
|
||||||
~_PointerList_();
|
|
||||||
|
|
||||||
typedef void *(* GenericEachFunction)(void *item, void *arg);
|
|
||||||
typedef int (* GenericCompareFunction)(const void *key, const void *item);
|
|
||||||
typedef int (* GenericCompareFunctionWithState)(const void *key, const void *item,
|
|
||||||
void *state);
|
|
||||||
typedef int (* UnaryPredicateGlue)(const void *item, void *key);
|
|
||||||
|
|
||||||
void *EachElement(GenericEachFunction, void *arg);
|
|
||||||
void SortItems(GenericCompareFunction);
|
|
||||||
void SortItems(GenericCompareFunctionWithState, void *state);
|
|
||||||
void HSortItems(GenericCompareFunction);
|
|
||||||
void HSortItems(GenericCompareFunctionWithState, void *state);
|
|
||||||
|
|
||||||
void *BinarySearch(const void *key, GenericCompareFunction) const;
|
|
||||||
void *BinarySearch(const void *key, GenericCompareFunctionWithState, void *state) const;
|
|
||||||
|
|
||||||
int32 BinarySearchIndex(const void *key, GenericCompareFunction) const;
|
|
||||||
int32 BinarySearchIndex(const void *key, GenericCompareFunctionWithState, void *state) const;
|
|
||||||
int32 BinarySearchIndexByPredicate(const void *arg, UnaryPredicateGlue) const;
|
|
||||||
|
|
||||||
bool Owning() const;
|
|
||||||
bool ReplaceItem(int32, void *);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool owning;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct comparator;
|
struct comparator;
|
||||||
|
|
||||||
|
|
||||||
class AbstractPointerListHelper {
|
class AbstractPointerListHelper {
|
||||||
public:
|
public:
|
||||||
AbstractPointerListHelper() {};
|
AbstractPointerListHelper() {};
|
||||||
|
@ -95,9 +61,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void HSortItems(BList *list);
|
void HSortItems(BList *list);
|
||||||
|
|
||||||
#if USE_STL
|
|
||||||
friend struct comparator;
|
friend struct comparator;
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
|
@ -113,19 +77,12 @@ private:
|
||||||
inline void Swap(void **items, int32 i, int32 j);
|
inline void Swap(void **items, int32 i, int32 j);
|
||||||
|
|
||||||
void* BinarySearch(const void *key, const void **items, int32 numItems, int32 &index);
|
void* BinarySearch(const void *key, const void **items, int32 numItems, int32 &index);
|
||||||
#if !USE_STL
|
|
||||||
void InsertionSort(void **items, int32 numItems);
|
|
||||||
inline void InsertionSort(void **items, int32 low, int32 high);
|
|
||||||
int32 ChoosePivot(void **items, int32 low, int32 high);
|
|
||||||
int32 Partition(void **items, int32 low, int32 high, bool &isSorted);
|
|
||||||
#endif
|
|
||||||
void QuickSort(void **items, int32 low, int32 high);
|
void QuickSort(void **items, int32 low, int32 high);
|
||||||
|
|
||||||
// Method to be implemented by sub classes
|
// Method to be implemented by sub classes
|
||||||
int virtual Compare(const void *key, const void* item) = 0;
|
int virtual Compare(const void *key, const void* item) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if USE_STL
|
|
||||||
struct comparator : public binary_function<const void*, const void*, bool>
|
struct comparator : public binary_function<const void*, const void*, bool>
|
||||||
{
|
{
|
||||||
comparator(AbstractPointerListHelper* helper) : helper(helper) {}
|
comparator(AbstractPointerListHelper* helper) : helper(helper) {}
|
||||||
|
@ -136,7 +93,6 @@ struct comparator : public binary_function<const void*, const void*, bool>
|
||||||
|
|
||||||
AbstractPointerListHelper* helper;
|
AbstractPointerListHelper* helper;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
AbstractPointerListHelper::~AbstractPointerListHelper()
|
AbstractPointerListHelper::~AbstractPointerListHelper()
|
||||||
|
@ -197,7 +153,6 @@ AbstractPointerListHelper::HSortItems(BList *list)
|
||||||
void *
|
void *
|
||||||
AbstractPointerListHelper::BinarySearch(const void *key, const void **items, int32 numItems, int32 &index)
|
AbstractPointerListHelper::BinarySearch(const void *key, const void **items, int32 numItems, int32 &index)
|
||||||
{
|
{
|
||||||
#if USE_STL
|
|
||||||
const void** end = &items[numItems];
|
const void** end = &items[numItems];
|
||||||
const void** found = lower_bound(items, end, key, comparator(this));
|
const void** found = lower_bound(items, end, key, comparator(this));
|
||||||
index = found - items;
|
index = found - items;
|
||||||
|
@ -207,193 +162,15 @@ AbstractPointerListHelper::BinarySearch(const void *key, const void **items, int
|
||||||
index = -(index + 1);
|
index = -(index + 1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
int32 low = 0;
|
|
||||||
int32 high = numItems-1;
|
|
||||||
int result = 0;
|
|
||||||
index = 0;
|
|
||||||
|
|
||||||
while (low <= high) {
|
|
||||||
index = (low + high) / 2;
|
|
||||||
const void *item = items[index];
|
|
||||||
result = Compare(key, item);
|
|
||||||
if (result < 0) {
|
|
||||||
// key < item
|
|
||||||
high = index - 1;
|
|
||||||
} else if (result > 0) {
|
|
||||||
// key > item
|
|
||||||
low = index + 1;
|
|
||||||
} else {
|
|
||||||
// key == item
|
|
||||||
return const_cast<void *>(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// item not found
|
|
||||||
if (result > 0) {
|
|
||||||
// key > last item (= items[index])
|
|
||||||
// insert position for key is after last item
|
|
||||||
index ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = -(index+1);
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !USE_STL
|
|
||||||
int32
|
|
||||||
AbstractPointerListHelper::ChoosePivot(void **items, int32 low, int32 high)
|
|
||||||
{
|
|
||||||
if (kPivotThreshold <= kQuickSortThreshold
|
|
||||||
|| high - low > kPivotThreshold) {
|
|
||||||
assert(high - low > kPivotThreshold);
|
|
||||||
// choose the middle item of three items
|
|
||||||
int32 mid = (low + high) / 2;
|
|
||||||
|
|
||||||
void* first = items[low];
|
|
||||||
void* middle = items[mid];
|
|
||||||
void* last = items[high];
|
|
||||||
|
|
||||||
if (Compare(first, middle) <= 0) {
|
|
||||||
// first <= middle
|
|
||||||
if (Compare(middle, last) <= 0) {
|
|
||||||
// first <= middle <= last
|
|
||||||
return mid;
|
|
||||||
}
|
|
||||||
// first <= middle and last < middle
|
|
||||||
if (Compare(first, last) <= 0) {
|
|
||||||
// first <= last < middle
|
|
||||||
return high;
|
|
||||||
}
|
|
||||||
// last < first <= middle
|
|
||||||
return low;
|
|
||||||
}
|
|
||||||
// middle < first
|
|
||||||
if (Compare(first, last) <= 0) {
|
|
||||||
// middle < first <= last
|
|
||||||
return low;
|
|
||||||
}
|
|
||||||
// middle < first and last < first
|
|
||||||
if (Compare(middle, last) <= 0) {
|
|
||||||
// middle <= last < first
|
|
||||||
return high;
|
|
||||||
}
|
|
||||||
// last < middle < first
|
|
||||||
return mid;
|
|
||||||
} else {
|
|
||||||
// choose the middle element to avoid O(n^2) for an already sorted list
|
|
||||||
return (low + high) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int32
|
|
||||||
AbstractPointerListHelper::Partition(void **items, int32 low, int32 high, bool &isSorted)
|
|
||||||
{
|
|
||||||
assert(low < high);
|
|
||||||
int32 left = low;
|
|
||||||
int32 right = high;
|
|
||||||
int32 pivot = ChoosePivot(items, low, high);
|
|
||||||
void *pivotItem = items[pivot];
|
|
||||||
|
|
||||||
// Optimization: Check if all items are equal. We get this almost for free.
|
|
||||||
// Searching the first item that does not belong to the left list has to
|
|
||||||
// be done anyway.
|
|
||||||
int32 result;
|
|
||||||
isSorted = true;
|
|
||||||
// Search first item in left part that does not belong to this part
|
|
||||||
// (where item > pivotItem)
|
|
||||||
while (left < right && (result = Compare(items[left], pivotItem)) <= 0) {
|
|
||||||
left ++;
|
|
||||||
if (result != 0) {
|
|
||||||
isSorted = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isSorted && left == right && Compare(items[right], pivotItem) == 0) {
|
|
||||||
return low;
|
|
||||||
}
|
|
||||||
// End of optimization
|
|
||||||
isSorted = false;
|
|
||||||
|
|
||||||
// pivot element has to be first element in list
|
|
||||||
if (low != pivot)
|
|
||||||
Swap(items, low, pivot);
|
|
||||||
|
|
||||||
// now partion the array in a left part where item <= pivotItem
|
|
||||||
// and a right part where item > pivotItem
|
|
||||||
do {
|
|
||||||
// search first item in left part that does not belong to this part
|
|
||||||
// (where item > pivotItem)
|
|
||||||
while (left < right && Compare(items[left], pivotItem) <= 0) {
|
|
||||||
left ++;
|
|
||||||
}
|
|
||||||
// search first item (from right to left) in right part that does not belong
|
|
||||||
// to this part (where item <= pivotItem). This holds at least for pivot
|
|
||||||
// element at top of list! No array bounds check needed!
|
|
||||||
while (Compare(items[right], pivotItem) > 0) {
|
|
||||||
right --;
|
|
||||||
}
|
|
||||||
if (left < right) {
|
|
||||||
// now swap the items to the proper part
|
|
||||||
Swap(items, left, right);
|
|
||||||
}
|
|
||||||
} while (left < right);
|
|
||||||
// place pivotItem between left and right part
|
|
||||||
items[low] = items[right];
|
|
||||||
items[right] = pivotItem;
|
|
||||||
return right;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractPointerListHelper::InsertionSort(void **items, int32 numItems)
|
|
||||||
{
|
|
||||||
for (int32 i = 1; i < numItems; i ++) {
|
|
||||||
// treat list[0 .. i-1] as sorted
|
|
||||||
void* item = items[i];
|
|
||||||
// insert item at right place in list[0..i]
|
|
||||||
int32 j = i;
|
|
||||||
void* prev = items[j-1];
|
|
||||||
while (Compare(prev, item) > 0) {
|
|
||||||
items[j] = prev;
|
|
||||||
j --;
|
|
||||||
if (j <= 0) break;
|
|
||||||
prev = items[j-1];
|
|
||||||
}
|
|
||||||
items[j] = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractPointerListHelper::InsertionSort(void **items, int32 low, int32 high)
|
|
||||||
{
|
|
||||||
InsertionSort(&items[low], high - low + 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AbstractPointerListHelper::QuickSort(void **items, int32 low, int32 high)
|
AbstractPointerListHelper::QuickSort(void **items, int32 low, int32 high)
|
||||||
{
|
{
|
||||||
#if USE_STL
|
|
||||||
if (low <= high) {
|
if (low <= high) {
|
||||||
sort(&items[low], &items[high+1], comparator(this));
|
sort(&items[low], &items[high+1], comparator(this));
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (low < high) {
|
|
||||||
if (high - low < kQuickSortThreshold) {
|
|
||||||
InsertionSort(items, low, high);
|
|
||||||
} else {
|
|
||||||
bool isSorted;
|
|
||||||
int pivot = Partition(items, low, high, isSorted);
|
|
||||||
if (isSorted) return;
|
|
||||||
|
|
||||||
QuickSort(items, low, pivot - 1);
|
|
||||||
QuickSort(items, pivot + 1, high);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue