diff --git a/src/kits/support/PointerList.cpp b/src/kits/support/PointerList.cpp index 44ead0ac6a..177eb266b8 100644 --- a/src/kits/support/PointerList.cpp +++ b/src/kits/support/PointerList.cpp @@ -16,59 +16,25 @@ // Note: Method Owning() is inlined in header file ObjectList.h +#include + +#include + #include #include -#include #include + 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! -#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; + class AbstractPointerListHelper { public: AbstractPointerListHelper() {}; @@ -95,9 +61,7 @@ public: */ void HSortItems(BList *list); -#if USE_STL friend struct comparator; -#endif private: enum { @@ -113,19 +77,12 @@ private: inline void Swap(void **items, int32 i, int32 j); 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); // Method to be implemented by sub classes int virtual Compare(const void *key, const void* item) = 0; }; -#if USE_STL struct comparator : public binary_function { comparator(AbstractPointerListHelper* helper) : helper(helper) {} @@ -136,7 +93,6 @@ struct comparator : public binary_function AbstractPointerListHelper* helper; }; -#endif AbstractPointerListHelper::~AbstractPointerListHelper() @@ -197,7 +153,6 @@ AbstractPointerListHelper::HSortItems(BList *list) void * AbstractPointerListHelper::BinarySearch(const void *key, const void **items, int32 numItems, int32 &index) { -#if USE_STL const void** end = &items[numItems]; const void** found = lower_bound(items, end, key, comparator(this)); index = found - items; @@ -207,193 +162,15 @@ AbstractPointerListHelper::BinarySearch(const void *key, const void **items, int index = -(index + 1); 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(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 AbstractPointerListHelper::QuickSort(void **items, int32 low, int32 high) { -#if USE_STL if (low <= high) { 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 }