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,
464 if (a.base != b.base)
465 return a.base < b.base;
466 if (a.size != b.size)
467 return a.size < b.size;
468 return compare(a.data, b.data);
474#ifdef ASSERT_RANGEMAP_ARE_SORTED
475 bool IsSorted()
const {
476 typename Collection::const_iterator pos,
end, prev;
479 if (prev !=
end && *pos < *prev)
487#ifdef ASSERT_RANGEMAP_ARE_SORTED
490 typename Collection::iterator pos;
491 typename Collection::iterator
end;
492 typename Collection::iterator prev;
493 bool can_combine =
false;
498 if (prev !=
end && prev->data == pos->data) {
509 pos !=
end; prev = pos++) {
510 if (prev !=
end && prev->data == pos->data)
511 minimal_ranges.back().SetRangeEnd(pos->GetRangeEnd());
513 minimal_ranges.push_back(*pos);
549 return std::distance(
m_entries.begin(), entry);
554#ifdef ASSERT_RANGEMAP_ARE_SORTED
560 return indexes.size();
564 return const_cast<Entry *
>(
574#ifdef ASSERT_RANGEMAP_ARE_SORTED
579 typename Collection::const_iterator
end =
m_entries.end();
580 typename Collection::const_iterator pos =
586 if (pos !=
end && pos->Contains(range))
593#ifdef ASSERT_RANGEMAP_ARE_SORTED
599 if (pos !=
end && pos->base == addr)
615#ifdef ASSERT_RANGEMAP_ARE_SORTED
620 typename Collection::const_iterator
end =
m_entries.end();
621 typename Collection::const_iterator pos = llvm::lower_bound(
636#ifdef ASSERT_RANGEMAP_ARE_SORTED
642 return std::distance(
m_entries.begin(), entry);
663 size_t mid = (lo + hi) / 2;
682 std::vector<uint32_t> &indexes) {
683 size_t mid = (lo + hi) / 2;
697 if (addr < entry.
base)
701 indexes.push_back(entry.
data);
724 if (this->addr == rhs.
addr)
725 return this->data < rhs.
data;
726 return this->addr < rhs.
addr;
730 return this->addr == rhs.
addr && this->data == rhs.
data;
734 return this->addr != rhs.
addr || this->data == rhs.
data;
754#ifdef ASSERT_RANGEMAP_ARE_SORTED
755 bool IsSorted()
const {
756 typename Collection::const_iterator pos, end, prev;
761 if (prev != end && *pos < *prev)
787#ifdef ASSERT_RANGEMAP_ARE_SORTED
793 typename Collection::iterator begin =
m_entries.begin();
794 typename Collection::iterator end =
m_entries.end();
795 typename Collection::iterator pos =
798 while (pos != begin && pos[-1].addr == addr)
802 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)
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.
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)