From 0d5a3abeaefd3a1682c48a59c5a9170cfb0a39d0 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 4 Feb 2024 19:16:07 +0100 Subject: Buffer Cache: Refactor to use Range sets instead --- src/common/range_sets.inc | 184 ++++++++++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 81 deletions(-) (limited to 'src/common/range_sets.inc') diff --git a/src/common/range_sets.inc b/src/common/range_sets.inc index fa55a68fb..705ebd4a1 100644 --- a/src/common/range_sets.inc +++ b/src/common/range_sets.inc @@ -6,9 +6,6 @@ #include #include -#define BOOST_NO_MT -#include -#undef BOOST_NO_MT #include #include #include @@ -20,18 +17,16 @@ #include "common/range_sets.h" -namespace boost { -template -class fast_pool_allocator; -} - namespace Common { template struct RangeSet::RangeSetImpl { + template + using MyAllocator = boost::fast_pool_allocator; using IntervalSet = boost::icl::interval_set< AddressType, std::less, ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, AddressType, std::less), - boost::fast_pool_allocator>; + MyAllocator>; using IntervalType = typename IntervalSet::interval_type; RangeSetImpl() = default; @@ -49,18 +44,58 @@ struct RangeSet::RangeSetImpl { m_ranges_set.subtract(interval); } + template + void ForEach(Func&& func) const { + if (m_ranges_set.empty()) { + return; + } + auto it = m_ranges_set.begin(); + auto end_it = m_ranges_set.end(); + for (; it != end_it; it++) { + const AddressType inter_addr_end = it->upper(); + const AddressType inter_addr = it->lower(); + func(inter_addr, inter_addr_end); + } + } + + template + void ForEachInRange(AddressType base_addr, size_t size, Func&& func) const { + if (m_ranges_set.empty()) { + return; + } + const AddressType start_address = base_addr; + const AddressType end_address = start_address + size; + const RangeSetImpl::IntervalType search_interval{start_address, end_address}; + auto it = m_ranges_set.lower_bound(search_interval); + if (it == m_ranges_set.end()) { + return; + } + auto end_it = m_ranges_set.upper_bound(search_interval); + for (; it != end_it; it++) { + AddressType inter_addr_end = it->upper(); + AddressType inter_addr = it->lower(); + if (inter_addr_end > end_address) { + inter_addr_end = end_address; + } + if (inter_addr < start_address) { + inter_addr = start_address; + } + func(inter_addr, inter_addr_end); + } + } + IntervalSet m_ranges_set; }; template struct SplitRangeSet::SplitRangeSetImpl { - - using IntervalSet = - boost::icl::split_interval_map; + template + using MyAllocator = boost::fast_pool_allocator; + using IntervalSet = boost::icl::split_interval_map< + AddressType, s32, boost::icl::partial_enricher, std::less, boost::icl::inplace_plus, + boost::icl::inter_section, + ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, AddressType, std::less), MyAllocator>; using IntervalType = typename IntervalSet::interval_type; SplitRangeSetImpl() = default; @@ -75,6 +110,9 @@ struct SplitRangeSet::SplitRangeSetImpl { template void Subtract(AddressType base_address, size_t size, s32 amount, [[maybe_unused]] Func&& on_delete) { + if (m_split_ranges_set.empty()) { + return; + } AddressType end_address = base_address + static_cast(size); IntervalType interval{base_address, end_address}; bool any_removals = false; @@ -101,6 +139,47 @@ struct SplitRangeSet::SplitRangeSetImpl { } while (any_removals); } + template + void ForEach(Func&& func) const { + if (m_split_ranges_set.empty()) { + return; + } + auto it = m_split_ranges_set.begin(); + auto end_it = m_split_ranges_set.end(); + for (; it != end_it; it++) { + const AddressType inter_addr_end = it->first.upper(); + const AddressType inter_addr = it->first.lower(); + func(inter_addr, inter_addr_end, it->second); + } + } + + template + void ForEachInRange(AddressType base_address, size_t size, Func&& func) const { + if (m_split_ranges_set.empty()) { + return; + } + const AddressType start_address = base_address; + const AddressType end_address = start_address + size; + const SplitRangeSetImpl::IntervalType search_interval{start_address, end_address}; + auto it = m_split_ranges_set.lower_bound(search_interval); + if (it == m_split_ranges_set.end()) { + return; + } + auto end_it = m_split_ranges_set.upper_bound(search_interval); + for (; it != end_it; it++) { + auto& inter = it->first; + AddressType inter_addr_end = inter.upper(); + AddressType inter_addr = inter.lower(); + if (inter_addr_end > end_address) { + inter_addr_end = end_address; + } + if (inter_addr < start_address) { + inter_addr = start_address; + } + func(inter_addr, inter_addr_end, it->second); + } + } + IntervalSet m_split_ranges_set; }; @@ -146,41 +225,13 @@ bool RangeSet::Empty() const { template template void RangeSet::ForEach(Func&& func) const { - if (m_impl->m_ranges_set.empty()) { - return; - } - auto it = m_impl->m_ranges_set.begin(); - auto end_it = m_impl->m_ranges_set.end(); - for (; it != end_it; it++) { - const AddressType inter_addr_end = it->upper(); - const AddressType inter_addr = it->lower(); - func(inter_addr, inter_addr_end); - } + m_impl->ForEach(std::move(func)); } template template -void RangeSet::ForEachInRange(AddressType base_addr, size_t size, Func&& func) const { - auto& range_set = m_impl->m_ranges_set; - const AddressType start_address = base_addr; - const AddressType end_address = start_address + size; - const RangeSetImpl::IntervalType search_interval{start_address, end_address}; - auto it = range_set.lower_bound(search_interval); - if (it == range_set.end()) { - return; - } - auto end_it = range_set.upper_bound(search_interval); - for (; it != end_it; it++) { - AddressType inter_addr_end = it->upper(); - AddressType inter_addr = it->lower(); - if (inter_addr_end > end_address) { - inter_addr_end = end_address; - } - if (inter_addr < start_address) { - inter_addr = start_address; - } - func(inter_addr, inter_addr_end); - } +void RangeSet::ForEachInRange(AddressType base_address, size_t size, Func&& func) const { + m_impl->ForEachInRange(base_address, size, std::move(func)); } template @@ -209,18 +260,18 @@ void SplitRangeSet::Add(AddressType base_address, size_t size) { template void SplitRangeSet::Subtract(AddressType base_address, size_t size) { - m_impl->Subtract(base_address, size, 1, [](AddressType, AddressType) {}); + m_impl->template Subtract(base_address, size, 1, [](AddressType, AddressType) {}); } template template void SplitRangeSet::Subtract(AddressType base_address, size_t size, Func&& on_delete) { - m_impl->Subtract(base_address, size, 1, on_delete); + m_impl->template Subtract(base_address, size, 1, std::move(on_delete)); } template void SplitRangeSet::DeleteAll(AddressType base_address, size_t size) { - m_impl->Subtract(base_address, size, std::numeric_limits::max(), + m_impl->template Subtract(base_address, size, std::numeric_limits::max(), [](AddressType, AddressType) {}); } @@ -237,43 +288,14 @@ bool SplitRangeSet::Empty() const { template template void SplitRangeSet::ForEach(Func&& func) const { - if (m_impl->m_split_ranges_set.empty()) { - return; - } - auto it = m_impl->m_split_ranges_set.begin(); - auto end_it = m_impl->m_split_ranges_set.end(); - for (; it != end_it; it++) { - const AddressType inter_addr_end = it->first.upper(); - const AddressType inter_addr = it->first.lower(); - func(inter_addr, inter_addr_end, it->second); - } + m_impl->ForEach(func); } template template void SplitRangeSet::ForEachInRange(AddressType base_address, size_t size, Func&& func) const { - auto& range_set = m_impl->m_split_ranges_set; - const AddressType start_address = base_address; - const AddressType end_address = start_address + size; - const SplitRangeSetImpl::IntervalType search_interval{start_address, end_address}; - auto it = range_set.lower_bound(search_interval); - if (it == range_set.end()) { - return; - } - auto end_it = range_set.upper_bound(search_interval); - for (; it != end_it; it++) { - auto& inter = it->first; - AddressType inter_addr_end = inter.upper(); - AddressType inter_addr = inter.lower(); - if (inter_addr_end > end_address) { - inter_addr_end = end_address; - } - if (inter_addr < start_address) { - inter_addr = start_address; - } - func(inter_addr, inter_addr_end, it->second); - } + m_impl->ForEachInRange(base_address, size, std::move(func)); } } // namespace Common \ No newline at end of file -- cgit v1.2.3