9#ifndef LLDB_UTILITY_RANGEMAP_H
10#define LLDB_UTILITY_RANGEMAP_H
15#include "llvm/ADT/SmallVector.h"
29template <
typename B,
typename S>
struct Range {
112 bool result = (lhs_base <= rhs_end) && (lhs_end >= rhs_base);
136template <
typename B,
typename S,
unsigned N = 0>
class RangeVector {
149#ifdef ASSERT_RANGEMAP_ARE_SORTED
150 assert(vec1.IsSorted() && vec2.IsSorted());
153 auto pos1 = vec1.
begin();
154 auto end1 = vec1.
end();
155 auto pos2 = vec2.
begin();
156 auto end2 = vec2.
end();
157 while (pos1 != end1 && pos2 != end2) {
161 if (pos1->GetRangeEnd() < pos2->GetRangeEnd())
172 for (
size_t i = 0; i <
GetSize(); ++i) {
192 auto pos = std::lower_bound(
begin,
end, entry);
194 if (pos !=
end && pos->Union(entry)) {
200 if (prev->Union(entry)) {
222#ifdef ASSERT_RANGEMAP_ARE_SORTED
223 bool IsSorted()
const {
224 typename Collection::const_iterator pos,
end, prev;
229 if (prev !=
end && *pos < *prev)
237#ifdef ASSERT_RANGEMAP_ARE_SORTED
240 auto first_intersect = std::adjacent_find(
242 return a.DoesAdjoinOrIntersect(b);
249 auto pos = std::next(first_intersect);
252 Entry &back = minimal_ranges.back();
256 minimal_ranges.push_back(*pos);
262#ifdef ASSERT_RANGEMAP_ARE_SORTED
273#ifdef ASSERT_RANGEMAP_ARE_SORTED
284 typename Collection::iterator pos,
end;
317#ifdef ASSERT_RANGEMAP_ARE_SORTED
321 Entry entry(addr, 1);
323 typename Collection::const_iterator
end =
m_entries.end();
324 typename Collection::const_iterator pos =
327 if (pos !=
end && pos->Contains(addr)) {
328 return std::distance(
begin, pos);
329 }
else if (pos !=
begin) {
331 if (pos->Contains(addr))
332 return std::distance(
begin, pos);
339#ifdef ASSERT_RANGEMAP_ARE_SORTED
343 Entry entry(addr, 1);
345 typename Collection::const_iterator
end =
m_entries.end();
346 typename Collection::const_iterator pos =
349 if (pos !=
end && pos->Contains(addr)) {
351 }
else if (pos !=
begin) {
353 if (pos->Contains(addr)) {
362#ifdef ASSERT_RANGEMAP_ARE_SORTED
367 typename Collection::const_iterator
end =
m_entries.end();
368 typename Collection::const_iterator pos =
371 if (pos !=
end && pos->Contains(range)) {
373 }
else if (pos !=
begin) {
375 if (pos->Contains(range)) {
393 if (prev->Union(*pos))
402 if (pos->Union(*next))
414template <
typename B,
typename S,
typename T>
430template <
typename B,
typename S,
typename T>
438template <
typename B,
typename S,
typename T,
unsigned N = 0,
470 if (a.base != b.base)
471 return a.base < b.base;
472 if (a.size != b.size)
473 return a.size < b.size;
474 return compare(a.data, b.data);
480#ifdef ASSERT_RANGEMAP_ARE_SORTED
481 bool IsSorted()
const {
482 typename Collection::const_iterator pos,
end, prev;
485 if (prev !=
end && *pos < *prev)
493#ifdef ASSERT_RANGEMAP_ARE_SORTED
496 typename Collection::iterator pos;
497 typename Collection::iterator
end;
498 typename Collection::iterator prev;
499 bool can_combine =
false;
504 if (prev !=
end && prev->data == pos->data) {
515 pos !=
end; prev = pos++) {
516 if (prev !=
end && prev->data == pos->data)
517 minimal_ranges.back().SetRangeEnd(pos->GetRangeEnd());
519 minimal_ranges.push_back(*pos);
555 return std::distance(
m_entries.begin(), entry);
560#ifdef ASSERT_RANGEMAP_ARE_SORTED
566 return indexes.size();
570 return const_cast<Entry *
>(
580#ifdef ASSERT_RANGEMAP_ARE_SORTED
585 typename Collection::const_iterator
end =
m_entries.end();
586 typename Collection::const_iterator pos =
592 if (pos !=
end && pos->Contains(range))
599#ifdef ASSERT_RANGEMAP_ARE_SORTED
605 if (pos !=
end && pos->base == addr)
621#ifdef ASSERT_RANGEMAP_ARE_SORTED
626 typename Collection::const_iterator
end =
m_entries.end();
627 typename Collection::const_iterator pos = llvm::lower_bound(
642#ifdef ASSERT_RANGEMAP_ARE_SORTED
648 return std::distance(
m_entries.begin(), entry);
669 size_t mid = (lo + hi) / 2;
688 std::vector<uint32_t> &indexes) {
689 size_t mid = (lo + hi) / 2;
703 if (addr < entry.
base)
707 indexes.push_back(entry.
data);
730 if (this->addr == rhs.
addr)
731 return this->data < rhs.
data;
732 return this->addr < rhs.
addr;
736 return this->addr == rhs.
addr && this->data == rhs.
data;
740 return this->addr != rhs.
addr || this->data == rhs.
data;
760#ifdef ASSERT_RANGEMAP_ARE_SORTED
761 bool IsSorted()
const {
762 typename Collection::const_iterator pos, end, prev;
767 if (prev != end && *pos < *prev)
793#ifdef ASSERT_RANGEMAP_ARE_SORTED
799 typename Collection::iterator begin =
m_entries.begin();
800 typename Collection::iterator end =
m_entries.end();
801 typename Collection::iterator pos =
804 while (pos != begin && pos[-1].addr == addr)
808 if (pos->addr == addr || !exact_match_only)
static bool Compare(BreakpointLocationSP lhs, lldb::break_id_t val)
Entry * FindEntry(B addr, bool exact_match_only)
llvm::SmallVector< Entry, N > Collection
AddressData< B, T > Entry
const Entry * GetEntryAtIndex(size_t i) const
const Entry * Back() const
const Entry & GetEntryRef(size_t i) const
void Append(const Entry &entry)
~AddressDataArray()=default
static bool BaseLessThan(const Entry &lhs, const Entry &rhs)
const Entry * FindNextEntry(const Entry *entry)
AddressDataArray()=default
const Entry * FindEntryThatContains(B addr) const
AugmentedRangeData< B, S, T > AugmentedEntry
void CombineConsecutiveEntriesWithEqualData()
uint32_t FindEntryIndexThatContainsOrFollows(B addr) const
uint32_t FindEntryIndexesThatContain(B addr, std::vector< uint32_t > &indexes)
Entry & GetEntryRef(size_t i)
uint32_t FindEntryIndexThatContains(B addr) const
B ComputeUpperBounds(size_t lo, size_t hi)
const Entry * FindEntryThatContains(const Entry &range) const
static bool BaseLessThan(const Entry &lhs, const Entry &rhs)
const_iterator end() const
const Entry * GetEntryAtIndex(size_t i) const
Entry * GetMutableEntryAtIndex(size_t i)
const Entry & GetEntryRef(size_t i) const
typename Collection::const_iterator const_iterator
const Entry * Back() const
RangeData< B, S, T > Entry
~RangeDataVector()=default
const_iterator begin() const
const Entry * FindEntryStartsAt(B addr) const
const Entry * FindEntryThatContainsOrFollows(B addr) const
void Append(const Entry &entry)
void Append(B &&b, S &&s, T &&t)
Append a range with data to the vector.
lldb_private::Range< B, S > Range
RangeDataVector(Compare compare=Compare())
bool Erase(uint32_t start, uint32_t end)
void FindEntryIndexesThatContain(B addr, size_t lo, size_t hi, std::vector< uint32_t > &indexes)
llvm::SmallVector< AugmentedEntry, N > Collection
Entry * FindEntryThatContains(B addr)
const Entry * FindEntryThatContains(B addr) const
typename Collection::const_iterator const_iterator
uint32_t FindEntryIndexThatContains(B addr) const
const Entry & GetEntryRef(size_t i) const
void Slide(BaseType slide)
const Entry * GetEntryAtIndex(size_t i) const
void CombinePrevAndNext(typename Collection::iterator pos)
const_iterator begin() const
BaseType GetMaxRangeEnd(BaseType fail_value) const
void Append(B base, S size)
Entry & GetEntryRef(size_t i)
bool RemoveEntryAtIndex(uint32_t idx)
static bool BaseLessThan(const Entry &lhs, const Entry &rhs)
void Append(const Entry &entry)
llvm::SmallVector< Entry, N > Collection
BaseType GetMinRangeBase(BaseType fail_value) const
static RangeVector GetOverlaps(const RangeVector &vec1, const RangeVector &vec2)
void CombineConsecutiveRanges()
void Reserve(typename Collection::size_type size)
const_iterator end() const
void Insert(const Entry &entry, bool combine)
const Entry * Back() const
bool operator==(const RangeVector &rhs) const
const Entry * FindEntryThatContains(const Entry &range) const
A class that represents a running process on the host machine.
llvm::APFloat::cmpResult compare(Scalar lhs, Scalar rhs)
bool operator==(const AddressData &rhs) const
bool operator<(const AddressData &rhs) const
bool operator!=(const AddressData &rhs) const
AddressData(B a, DataType d)
AugmentedRangeData(const RangeData< B, S, T > &rd)
RangeData(B base, S size, DataType d)
RangeData(B base, S size)
bool ContainsEndInclusive(BaseType r) const
bool DoesAdjoinOrIntersect(const Range &rhs) const
bool Contains(const Range &range) const
bool Contains(BaseType r) const
BaseType GetRangeBase() const
Range(BaseType b, SizeType s)
bool operator==(const Range &rhs) const
bool Union(const Range &rhs)
void SetRangeEnd(BaseType end)
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const
bool DoesIntersect(const Range &rhs) const
bool operator<(const Range &rhs) const
void Slide(BaseType slide)
bool operator!=(const Range &rhs) const
Range Intersect(const Range &rhs) const
void SetByteSize(SizeType s)