3 #ifndef CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
4 #define CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
6 #include <cds/container/impl/bronson_avltree_map_rcu.h>
8 namespace cds { namespace container {
10 namespace bronson_avltree {
13 template < class RCU, typename Key, typename T, typename Traits>
17 typedef T mapped_type;
18 typedef Traits original_traits;
20 typedef cds::details::Allocator< mapped_type, typename original_traits::allocator > cxx_allocator;
22 struct traits : public original_traits
25 void operator()( mapped_type * p ) const
27 cxx_allocator().Delete( p );
32 // Metafunction result
33 typedef BronsonAVLTreeMap< RCU, Key, T *, traits > type;
35 } // namespace details
37 } // namespace bronson_avltree
39 /// Bronson et al AVL-tree (RCU specialization)
40 /** @ingroup cds_nonintrusive_map
41 @ingroup cds_nonintrusive_tree
42 @anchor cds_container_BronsonAVLTreeMap_rcu
45 - [2010] N.Bronson, J.Casper, H.Chafi, K.Olukotun "A Practical Concurrent Binary Search Tree"
49 <b>Template arguments</b>:
50 - \p RCU - one of \ref cds_urcu_gc "RCU type"
52 - \p T - value type to be stored in tree's nodes.
53 - \p Traits - tree traits, default is \p bronson_avltree::traits
54 It is possible to declare option-based tree with \p bronson_avltree::make_traits metafunction
55 instead of \p Traits template argument.
57 @note Before including <tt><cds/container/bronson_avltree_map_rcu.h></tt> you should include appropriate RCU header file,
58 see \ref cds_urcu_gc "RCU type" for list of existing RCU class and corresponding header files.
64 # ifdef CDS_DOXYGEN_INVOKED
65 typename Traits = bronson_avltree::traits
70 class BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T, Traits >
71 #ifdef CDS_DOXYGEN_INVOKED
72 : private BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T*, Traits >
74 : private bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits >::type
78 typedef bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits > maker;
79 typedef typename maker::type base_class;
83 typedef cds::urcu::gc<RCU> gc; ///< RCU Garbage collector
84 typedef Key key_type; ///< type of a key stored in the map
85 typedef T mapped_type; ///< type of value stored in the map
86 typedef Traits traits; ///< Traits template parameter
88 typedef typename base_class::key_comparator key_comparator; ///< key compare functor based on \p Traits::compare and \p Traits::less
89 typedef typename traits::item_counter item_counter; ///< Item counting policy
90 typedef typename traits::memory_model memory_model; ///< Memory ordering, see \p cds::opt::memory_model option
91 typedef typename traits::allocator allocator_type; ///< allocator for value
92 typedef typename traits::node_allocator node_allocator_type;///< allocator for maintaining internal nodes
93 typedef typename traits::stat stat; ///< internal statistics
94 typedef typename traits::rcu_check_deadlock rcu_check_deadlock; ///< Deadlock checking policy
95 typedef typename traits::back_off back_off; ///< Back-off strategy
96 typedef typename traits::sync_monitor sync_monitor; ///< @ref cds_sync_monitor "Synchronization monitor" type for node-level locking
98 /// Enabled or disabled @ref bronson_avltree::relaxed_insert "relaxed insertion"
99 static bool const c_bRelaxedInsert = traits::relaxed_insert;
101 /// Returned pointer to value of extracted node
102 typedef typename base_class::unique_ptr unique_ptr;
104 typedef typename base_class::rcu_lock rcu_lock; ///< RCU scoped lock
108 typedef typename base_class::node_type node_type;
109 typedef typename base_class::node_scoped_lock node_scoped_lock;
110 typedef typename maker::cxx_allocator cxx_allocator;
112 typedef typename base_class::update_flags update_flags;
116 /// Creates empty map
124 /// Inserts new node with \p key and default value
126 The function creates a node with \p key and default value, and then inserts the node created into the map.
129 - The \p key_type should be constructible from a value of type \p K.
130 - The \p mapped_type should be default-constructible.
132 RCU \p synchronize() can be called. RCU should not be locked.
134 Returns \p true if inserting successful, \p false otherwise.
136 template <typename K>
137 bool insert( K const& key )
139 return base_class::do_update(key, key_comparator(),
140 []( node_type * pNode ) -> mapped_type*
142 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
144 return cxx_allocator().New();
146 static_cast<int>(update_flags::allow_insert)
147 ) == static_cast<int>(update_flags::result_inserted);
152 The function creates a node with copy of \p val value
153 and then inserts the node created into the map.
156 - The \p key_type should be constructible from \p key of type \p K.
157 - The \p mapped_type should be constructible from \p val of type \p V.
159 RCU \p synchronize() method can be called. RCU should not be locked.
161 Returns \p true if \p val is inserted into the map, \p false otherwise.
163 template <typename K, typename V>
164 bool insert( K const& key, V const& val )
166 return base_class::do_update( key, key_comparator(),
167 [&val]( node_type * pNode )
169 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
171 return cxx_allocator().New( val );
173 static_cast<int>(update_flags::allow_insert)
174 ) == static_cast<int>(update_flags::result_inserted);
177 /// Inserts new node and initialize it by a functor
179 This function inserts new node with key \p key and if inserting is successful then it calls
180 \p func functor with signature
183 void operator()( key_type const& key, mapped_type& item );
187 The key_type should be constructible from value of type \p K.
189 The function allows to split creating of new item into two part:
190 - create item from \p key;
191 - insert new item into the map;
192 - if inserting is successful, initialize the value of item by calling \p func functor
194 This can be useful if complete initialization of object of \p value_type is heavyweight and
195 it is preferable that the initialization should be completed only if inserting is successful.
196 The functor is called under the node lock.
198 RCU \p synchronize() method can be called. RCU should not be locked.
200 template <typename K, typename Func>
201 bool insert_with( K const& key, Func func )
203 return base_class::do_update( key, key_comparator(),
204 [&func]( node_type * pNode ) -> mapped_type*
206 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
207 mapped_type * pVal = cxx_allocator().New();
208 func( pNode->m_key, *pVal );
211 static_cast<int>(update_flags::allow_insert)
212 ) == static_cast<int>(update_flags::result_inserted);
215 /// For key \p key inserts data of type \p mapped_type created in-place from \p args
217 Returns \p true if inserting successful, \p false otherwise.
219 RCU \p synchronize() method can be called. RCU should not be locked.
221 template <typename K, typename... Args>
222 bool emplace( K&& key, Args&&... args )
224 return base_class::do_update( key, key_comparator(),
225 [&]( node_type * pNode ) -> mapped_type*
227 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
229 return cxx_allocator().New( std::forward<Args>(args)...);
231 static_cast<int>(update_flags::allow_insert)
232 ) == static_cast<int>(update_flags::result_inserted);
235 /// Ensures that the \p key exists in the map
237 The operation performs inserting or changing data with lock-free manner.
239 If the \p key not found in the map, then the new item created from \p key
240 is inserted into the map (note that in this case the \ref key_type should be
241 constructible from type \p K).
242 Otherwise, the functor \p func is called with item found.
243 The functor \p Func may be a functor:
246 void operator()( bool bNew, key_type const& key, mapped_type& item );
251 - \p bNew - \p true if the item has been inserted, \p false otherwise
254 The functor may change any fields of the \p item. The functor is called under the node lock.
256 RCU \p synchronize() method can be called. RCU should not be locked.
258 Returns <tt> std::pair<bool, bool> </tt> where \p first is \p true if operation is successfull,
259 \p second is \p true if new item has been added or \p false if the item with \p key
260 already is in the tree.
262 template <typename K, typename Func>
263 std::pair<bool, bool> update( K const& key, Func func )
265 int result = base_class::do_update( key, key_comparator(),
266 [&func]( node_type * pNode ) -> mapped_type*
268 mapped_type * pVal = pNode->m_pValue.load( memory_model::memory_order_relaxed );
270 pVal = cxx_allocator().New();
271 func( true, pNode->m_key, *pVal );
274 func( false, pNode->m_key, *pVal );
277 update_flags::allow_insert | update_flags::allow_update
279 return std::make_pair( result != 0, (result & update_flags::result_inserted) != 0 );
282 /// Delete \p key from the map
284 RCU \p synchronize() method can be called. RCU should not be locked.
286 Return \p true if \p key is found and deleted, \p false otherwise
288 template <typename K>
289 bool erase( K const& key )
291 return base_class::erase( key );
294 /// Deletes the item from the map using \p pred predicate for searching
296 The function is an analog of \p erase(K const&)
297 but \p pred is used for key comparing.
298 \p Less functor has the interface like \p std::less.
299 \p Less must imply the same element order as the comparator used for building the map.
301 template <typename K, typename Less>
302 bool erase_with( K const& key, Less pred )
304 return base_class::erase_with( key, pred );
307 /// Delete \p key from the map
308 /** \anchor cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func
310 The function searches an item with key \p key, calls \p f functor
311 and deletes the item. If \p key is not found, the functor is not called.
313 The functor \p Func interface:
316 void operator()(mapped_type& item) { ... }
320 RCU \p synchronize method can be called. RCU should not be locked.
322 Return \p true if key is found and deleted, \p false otherwise
324 template <typename K, typename Func>
325 bool erase( K const& key, Func f )
327 return base_class::erase( key, f );
330 /// Deletes the item from the map using \p pred predicate for searching
332 The function is an analog of \ref cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func "erase(K const&, Func)"
333 but \p pred is used for key comparing.
334 \p Less functor has the interface like \p std::less.
335 \p Less must imply the same element order as the comparator used for building the map.
337 template <typename K, typename Less, typename Func>
338 bool erase_with( K const& key, Less pred, Func f )
340 return base_class::erase_with( key, pred, f );
343 /// Extracts an item with minimal key from the map
345 Returns \p std::unique_ptr pointer to the leftmost item.
346 If the set is empty, returns empty \p std::unique_ptr.
348 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
349 It means that the function gets leftmost leaf of the tree and tries to unlink it.
350 During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
351 So, the function returns the item with minimum key at the moment of tree traversing.
353 RCU \p synchronize method can be called. RCU should NOT be locked.
354 The function does not free the item.
355 The deallocator will be implicitly invoked when the returned object is destroyed or when
356 its \p reset(nullptr) member function is called.
358 unique_ptr extract_min()
360 return base_class::extract_min();
363 /// Extracts an item with maximal key from the map
365 Returns \p std::unique_ptr pointer to the rightmost item.
366 If the set is empty, returns empty \p std::unique_ptr.
368 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
369 It means that the function gets rightmost leaf of the tree and tries to unlink it.
370 During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
371 So, the function returns the item with maximum key at the moment of tree traversing.
373 RCU \p synchronize method can be called. RCU should NOT be locked.
374 The function does not free the item.
375 The deallocator will be implicitly invoked when the returned object is destroyed or when
376 its \p reset(nullptr) is called.
377 @note Before reusing \p result object you should call its \p release() method.
379 unique_ptr extract_max()
381 return base_class::extract_min();
384 /// Extracts an item from the map
386 The function searches an item with key equal to \p key in the tree,
387 unlinks it, and returns \p std::unique_ptr pointer to a value found.
388 If \p key is not found the function returns an empty \p std::unique_ptr.
390 RCU \p synchronize method can be called. RCU should NOT be locked.
391 The function does not destroy the value found.
392 The dealloctor will be implicitly invoked when the returned object is destroyed or when
393 its \p reset(nullptr) member function is called.
395 template <typename Q>
396 unique_ptr extract( Q const& key )
398 return base_class::extract( key );
401 /// Extracts an item from the map using \p pred for searching
403 The function is an analog of \p extract(Q const&)
404 but \p pred is used for key compare.
405 \p Less has the interface like \p std::less and should meet \ref cds_container_EllenBinTreeSet_rcu_less
406 "predicate requirements".
407 \p pred must imply the same element order as the comparator used for building the map.
409 template <typename Q, typename Less>
410 unique_ptr extract_with( Q const& key, Less pred )
412 return base_class::extract_with( key, pred );
415 /// Find the key \p key
417 The function searches the item with key equal to \p key and calls the functor \p f for item found.
418 The interface of \p Func functor is:
421 void operator()( mapped_type& item );
424 where \p item is the item found.
425 The functor is called under node-level lock.
427 The function applies RCU lock internally.
429 The function returns \p true if \p key is found, \p false otherwise.
431 template <typename K, typename Func>
432 bool find( K const& key, Func f )
434 return base_class::find( key, f );
437 /// Finds the key \p val using \p pred predicate for searching
439 The function is an analog of \p find(K const&, Func)
440 but \p pred is used for key comparing.
441 \p Less functor has the interface like \p std::less.
442 \p Less must imply the same element order as the comparator used for building the map.
444 template <typename K, typename Less, typename Func>
445 bool find_with( K const& key, Less pred, Func f )
447 return base_class::find_with( key, pred, f );
450 /// Find the key \p key
452 The function searches the item with key equal to \p key
453 and returns \p true if it is found, and \p false otherwise.
455 The function applies RCU lock internally.
457 template <typename K>
458 bool find( K const& key )
460 return base_class::find( key );
463 /// Finds the key \p val using \p pred predicate for searching
465 The function is an analog of \p find(K const&)
466 but \p pred is used for key comparing.
467 \p Less functor has the interface like \p std::less.
468 \p Less must imply the same element order as the comparator used for building the map.
470 template <typename K, typename Less>
471 bool find_with( K const& key, Less pred )
473 return base_class::find_with( key, pred );
482 /// Checks if the map is empty
485 return base_class::empty();
488 /// Returns item count in the map
490 Only leaf nodes containing user data are counted.
492 The value returned depends on item counter type provided by \p Traits template parameter.
493 If it is \p atomicity::empty_item_counter this function always returns 0.
495 The function is not suitable for checking the tree emptiness, use \p empty()
496 member function for this purpose.
500 return base_class::size();
503 /// Returns const reference to internal statistics
504 stat const& statistics() const
506 return base_class::statistics();
509 /// Checks internal consistency (not atomic, not thread-safe)
511 The debugging function to check internal consistency of the tree.
513 bool check_consistency() const
515 return base_class::check_consistency();
518 }} // namespace cds::container
520 #endif // #ifndef CDSLIB_CONTAINER_IMPL_BRONSON_AVLTREE_MAP_RCU_H