Add RangeList utility class.
- Tracks a set of ranges. Implicitly deals with collapsing overlapping ranges as they're added.
This commit is contained in:
parent
b11fd75b4b
commit
8a9423ee95
@ -266,6 +266,7 @@ Application Debugger :
|
||||
ArchivingUtils.cpp
|
||||
BitBuffer.cpp
|
||||
IntegerFormatter.cpp
|
||||
RangeList.cpp
|
||||
StringUtils.cpp
|
||||
Worker.cpp
|
||||
|
||||
|
142
src/apps/debugger/util/RangeList.cpp
Normal file
142
src/apps/debugger/util/RangeList.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "RangeList.h"
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
|
||||
RangeList::RangeList()
|
||||
: BObjectList<Range>(20, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RangeList::~RangeList()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RangeList::AddRange(int32 lowValue, int32 highValue)
|
||||
{
|
||||
if (lowValue > highValue)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
int32 i = 0;
|
||||
if (CountItems() != 0) {
|
||||
for (; i < CountItems(); i++) {
|
||||
Range* range = ItemAt(i);
|
||||
if (lowValue < range->lowerBound) {
|
||||
if (highValue < range->lowerBound) {
|
||||
// the new range is completely below the bounds
|
||||
// of the ranges we currently contain,
|
||||
// insert it here.
|
||||
break;
|
||||
} else if (highValue <= range->upperBound) {
|
||||
// the new range partly overlaps the lower
|
||||
// current range
|
||||
range->lowerBound = lowValue;
|
||||
return B_OK;
|
||||
} else {
|
||||
// the new range completely encompasses
|
||||
// the current range
|
||||
range->lowerBound = lowValue;
|
||||
range->upperBound = highValue;
|
||||
_CollapseOverlappingRanges(i +1, highValue);
|
||||
}
|
||||
|
||||
} else if (lowValue < range->upperBound) {
|
||||
if (highValue <= range->upperBound) {
|
||||
// the requested range is already completely contained
|
||||
// within our existing range list
|
||||
return B_OK;
|
||||
} else {
|
||||
range->upperBound = highValue;
|
||||
_CollapseOverlappingRanges(i + 1, highValue);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Range* range = new(std::nothrow) Range(lowValue, highValue);
|
||||
if (range == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
BPrivate::ObjectDeleter<Range> rangeDeleter(range);
|
||||
if (!AddItem(range, i))
|
||||
return B_NO_MEMORY;
|
||||
|
||||
rangeDeleter.Detach();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RangeList::AddRange(const Range& range)
|
||||
{
|
||||
return AddRange(range.lowerBound, range.upperBound);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RangeList::RemoveRangeAt(int32 index)
|
||||
{
|
||||
if (index < 0 || index >= CountItems())
|
||||
return;
|
||||
|
||||
RemoveItem(ItemAt(index));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RangeList::Contains(int32 value) const
|
||||
{
|
||||
for (int32 i = 0; i < CountItems(); i++) {
|
||||
const Range* range = ItemAt(i);
|
||||
if (value < range->lowerBound || value > range->upperBound)
|
||||
break;
|
||||
else if (value >= range->lowerBound && value <= range->upperBound)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
RangeList::CountRanges() const
|
||||
{
|
||||
return CountItems();
|
||||
}
|
||||
|
||||
|
||||
const Range*
|
||||
RangeList::RangeAt(int32 index) const
|
||||
{
|
||||
return ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RangeList::_CollapseOverlappingRanges(int32 startIndex, int32 highValue)
|
||||
{
|
||||
for (int32 i = startIndex; i < CountItems();) {
|
||||
// check if it also overlaps any of the following
|
||||
// ranges.
|
||||
Range* nextRange = ItemAt(i);
|
||||
if (nextRange->lowerBound > highValue)
|
||||
return;
|
||||
else if (nextRange->upperBound < highValue) {
|
||||
RemoveItem(nextRange);
|
||||
continue;
|
||||
} else {
|
||||
nextRange->lowerBound = highValue + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
55
src/apps/debugger/util/RangeList.h
Normal file
55
src/apps/debugger/util/RangeList.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef RANGE_LIST_H
|
||||
#define RANGE_LIST_H
|
||||
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
struct Range {
|
||||
int32 lowerBound;
|
||||
int32 upperBound;
|
||||
|
||||
Range()
|
||||
:
|
||||
lowerBound(-1),
|
||||
upperBound(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Range(int32 lowValue, int32 highValue)
|
||||
:
|
||||
lowerBound(lowValue),
|
||||
upperBound(highValue)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class RangeList : private BObjectList<Range>
|
||||
{
|
||||
public:
|
||||
RangeList();
|
||||
virtual ~RangeList();
|
||||
|
||||
|
||||
status_t AddRange(int32 lowValue, int32 highValue);
|
||||
status_t AddRange(const Range& range);
|
||||
|
||||
void RemoveRangeAt(int32 index);
|
||||
|
||||
int32 CountRanges() const;
|
||||
const Range* RangeAt(int32 index) const;
|
||||
|
||||
bool Contains(int32 value) const;
|
||||
|
||||
private:
|
||||
void _CollapseOverlappingRanges(int32 startIndex,
|
||||
int32 highValue);
|
||||
};
|
||||
|
||||
#endif // RANGE_LIST_H
|
Loading…
Reference in New Issue
Block a user