ATLAS Offline Software
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-2023 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/concepts.h"
19 #include "CxxUtils/IsUpdater.h"
20 #include "boost/range/iterator_range.hpp"
21 #include <atomic>
22 #include <mutex>
23 #include <utility>
24 #include <vector>
25 #include <memory>
26 #include <algorithm>
27 #include <functional>
28 
29 
30 namespace CxxUtils {
31 
32 
43 template <class T, class CONTEXT>
45 {
46 public:
48  typedef void delete_function (const T*);
49 
50 
56 
57 
59  virtual ~IRangeMapPayloadDeleter() = default;
60 
61 
69  virtual void discard (const T* p) = 0;
70 
71 
76  virtual void quiescent (const CONTEXT& ctx) = 0;
77 
78 
83 
84 
85 private:
88 };
89 
90 
91 //*****************************************************************************
92 
93 
94 #if HAVE_CONCEPTS
95 
96 
97 namespace detail {
98 
99 
104 template <class COMPARE, class RANGE, class KEY, class CONTEXT>
105 concept IsConcurrentRangeCompare = requires (const COMPARE& c,
106  const RANGE& r1,
107  const RANGE& r2,
108  RANGE& r_nc,
109  const KEY& k,
110  const CONTEXT& ctx)
111 {
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>;
117 };
118 
119 
120 } // namespace detail
121 
122 
123 #endif // HAVE_CONCEPTS
124 
125 
126 //*****************************************************************************
127 
128 
215 template <class RANGE, class KEY, class T, class COMPARE,
216  template <class> class UPDATER>
217 ATH_REQUIRES (detail::IsUpdater<UPDATER> &&
218  detail::IsConcurrentRangeCompare<COMPARE, RANGE, KEY, typename UPDATER<int>::Context_t>)
219 class ConcurrentRangeMap
220 {
221 public:
222  typedef RANGE key_type;
223  typedef const T* mapped_type;
224  typedef std::pair<RANGE, const T*> value_type;
225  typedef const value_type& const_reference;
226  typedef const value_type* const_pointer;
227  typedef size_t size_type;
228  typedef int difference_type;
229  typedef COMPARE key_compare;
230  typedef KEY key_query_type;
231 
232 
234  typedef void delete_function (const T*);
235 
236 
243  struct DeletePayload
244  {
246  // cppcheck-suppress uninitMemberVar // false positive
247  DeletePayload (delete_function* delfcn)
248  : m_delete (delfcn)
249  {
250  }
251 
253  template <class U>
254  static void delfcn (const T* p)
255  {
256  delete reinterpret_cast<const U*>(p);
257  }
258  template <class U>
259  // cppcheck-suppress uninitMemberVar // false positive
260  DeletePayload (const std::default_delete<U>&)
261  {
262  m_delete = delfcn<U>;
263  }
264 
266  void operator() (const T* p) const
267  {
268  m_delete (p);
269  }
270 
272  delete_function* m_delete;
273  };
274 
275 
295  typedef std::unique_ptr<T, DeletePayload> payload_unique_ptr;
296 
297  typedef const value_type* const_iterator;
298  typedef boost::iterator_range<const_iterator> const_iterator_range;
299 
300 
311  class Impl
312  {
313  public:
318  Impl (size_t capacity = 10);
319 
320 
324  ~Impl() = default;
325 
326 
330  value_type* data();
331 
332 
336  size_t capacity() const;
337 
338 
339  private:
341  std::vector<value_type> m_data;
342  };
343 
344  using Updater_t = UPDATER<Impl>;
346 
347 
357  ConcurrentRangeMap (Updater_t&& updater,
358  std::shared_ptr<IPayloadDeleter> payloadDeleter,
359  size_t capacity = 16,
360  const COMPARE& compare = COMPARE());
361 
362 
368  ~ConcurrentRangeMap();
369 
370 
374  IPayloadDeleter& deleter();
375 
376 
380  const IPayloadDeleter& deleter() const;
381 
382 
388  const_iterator find (const key_query_type& key) const;
389 
390 
392  enum class EmplaceResult
393  {
395  SUCCESS,
396 
398  OVERLAP,
399 
401  DUPLICATE,
402 
403  // Existing range was extended to match the new range; new object
404  // was deleted.
405  EXTENDED
406  };
407 
408 
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());
436 
437 
443  void erase (const key_query_type& key,
444  const typename Updater_t::Context_t& ctx =
445  Updater_t::defaultContext());
446 
447 
463  int extendLastRange (const RANGE& newRange,
464  const typename Updater_t::Context_t& ctx =
465  Updater_t::defaultContext());
466 
467 
478  void updateRanges (std::function<void (RANGE&)> rangeUpdater,
479  const typename Updater_t::Context_t& ctx =
480  Updater_t::defaultContext());
481 
482 
503  size_t trim (const std::vector<key_query_type>& keys, bool trimall = false);
504 
505 
510  void clear();
511 
512 
516  size_t size() const;
517 
518 
522  bool empty() const;
523 
524 
528  size_t capacity() const;
529 
530 
534  size_t nInserts() const;
535 
536 
540  size_t maxSize() const;
541 
542 
546  const_iterator_range range() const;
547 
548 
554  void quiescent (const typename Updater_t::Context_t& ctx =
555  Updater_t::defaultContext());
556 
557 
558 private:
560  typedef std::mutex mutex_t;
561  typedef std::lock_guard<mutex_t> lock_t;
562 
563 
579  const_iterator getBegin (const_iterator& last) const;
580 
581 
587  void updatePointers (value_type* new_begin, value_type* new_end);
588 
589 
595  bool anyInRange (const key_type& r,
596  const std::vector<key_query_type>& keys) const;
597 
598 
608  void installImpl (std::unique_ptr<Impl> new_impl,
609  value_type* new_begin,
610  value_type* new_end,
611  const typename Updater_t::Context_t& ctx);
612 
613 
623  int extendImpl (lock_t& lock,
624  const RANGE& extendedRange,
625  const typename Updater_t::Context_t& ctx);
626 
627 
628 
631  Updater_t m_updater;
632 
634  COMPARE m_compare;
635 
647  std::shared_ptr<IPayloadDeleter> m_payloadDeleter;
648 
650  Impl* m_impl;
651 
663  std::atomic<value_type*> m_begin;
664  std::atomic<value_type*> m_last;
665 
667  size_t m_nInserts;
668  size_t m_maxSize;
669 
671  mutex_t m_mutex;
672 };
673 
674 
675 } // namespace CxxUtils
676 
677 
679 
680 
681 #endif // not CXXUTILS_CONCURRENTRANGEMAP_H
CxxUtils::IRangeMapPayloadDeleter
Helper to delete payload objects for ConcurrentRangeMap.
Definition: ConcurrentRangeMap.h:45
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:87
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:48
FPEAudit::lock_t
std::lock_guard< std::mutex > lock_t
Definition: FPEAuditor.cxx:44
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
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.
stall.h
Emit stall instruction for use in a spin loop.
CxxUtils::IRangeMapPayloadDeleter::IRangeMapPayloadDeleter
IRangeMapPayloadDeleter(delete_function *delfcn)
Constructor.
concepts.h
Compatibility helpers for using some pieces of C++20 concepts with older compilers.
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.
CxxUtils::ATH_REQUIRES
ATH_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
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
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
fitman.k
k
Definition: fitman.py:528
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37