Fixed bugs.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8803 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ba0b8a97e0
commit
38ded28eee
@ -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_();
|
||||||
|
|
||||||
static void *BSearch(const void *key, const void *start,
|
typedef void *(* GenericEachFunction)(void *, void *);
|
||||||
size_t numItems, size_t size,
|
typedef int (* GenericCompareFunction)(const void *, const void *);
|
||||||
GenericCompareFunction compareFunc);
|
typedef int (* GenericCompareFunctionWithState)(const void *, const void *,
|
||||||
|
void *);
|
||||||
|
typedef int (* UnaryPredicateGlue)(const void *, void *);
|
||||||
|
|
||||||
static void *BSearchWithState(const void *key, const void *start,
|
void *EachElement(GenericEachFunction, void *);
|
||||||
size_t numItems, size_t size,
|
void SortItems(GenericCompareFunction);
|
||||||
GenericCompareFunctionWithState compareFunc, void *state);
|
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
|
||||||
|
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
|
||||||
|
static void *BinarySearch(const void *key, const void **items,
|
||||||
|
int32 numItems,
|
||||||
|
_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;
|
||||||
int low;
|
index = 0;
|
||||||
int high;
|
while (low <= high) {
|
||||||
int result;
|
index = (low + high) / 2;
|
||||||
size_t i;
|
const void* item = items[index];
|
||||||
for (low = -1, high = numItems; high - low > 1;) {
|
result = compareFunc(key, item);
|
||||||
i = (high + low) >> 1;
|
if (result < 0) {
|
||||||
p = (void *)(base + (i * size));
|
high = index - 1;
|
||||||
|
} else if (result > 0) {
|
||||||
result = compareFunc(key, *(void **)p);
|
low = index + 1;
|
||||||
if (result == 0)
|
} else {
|
||||||
break;
|
return (void*)item;
|
||||||
else if (result < 0)
|
}
|
||||||
high = i;
|
}
|
||||||
else
|
|
||||||
low = i;
|
if (result > 0) {
|
||||||
}
|
index ++;
|
||||||
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user