Fixed bugs.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8803 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Pfeiffer 2004-09-02 20:29:30 +00:00
parent ba0b8a97e0
commit 38ded28eee
1 changed files with 159 additions and 100 deletions

View File

@ -1,32 +1,73 @@
/* /*
** Copyright 2003-2004, Stefano Ceccherini (burton666@libero.it). All rights reserved. ** Copyright 2003-2004, Stefano Ceccherini (burton666@libero.it). All rights reserved.
** 2004, Michael Pfeiffer (laplace@users.sourceforge.net).
** Distributed under the terms of the OpenBeOS License. ** Distributed under the terms of the OpenBeOS License.
**
** History
** 2003-2004 Initial implementation by Stefano Ceccerini.
** 2004/08/03 Testing, bug fixing and implementation of quick sort by Michael Pfeiffer.
*/ */
// TODO: we need to include this as _PointerList_ is declared there. // TODO: Implement quick sort
// I wonder if we should add a PointerList.h file, then ObjectList.h would contain
// a copy of the declaration
#include <ObjectList.h>
#include <stdlib.h> // Note: Method Owning() is inlined in header file ObjectList.h
// TODO: I used bubble sort, which is notably the slowest possible sorting algorithm #include <List.h>
// Why ? Laziness. Fix that!
// Test the class.
typedef int (* GenericCompareFunction)(const void *, const void *); // Declaration of class _PointerList_ is inlined to be independet of the
typedef int (* GenericCompareFunctionWithState)(const void *, const void *, void *); // 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 *, void *);
typedef int (* GenericCompareFunction)(const void *, const void *);
typedef int (* GenericCompareFunctionWithState)(const void *, const void *,
void *);
typedef int (* UnaryPredicateGlue)(const void *, void *);
void *EachElement(GenericEachFunction, void *);
void SortItems(GenericCompareFunction);
void SortItems(GenericCompareFunctionWithState, void *state);
void HSortItems(GenericCompareFunction);
void HSortItems(GenericCompareFunctionWithState, void *state);
void *BinarySearch(const void *, GenericCompareFunction) const;
void *BinarySearch(const void *, GenericCompareFunctionWithState, void *state) const;
int32 BinarySearchIndex(const void *, GenericCompareFunction) const;
int32 BinarySearchIndex(const void *, GenericCompareFunctionWithState, void *state) const;
int32 BinarySearchIndexByPredicate(const void *, UnaryPredicateGlue) const;
bool Owning() const;
bool ReplaceItem(int32, void *);
protected:
bool owning;
};
#endif
static void *BSearch(const void *key, const void *start, // Forward declarations
size_t numItems, size_t size,
GenericCompareFunction compareFunc);
static void *BSearchWithState(const void *key, const void *start, static void *BinarySearch(const void *key, const void **items,
size_t numItems, size_t size, int32 numItems,
GenericCompareFunctionWithState compareFunc, void *state); _PointerList_::GenericCompareFunction compareFunc,
int32& index);
static void *BinarySearch(const void *key, const void **items,
int32 numItems,
_PointerList_::GenericCompareFunctionWithState compareFunc, void *state,
int32& index);
// Implementation of class _PointerList_
_PointerList_::_PointerList_(int32 itemsPerBlock, bool own) _PointerList_::_PointerList_(int32 itemsPerBlock, bool own)
: :
@ -72,6 +113,7 @@ _PointerList_::EachElement(GenericEachFunction function, void *arg)
void void
_PointerList_::SortItems(GenericCompareFunction compareFunc) _PointerList_::SortItems(GenericCompareFunction compareFunc)
{ {
if (compareFunc) { if (compareFunc) {
int32 numItems = CountItems(); int32 numItems = CountItems();
if (numItems > 1) { if (numItems > 1) {
@ -85,7 +127,6 @@ _PointerList_::SortItems(GenericCompareFunction compareFunc)
} }
} }
} }
} }
} }
} }
@ -107,7 +148,6 @@ _PointerList_::SortItems(GenericCompareFunctionWithState compareFunc, void *stat
} }
} }
} }
} }
} }
} }
@ -116,23 +156,42 @@ _PointerList_::SortItems(GenericCompareFunctionWithState compareFunc, void *stat
void void
_PointerList_::HSortItems(GenericCompareFunction sortFunction) _PointerList_::HSortItems(GenericCompareFunction sortFunction)
{ {
//TODO: Does "H" stand for "Heap" ? Should we use Heap Sort here ? const bool hasItems = !IsEmpty();
void* firstItem = NULL;
if (hasItems) {
// append first item after sorting the list
firstItem = ItemAt(0);
RemoveItem((int32)0);
}
SortItems(sortFunction); SortItems(sortFunction);
if (hasItems) {
AddItem(firstItem);
}
} }
void void
_PointerList_::HSortItems(GenericCompareFunctionWithState sortFunc, void *state) _PointerList_::HSortItems(GenericCompareFunctionWithState sortFunc, void *state)
{ {
//TODO: Same as above const bool hasItems = !IsEmpty();
void* firstItem = NULL;
if (hasItems) {
// append first item after sorting the list
firstItem = ItemAt(0);
RemoveItem((int32)0);
}
SortItems(sortFunc, state); SortItems(sortFunc, state);
if (hasItems) {
AddItem(firstItem);
}
} }
void * void *
_PointerList_::BinarySearch(const void *key, GenericCompareFunction compareFunc) const _PointerList_::BinarySearch(const void *key, GenericCompareFunction compareFunc) const
{ {
return BSearch(key, Items(), CountItems(), sizeof(void *), compareFunc); int32 index;
return ::BinarySearch(key, (const void **)Items(), CountItems(), compareFunc, index);
} }
@ -140,19 +199,17 @@ void *
_PointerList_::BinarySearch(const void *key, _PointerList_::BinarySearch(const void *key,
GenericCompareFunctionWithState compareFunc, void *state) const GenericCompareFunctionWithState compareFunc, void *state) const
{ {
return BSearchWithState(key, Items(), CountItems(), sizeof(void *), compareFunc, state); int32 index;
return ::BinarySearch(key, (const void**)Items(), CountItems(), compareFunc, state, index);
} }
int32 int32
_PointerList_::BinarySearchIndex(const void *key, GenericCompareFunction compareFunc) const _PointerList_::BinarySearchIndex(const void *key, GenericCompareFunction compareFunc) const
{ {
void *item = BSearch(key, Items(), CountItems(), sizeof(void *), compareFunc); int32 index;
::BinarySearch(key, (const void**)Items(), CountItems(), compareFunc, index);
if (item) return index;
return IndexOf(item);
return -1;
} }
@ -160,30 +217,39 @@ int32
_PointerList_::BinarySearchIndex(const void *key, _PointerList_::BinarySearchIndex(const void *key,
GenericCompareFunctionWithState compareFunc, void *state) const GenericCompareFunctionWithState compareFunc, void *state) const
{ {
void *item = BSearchWithState(key, Items(), CountItems(), int32 index;
sizeof(void *), compareFunc, state); ::BinarySearch(key, (const void**)Items(), CountItems(), compareFunc, state, index);
return index;
if (item)
return IndexOf(item);
return -1;
} }
int32 int32
_PointerList_::BinarySearchIndexByPredicate(const void *key, UnaryPredicateGlue predicate) const _PointerList_::BinarySearchIndexByPredicate(const void *key, UnaryPredicateGlue predicate) const
{ {
int32 numItems = CountItems(); void** items = (void**)Items();
int32 result = -1; int32 low = 0;
for (int32 index = 0; index < numItems; index++) { int32 high = CountItems()-1;
result = predicate(ItemAtFast(index), (void *)key); int result = 0;
if (result) int index = 0;
break; while (low <= high) {
index = (low + high) / 2;
const void* item = items[index];
result = predicate(item, (void*)key);
if (result > 0) {
high = index - 1;
} else if (result < 0) {
low = index + 1;
} else {
return index;
}
} }
return result; if (result < 0) {
} index ++;
}
return -(index+1);
}
bool bool
_PointerList_::ReplaceItem(int32 index, void *newItem) _PointerList_::ReplaceItem(int32 index, void *newItem)
@ -197,67 +263,60 @@ _PointerList_::ReplaceItem(int32 index, void *newItem)
return true; return true;
} }
// Implementation of static functions
static void * static void * BinarySearch(const void* key, const void** items, int32 numItems,
BSearch(const void *key, const void *start, _PointerList_::GenericCompareFunction compareFunc, int32& index)
size_t numItems, size_t size,
GenericCompareFunction compareFunc)
{ {
const char *base = (const char *)start; int32 low = 0;
const void *p; int32 high = numItems-1;
int result = 0;
index = 0;
while (low <= high) {
index = (low + high) / 2;
const void* item = items[index];
result = compareFunc(key, item);
if (result < 0) {
high = index - 1;
} else if (result > 0) {
low = index + 1;
} else {
return (void*)item;
}
}
int low; if (result > 0) {
int high; index ++;
int result; }
size_t i;
for (low = -1, high = numItems; high - low > 1;) {
i = (high + low) >> 1;
p = (void *)(base + (i * size));
result = compareFunc(key, *(void **)p);
if (result == 0)
break;
else if (result < 0)
high = i;
else
low = i;
}
if (result == 0)
return *(void **)p;
index = -(index+1);
return NULL; return NULL;
} }
static void * BinarySearch(const void* key, const void** items, int32 numItems,
static void * _PointerList_::GenericCompareFunctionWithState compareFunc, void* state, int32& index)
BSearchWithState(const void *key, const void *start,
size_t numItems, size_t size,
GenericCompareFunctionWithState compareFunc, void *state)
{ {
const char *base = (const char *)start; int32 low = 0;
const void *p; int32 high = numItems-1;
int result = 0;
index = 0;
while (low <= high) {
index = (low + high) / 2;
const void* item = items[index];
result = compareFunc(key, item, state);
if (result < 0) {
high = index - 1;
} else if (result > 0) {
low = index + 1;
} else {
return (void*)item;
}
}
int low; if (result > 0) {
int high; index ++;
int result; }
size_t i;
for (low = -1, high = numItems; high - low > 1;) {
i = (high + low) >> 1;
p = (void *)(base + (i * size));
result = compareFunc(key, *(void **)p, state);
if (result == 0)
break;
else if (result < 0)
high = i;
else
low = i;
}
if (result == 0)
return *(void **)p;
index = -(index+1);
return NULL; return NULL;
} }