13 #ifndef CXXUTILS_CONCURRENTRANGEMAP_H
14 #define CXXUTILS_CONCURRENTRANGEMAP_H
20 #include "boost/range/iterator_range.hpp"
43 template <
class T,
class CONTEXT>
104 template <
class COMPARE,
class RANGE,
class KEY,
class CONTEXT>
105 concept IsConcurrentRangeCompare = requires (
const COMPARE&
c,
112 {
c(
k, r2) } -> std::same_as<bool>;
113 {
c(r1, r2) } -> std::same_as<bool>;
114 {
c.inRange (
k, r2) } -> std::same_as<bool>;
115 {
c.overlap (ctx, r1, r_nc) } -> std::same_as<int>;
116 {
c.extendRange (r_nc, r2) } -> std::same_as<int>;
123 #endif // HAVE_CONCEPTS
215 template <
class RANGE,
class KEY,
class T,
class COMPARE,
216 template <
class>
class UPDATER>
218 detail::IsConcurrentRangeCompare<COMPARE, RANGE, KEY,
typename UPDATER<int>::Context_t>)
219 class ConcurrentRangeMap
222 typedef RANGE key_type;
223 typedef const T* mapped_type;
224 typedef std::pair<RANGE, const T*>
value_type;
227 typedef size_t size_type;
228 typedef int difference_type;
229 typedef COMPARE key_compare;
230 typedef KEY key_query_type;
234 typedef void delete_function (
const T*);
247 DeletePayload (delete_function* delfcn)
254 static void delfcn (
const T*
p)
256 delete reinterpret_cast<const U*
>(
p);
260 DeletePayload (
const std::default_delete<U>&)
262 m_delete = delfcn<U>;
266 void operator() (
const T*
p)
const
272 delete_function* m_delete;
295 typedef std::unique_ptr<T, DeletePayload> payload_unique_ptr;
298 typedef boost::iterator_range<const_iterator> const_iterator_range;
318 Impl (
size_t capacity = 10);
336 size_t capacity()
const;
341 std::vector<value_type>
m_data;
344 using Updater_t = UPDATER<Impl>;
357 ConcurrentRangeMap (Updater_t&& updater,
358 std::shared_ptr<IPayloadDeleter> payloadDeleter,
359 size_t capacity = 16,
360 const COMPARE&
compare = COMPARE());
368 ~ConcurrentRangeMap();
374 IPayloadDeleter& deleter();
380 const IPayloadDeleter& deleter()
const;
388 const_iterator
find (
const key_query_type&
key)
const;
392 enum class EmplaceResult
431 EmplaceResult emplace (
const RANGE&
range,
432 payload_unique_ptr
ptr,
433 bool tryExtend =
false,
434 const typename Updater_t::Context_t& ctx =
435 Updater_t::defaultContext());
443 void erase (
const key_query_type&
key,
444 const typename Updater_t::Context_t& ctx =
445 Updater_t::defaultContext());
463 int extendLastRange (
const RANGE& newRange,
464 const typename Updater_t::Context_t& ctx =
465 Updater_t::defaultContext());
478 void updateRanges (std::function<
void (RANGE&)> rangeUpdater,
479 const typename Updater_t::Context_t& ctx =
480 Updater_t::defaultContext());
503 size_t trim (
const std::vector<key_query_type>&
keys,
bool trimall =
false);
528 size_t capacity()
const;
534 size_t nInserts()
const;
540 size_t maxSize()
const;
546 const_iterator_range
range()
const;
554 void quiescent (
const typename Updater_t::Context_t& ctx =
555 Updater_t::defaultContext());
561 typedef std::lock_guard<mutex_t>
lock_t;
579 const_iterator getBegin (const_iterator& last)
const;
595 bool anyInRange (
const key_type&
r,
596 const std::vector<key_query_type>&
keys)
const;
608 void installImpl (std::unique_ptr<Impl> new_impl,
611 const typename Updater_t::Context_t& ctx);
623 int extendImpl (
lock_t& lock,
624 const RANGE& extendedRange,
625 const typename Updater_t::Context_t& ctx);
647 std::shared_ptr<IPayloadDeleter> m_payloadDeleter;
663 std::atomic<value_type*> m_begin;
664 std::atomic<value_type*> m_last;
681 #endif // not CXXUTILS_CONCURRENTRANGEMAP_H