ATLAS Offline Software
ConcurrentMap.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_CONCURRENTMAP_H
14 #define CXXUTILS_CONCURRENTMAP_H
15 
16 
18 #include "CxxUtils/UIntConv.h"
19 #include "CxxUtils/concepts.h"
20 #include "CxxUtils/IsUpdater.h"
21 #include "boost/iterator/iterator_facade.hpp"
22 #include "boost/range/iterator_range.hpp"
23 #include <type_traits>
24 #include <stdexcept>
25 
26 
27 namespace CxxUtils {
28 
29 
89 template <class KEY, class VALUE, template <class> class UPDATER,
90  class HASHER = std::hash<KEY>,
91  class MATCHER = std::equal_to<KEY>,
93  detail::ConcurrentHashmapVal_t TOMBSTONE = NULLVAL>
94 ATH_REQUIRES (detail::IsConcurrentHashmapPayload<KEY> &&
95  detail::IsConcurrentHashmapPayload<VALUE> &&
96  detail::IsUpdater<UPDATER> &&
97  detail::IsHash<HASHER, KEY> &&
98  detail::IsBinaryPredicate<MATCHER, KEY>)
99 class ConcurrentMap
100 {
101 private:
104 
105  // Translate between the Hasher/Matcher provided (which take KEY arguments)
106  // and what we need to give to the underlying implementation
107  // (which takes a uintptr_t).
108  struct Hasher
109  {
110  size_t operator() (val_t k) const {
111  return m_h (keyAsKey (k));
112  }
113  HASHER m_h;
114  };
115  struct Matcher
116  {
117  bool operator() (val_t a, val_t b) const {
118  return m_m (keyAsKey (a), keyAsKey (b));
119  }
120  MATCHER m_m;
121  };
122 
124  using Impl_t = typename detail::ConcurrentHashmapImpl<UPDATER,
125  Hasher,
126  Matcher,
127  NULLVAL,
128  TOMBSTONE>;
129 
130 
131 public:
133  using key_type = KEY;
134  using mapped_type = VALUE;
135  using size_type = size_t;
137  using Updater_t = typename Impl_t::Updater_t;
139  using Context_t = typename Updater_t::Context_t;
141  using Lock_t = typename Impl_t::Lock_t;
142 
144  static_assert( sizeof(typename Impl_t::val_t) >= sizeof(key_type) );
145  static_assert( sizeof(typename Impl_t::val_t) >= sizeof(mapped_type) );
146 
147 
156  ConcurrentMap (Updater_t&& updater,
157  size_type capacity = 64,
158  const Context_t& ctx = Updater_t::defaultContext());
159 
170  ConcurrentMap (const ConcurrentMap& other,
171  Updater_t&& updater,
172  size_t capacity = 64,
173  const Context_t& ctx = Updater_t::defaultContext());
174 
175 
188  template <class InputIterator>
189  ConcurrentMap (InputIterator f,
190  InputIterator l,
191  Updater_t&& updater,
192  size_type capacity = 64,
193  const Context_t& ctx = Updater_t::defaultContext());
194 
195 
197  ConcurrentMap (const ConcurrentMap& other) = delete;
198  ConcurrentMap (ConcurrentMap&& other) = delete;
199  ConcurrentMap& operator= (const ConcurrentMap& other) = delete;
200  ConcurrentMap& operator= (ConcurrentMap&& other) = delete;
201 
202 
206  ~ConcurrentMap() = default;
207 
208 
212  size_type size() const;
213 
214 
218  bool empty() const;
219 
220 
224  size_t capacity() const;
225 
226 
230  size_t erased() const;
231 
232 
236  using const_iterator_value = std::pair<const key_type, mapped_type>;
237 
238 
248  class const_iterator
249  : public boost::iterator_facade<const_iterator,
250  const const_iterator_value,
251  std::bidirectional_iterator_tag,
252  const const_iterator_value>
253  {
254  public:
259  const_iterator (typename Impl_t::const_iterator it);
260 
261 
267  bool valid() const;
268 
269 
270  private:
272  friend class boost::iterator_core_access;
273 
274 
278  void increment();
279 
280 
284  void decrement();
285 
286 
290  bool equal (const const_iterator& other) const;
291 
292 
296  const const_iterator_value dereference() const;
297 
298 
300  typename Impl_t::const_iterator m_impl;
301  };
302 
303 
305  typedef boost::iterator_range<const_iterator> const_iterator_range;
306 
307 
311  const_iterator_range range() const;
312 
313 
317  const_iterator begin() const;
318 
319 
323  const_iterator end() const;
324 
325 
329  const_iterator cbegin() const;
330 
331 
335  const_iterator cend() const;
336 
337 
342  bool contains (key_type key) const;
343 
344 
351  size_type count (key_type key) const;
352 
353 
360  const_iterator find (key_type key) const;
361 
362 
370  mapped_type at (key_type key) const;
371 
372 
380  std::pair<const_iterator, const_iterator>
381  equal_range (key_type key) const;
382 
383 
392  Lock_t lock();
393 
394 
406  std::pair<const_iterator, bool>
407  emplace (key_type key, mapped_type val,
408  const Context_t& ctx = Updater_t::defaultContext());
409 
410 
423  std::pair<const_iterator, bool>
424  emplace (const Lock_t& lock,
425  key_type key, mapped_type val,
426  const Context_t& ctx = Updater_t::defaultContext());
427 
428 
440  std::pair<const_iterator, bool>
441  insert_or_assign (key_type key, mapped_type val,
442  const Context_t& ctx = Updater_t::defaultContext());
443 
444 
458  std::pair<const_iterator, bool>
459  insert_or_assign (const Lock_t& lock,
460  key_type key, mapped_type val,
461  const Context_t& ctx = Updater_t::defaultContext());
462 
463 
477  template <class PAIR>
478  std::pair<const_iterator, bool> insert (const PAIR& p);
479 
480 
489  template <class InputIterator>
490  void insert (InputIterator first, InputIterator last);
491 
492 
505  bool erase (key_type key);
506 
507 
521  bool erase (const Lock_t& lock, key_type key);
522 
523 
532  void reserve (size_type capacity,
533  const Context_t& ctx = Updater_t::defaultContext());
534 
535 
543  void rehash (size_type capacity);
544 
545 
551  void clear (size_t capacity,
552  const Context_t& ctx = Updater_t::defaultContext());
553 
554 
559  void clear (const Context_t& ctx = Updater_t::defaultContext());
560 
561 
570  void forceClear();
571 
572 
578  void quiescent (const Context_t& ctx);
579 
580 
592  void swap (ConcurrentMap& other);
593 
594 
598  Updater_t& updater();
599 
600 
601 private:
606  static key_type keyAsKey (val_t val);
607 
608 
613  static val_t keyAsVal (key_type k);
614 
615 
620  static mapped_type mappedAsMapped (val_t val);
621 
622 
627  static val_t mappedAsVal (mapped_type val);
628 
629 
637  typename Impl_t::const_iterator get (key_type key) const;
638 
639 
651  std::pair<const_iterator, bool>
652  put (key_type key,
653  mapped_type val,
654  bool overwrite = true,
655  const Context_t& ctx = Updater_t::defaultContext());
656 
657 
670  std::pair<const_iterator, bool>
671  put (const Lock_t& lock,
672  key_type key,
673  mapped_type val,
674  bool overwrite = true,
675  const Context_t& ctx = Updater_t::defaultContext());
676 
677 
679  Impl_t m_impl;
680 };
681 
682 
683 } // namespace CxxUtils
684 
685 
687 
688 
689 #endif // not CXXUTILS_CONCURRENTMAP_H
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CxxUtils::detail::ConcurrentHashmapVal_t
uintptr_t ConcurrentHashmapVal_t
Type used for keys and values — an unsigned big enough to hold a pointer.
Definition: ConcurrentHashmapImpl.h:41
IsUpdater.h
Concept check for Updater class used by concurrent classes.
skel.it
it
Definition: skel.GENtoEVGEN.py:423
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
CxxUtils::detail::ConcurrentHashmapImpl
Hash table allowing concurrent, lockless reads.
Definition: ConcurrentHashmapImpl.h:208
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
CxxUtils::fpcompare::equal
bool equal(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition: fpcompare.h:114
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
calibdata.valid
list valid
Definition: calibdata.py:45
CxxUtils
Definition: aligned_vector.h:29
contains
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition: hcg.cxx:111
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
VALUE
#define VALUE(TESTED)
Definition: expect.h:59
UIntConv.h
Helpers for converting between uintptr_t and a pointer or integer.
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
CxxUtils::end
auto end(range_with_at< T > &s)
Definition: range_with_at.h:68
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
ConcurrentMap.icc
concepts.h
Compatibility helpers for using some pieces of C++20 concepts with older compilers.
a
TList * a
Definition: liststreamerinfos.cxx:10
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
VKalVrtAthena::varHolder_detail::clear
void clear(T &var)
Definition: NtupleVars.h:48
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
DeMoScan.first
bool first
Definition: DeMoScan.py:534
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
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
fitman.k
k
Definition: fitman.py:528
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
CxxUtils::begin
auto begin(range_with_at< T > &s)
Definition: range_with_at.h:64
ConcurrentHashmapImpl.h
Hash table allowing concurrent, lockless reads.