Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ConcurrentRangeMap.h
Go to the documentation of this file.
1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
2 /*
3  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4 */
13 #ifndef CXXUTILS_CONCURRENTRANGEMAP_H
14 #define CXXUTILS_CONCURRENTRANGEMAP_H
15 
16 
17 #include "CxxUtils/stall.h"
18 #include "CxxUtils/IsUpdater.h"
19 #include "boost/range/iterator_range.hpp"
20 #include <atomic>
21 #include <mutex>
22 #include <utility>
23 #include <vector>
24 #include <memory>
25 #include <algorithm>
26 #include <functional>
27 
28 
29 namespace CxxUtils {
30 
31 
42 template <class T, class CONTEXT>
44 {
45 public:
47  typedef void delete_function (const T*);
48 
49 
55 
56 
58  virtual ~IRangeMapPayloadDeleter() = default;
59 
60 
68  virtual void discard (const T* p) = 0;
69 
70 
75  virtual void quiescent (const CONTEXT& ctx) = 0;
76 
77 
82 
83 
84 private:
87 };
88 
89 
90 //*****************************************************************************
91 
92 
93 namespace detail {
94 
95 
100 template <class COMPARE, class RANGE, class KEY, class CONTEXT>
101 concept IsConcurrentRangeCompare = requires (const COMPARE& c,
102  const RANGE& r1,
103  const RANGE& r2,
104  RANGE& r_nc,
105  const KEY& k,
106  const CONTEXT& ctx)
107 {
108  { c(k, r2) } -> std::same_as<bool>;
109  { c(r1, r2) } -> std::same_as<bool>;
110  { c.inRange (k, r2) } -> std::same_as<bool>;
111  { c.overlap (ctx, r1, r_nc) } -> std::same_as<int>;
112  { c.extendRange (r_nc, r2) } -> std::same_as<int>;
113 };
114 
115 
116 } // namespace detail
117 
118 
119 //*****************************************************************************
120 
121 
208 template <class RANGE, class KEY, class T, class COMPARE,
209  template <class> class UPDATER>
210 requires (detail::IsUpdater<UPDATER> &&
211  detail::IsConcurrentRangeCompare<COMPARE, RANGE, KEY, typename UPDATER<int>::Context_t>)
212 class ConcurrentRangeMap
213 {
214 public:
215  typedef RANGE key_type;
216  typedef const T* mapped_type;
217  typedef std::pair<RANGE, const T*> value_type;
218  typedef const value_type& const_reference;
219  typedef const value_type* const_pointer;
220  typedef size_t size_type;
221  typedef int difference_type;
222  typedef COMPARE key_compare;
223  typedef KEY key_query_type;
224 
225 
227  typedef void delete_function (const T*);
228 
229 
236  struct DeletePayload
237  {
239  DeletePayload (delete_function* delfcn)
240  : m_delete (delfcn)
241  {
242  }
243 
245  template <class U>
246  static void delfcn (const T* p)
247  {
248  delete reinterpret_cast<const U*>(p);
249  }
250  template <class U>
251  DeletePayload (const std::default_delete<U>&)
252  {
253  m_delete = delfcn<U>;
254  }
255 
257  void operator() (const T* p) const
258  {
259  m_delete (p);
260  }
261 
263  delete_function* m_delete;
264  };
265 
266 
286  typedef std::unique_ptr<T, DeletePayload> payload_unique_ptr;
287 
288  typedef const value_type* const_iterator;
289  typedef boost::iterator_range<const_iterator> const_iterator_range;
290 
291 
302  class Impl
303  {
304  public:
309  Impl (size_t capacity = 10);
310 
311 
315  ~Impl() = default;
316 
317 
321  value_type* data();
322 
323 
327  size_t capacity() const;
328 
329 
330  private:
332  std::vector<value_type> m_data;
333  };
334 
335  using Updater_t = UPDATER<Impl>;
337 
338 
348  ConcurrentRangeMap (Updater_t&& updater,
349  std::shared_ptr<IPayloadDeleter> payloadDeleter,
350  size_t capacity = 16,
351  const COMPARE& compare = COMPARE());
352 
353 
359  ~ConcurrentRangeMap();
360 
361 
365  IPayloadDeleter& deleter();
366 
367 
371  const IPayloadDeleter& deleter() const;
372 
373 
379  const_iterator find (const key_query_type& key) const;
380 
381 
383  enum class EmplaceResult
384  {
386  SUCCESS,
387 
389  OVERLAP,
390 
392  DUPLICATE,
393 
394  // Existing range was extended to match the new range; new object
395  // was deleted.
396  EXTENDED
397  };
398 
399 
422  EmplaceResult emplace (const RANGE& range,
423  payload_unique_ptr ptr,
424  bool tryExtend = false,
425  const typename Updater_t::Context_t& ctx =
426  Updater_t::defaultContext());
427 
428 
434  void erase (const key_query_type& key,
435  const typename Updater_t::Context_t& ctx =
436  Updater_t::defaultContext());
437 
438 
454  int extendLastRange (const RANGE& newRange,
455  const typename Updater_t::Context_t& ctx =
456  Updater_t::defaultContext());
457 
458 
469  void updateRanges (std::function<void (RANGE&)> rangeUpdater,
470  const typename Updater_t::Context_t& ctx =
471  Updater_t::defaultContext());
472 
473 
494  size_t trim (const std::vector<key_query_type>& keys, bool trimall = false);
495 
496 
501  void clear();
502 
503 
507  size_t size() const;
508 
509 
513  bool empty() const;
514 
515 
519  size_t capacity() const;
520 
521 
525  size_t nInserts() const;
526 
527 
531  size_t maxSize() const;
532 
533 
537  const_iterator_range range() const;
538 
539 
545  void quiescent (const typename Updater_t::Context_t& ctx =
546  Updater_t::defaultContext());
547 
548 
549 private:
551  typedef std::mutex mutex_t;
552  typedef std::lock_guard<mutex_t> lock_t;
553 
554 
570  const_iterator getBegin (const_iterator& last) const;
571 
572 
578  void updatePointers (value_type* new_begin, value_type* new_end);
579 
580 
586  bool anyInRange (const key_type& r,
587  const std::vector<key_query_type>& keys) const;
588 
589 
599  void installImpl (std::unique_ptr<Impl> new_impl,
600  value_type* new_begin,
601  value_type* new_end,
602  const typename Updater_t::Context_t& ctx);
603 
604 
614  int extendImpl (lock_t& lock,
615  const RANGE& extendedRange,
616  const typename Updater_t::Context_t& ctx);
617 
618 
619 
622  Updater_t m_updater;
623 
625  COMPARE m_compare;
626 
638  std::shared_ptr<IPayloadDeleter> m_payloadDeleter;
639 
641  Impl* m_impl;
642 
654  std::atomic<value_type*> m_begin;
655  std::atomic<value_type*> m_last;
656 
658  size_t m_nInserts;
659  size_t m_maxSize;
660 
662  mutex_t m_mutex;
663 };
664 
665 
666 } // namespace CxxUtils
667 
668 
670 
671 
672 #endif // not CXXUTILS_CONCURRENTRANGEMAP_H
CxxUtils::IRangeMapPayloadDeleter
Helper to delete payload objects for ConcurrentRangeMap.
Definition: ConcurrentRangeMap.h:44
beamspotman.r
def r
Definition: beamspotman.py:676
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
Amg::compare
std::pair< int, int > compare(const AmgSymMatrix(N) &m1, const AmgSymMatrix(N) &m2, double precision=1e-9, bool relative=false)
compare two matrices, returns the indices of the first element that fails the condition,...
Definition: EventPrimitivesHelpers.h:109
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
m_data
std::vector< T > m_data
Definition: TrackTruthMatchingBaseAlg.cxx:660
IsUpdater.h
Concept check for Updater class used by concurrent classes.
CxxUtils::IRangeMapPayloadDeleter::m_delfcn
delete_function * m_delfcn
Immediate deletion function.
Definition: ConcurrentRangeMap.h:86
CxxUtils::detail::IsConcurrentRangeCompare
concept IsConcurrentRangeCompare
Concept for comparison template argument.
Definition: ConcurrentRangeMap.h:101
ConcurrentRangeMap.icc
detail
Definition: extract_histogram_tag.cxx:14
CxxUtils::IRangeMapPayloadDeleter::~IRangeMapPayloadDeleter
virtual ~IRangeMapPayloadDeleter()=default
Virtual destructor.
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
CxxUtils::IRangeMapPayloadDeleter::discard
virtual void discard(const T *p)=0
Queue an object for deletion.
CxxUtils::IRangeMapPayloadDeleter::delete_function
void delete_function(const T *)
Type of a function to delete a payload object immediately.
Definition: ConcurrentRangeMap.h:47
FPEAudit::lock_t
std::lock_guard< std::mutex > lock_t
Definition: FPEAuditor.cxx:44
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
CondContStatusCode::DUPLICATE
@ DUPLICATE
CondContStatusCode::OVERLAP
@ OVERLAP
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
CxxUtils
Definition: aligned_vector.h:29
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
CxxUtils::IRangeMapPayloadDeleter::delfcn
delete_function * delfcn() const
Return a function to delete a payload object immediately.
CxxUtils::requires
requires(detail::IsConcurrentHashmapPayload< KEY > &&detail::IsConcurrentHashmapPayload< VALUE > &&detail::IsUpdater< UPDATER > &&detail::IsHash< HASHER, KEY > &&detail::IsBinaryPredicate< MATCHER, KEY >) class ConcurrentMap
Hash map from integers/pointers allowing concurrent, lockless reads.
Definition: ConcurrentMap.h:94
stall.h
Emit stall instruction for use in a spin loop.
CxxUtils::IRangeMapPayloadDeleter::IRangeMapPayloadDeleter
IRangeMapPayloadDeleter(delete_function *delfcn)
Constructor.
columnar::operator()
decltype(auto) operator()(ObjectId< OT, CM > id) const noexcept
Definition: ColumnAccessor.h:175
VKalVrtAthena::varHolder_detail::clear
void clear(T &var)
Definition: NtupleVars.h:48
CxxUtils::IRangeMapPayloadDeleter::quiescent
virtual void quiescent(const CONTEXT &ctx)=0
Mark a slot as quiescent.
GRLStrUtil::trim
void trim(std::string &input)
Definition: StrUtil.cxx:12
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
CondContStatusCode::EXTENDED
@ EXTENDED
value_type
Definition: EDM_MasterSearch.h:11
python.compressB64.c
def c
Definition: compressB64.py:93
fitman.k
k
Definition: fitman.py:528
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37