From 8a9423ee95f61b613cfe961e1a5cbbf54d558bfc Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 27 Apr 2013 13:57:00 -0400 Subject: [PATCH] Add RangeList utility class. - Tracks a set of ranges. Implicitly deals with collapsing overlapping ranges as they're added. --- src/apps/debugger/Jamfile | 1 + src/apps/debugger/util/RangeList.cpp | 142 +++++++++++++++++++++++++++ src/apps/debugger/util/RangeList.h | 55 +++++++++++ 3 files changed, 198 insertions(+) create mode 100644 src/apps/debugger/util/RangeList.cpp create mode 100644 src/apps/debugger/util/RangeList.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 6f90e1b418..caa8f1caef 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -266,6 +266,7 @@ Application Debugger : ArchivingUtils.cpp BitBuffer.cpp IntegerFormatter.cpp + RangeList.cpp StringUtils.cpp Worker.cpp diff --git a/src/apps/debugger/util/RangeList.cpp b/src/apps/debugger/util/RangeList.cpp new file mode 100644 index 0000000000..8ab7f80bac --- /dev/null +++ b/src/apps/debugger/util/RangeList.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "RangeList.h" + +#include + + +RangeList::RangeList() + : BObjectList(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 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; + } + } +} diff --git a/src/apps/debugger/util/RangeList.h b/src/apps/debugger/util/RangeList.h new file mode 100644 index 0000000000..b37fc1ba50 --- /dev/null +++ b/src/apps/debugger/util/RangeList.h @@ -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 +#include + + +struct Range { + int32 lowerBound; + int32 upperBound; + + Range() + : + lowerBound(-1), + upperBound(-1) + { + } + + Range(int32 lowValue, int32 highValue) + : + lowerBound(lowValue), + upperBound(highValue) + { + } +}; + + +class RangeList : private BObjectList +{ +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