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) {
158 Entry entry = pos1->Intersect(*pos2);
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)) {
384#ifdef ASSERT_RANGEMAP_ARE_SORTED
389 typename Collection::const_iterator
end =
m_entries.end();
390 typename Collection::const_iterator pos =
393 while (pos !=
begin && pos[-1].DoesIntersect(range))
396 if (pos !=
end && pos->DoesIntersect(range))
412 if (prev->Union(*pos))
421 if (pos->Union(*next))
433template <
typename B,
typename S,
typename T>
449template <
typename B,
typename S,
typename T>
457template <
typename B,
typename S,
typename T,
unsigned N = 0,
499#ifdef ASSERT_RANGEMAP_ARE_SORTED
500 bool IsSorted()
const {
501 typename Collection::const_iterator pos,
end, prev;
504 if (prev !=
end && *pos < *prev)
512#ifdef ASSERT_RANGEMAP_ARE_SORTED
515 auto first_intersect = std::adjacent_find(
517 return a.DoesAdjoinOrIntersect(b) && a.data == b.data;
525 auto pos = std::next(first_intersect);
528 Entry &back = minimal_ranges.back();
532 minimal_ranges.push_back(*pos);
565 return std::distance(
m_entries.begin(), entry);
570#ifdef ASSERT_RANGEMAP_ARE_SORTED
576 return indexes.size();
580 return const_cast<Entry *
>(
590#ifdef ASSERT_RANGEMAP_ARE_SORTED
595 typename Collection::const_iterator
end =
m_entries.end();
596 typename Collection::const_iterator pos =
602 if (pos !=
end && pos->Contains(range))
609#ifdef ASSERT_RANGEMAP_ARE_SORTED
615 if (pos !=
end && pos->base == addr)
631#ifdef ASSERT_RANGEMAP_ARE_SORTED
636 typename Collection::const_iterator
end =
m_entries.end();
637 typename Collection::const_iterator pos = llvm::lower_bound(
652#ifdef ASSERT_RANGEMAP_ARE_SORTED
658 return std::distance(
m_entries.begin(), entry);
679 size_t mid = (lo + hi) / 2;
698 std::vector<uint32_t> &indexes) {
699 size_t mid = (lo + hi) / 2;
713 if (addr < entry.
base)
717 indexes.push_back(entry.
data);
740 if (this->addr == rhs.
addr)
741 return this->data < rhs.
data;
742 return this->addr < rhs.
addr;
746 return this->addr == rhs.
addr && this->data == rhs.
data;
750 return this->addr != rhs.
addr || this->data == rhs.
data;
770#ifdef ASSERT_RANGEMAP_ARE_SORTED
771 bool IsSorted()
const {
772 typename Collection::const_iterator pos, end, prev;
777 if (prev != end && *pos < *prev)
803#ifdef ASSERT_RANGEMAP_ARE_SORTED
809 typename Collection::iterator begin =
m_entries.begin();
810 typename Collection::iterator end =
m_entries.end();
811 typename Collection::iterator pos =
814 while (pos != begin && pos[-1].addr == addr)
818 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
DWARFExpressionCompare m_compare
const Entry * FindEntryThatContains(B addr) const
AugmentedRangeData< lldb::addr_t, lldb::addr_t, DWARFExpression > 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< lldb::addr_t, lldb::addr_t, DWARFExpression > 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< lldb::addr_t, lldb::addr_t > 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)
Range< int32_t, uint32_t > 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 * FindEntryThatIntersects(const Entry &range) const
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)