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, mapped_type *, 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"
46 - <a href="http://github.com/nbronson/snaptree">Java implementation</a>
48 This is a concurrent AVL tree algorithm that uses hand-over-hand optimistic validation,
49 a concurrency control mechanism for searching and navigating a binary search tree.
50 This mechanism minimizes spurious retries when concurrent structural changes cannot
51 affect the correctness of the search or navigation result. The algorithm is based on
52 partially external trees, a simple scheme that simplifies deletions by leaving a routing
53 node in the tree when deleting a node that has two children, then opportunistically unlinking
54 routing nodes during rebalancing. As in external trees, which store values only in leaf nodes,
55 deletions can be performed locally while holding a fixed number of locks. Partially
56 external trees, however, require far fewer routing nodes than an external tree for most sequences
57 of insertions and deletions.
59 <b>Template arguments</b>:
60 - \p RCU - one of \ref cds_urcu_gc "RCU type"
62 - \p T - value type to be stored in tree's nodes.
63 - \p Traits - tree traits, default is \p bronson_avltree::traits
64 It is possible to declare option-based tree with \p bronson_avltree::make_traits metafunction
65 instead of \p Traits template argument.
67 There is \ref cds_container_BronsonAVLTreeMap_rcu_ptr "a specialization" for "key -> value pointer" map.
69 @note Before including <tt><cds/container/bronson_avltree_map_rcu.h></tt> you should include appropriate RCU header file,
70 see \ref cds_urcu_gc "RCU type" for list of existing RCU class and corresponding header files.
76 # ifdef CDS_DOXYGEN_INVOKED
77 typename Traits = bronson_avltree::traits
82 class BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T, Traits >
83 #ifdef CDS_DOXYGEN_INVOKED
84 : private BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T*, Traits >
86 : private bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits >::type
90 typedef bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits > maker;
91 typedef typename maker::type base_class;
95 typedef cds::urcu::gc<RCU> gc; ///< RCU Garbage collector
96 typedef Key key_type; ///< type of a key stored in the map
97 typedef T mapped_type; ///< type of value stored in the map
98 typedef Traits traits; ///< Traits template parameter
100 typedef typename base_class::key_comparator key_comparator; ///< key compare functor based on \p Traits::compare and \p Traits::less
101 typedef typename traits::item_counter item_counter; ///< Item counting policy
102 typedef typename traits::memory_model memory_model; ///< Memory ordering, see \p cds::opt::memory_model option
103 typedef typename traits::allocator allocator_type; ///< allocator for value
104 typedef typename traits::node_allocator node_allocator_type;///< allocator for maintaining internal nodes
105 typedef typename traits::stat stat; ///< internal statistics
106 typedef typename traits::rcu_check_deadlock rcu_check_deadlock; ///< Deadlock checking policy
107 typedef typename traits::back_off back_off; ///< Back-off strategy
108 typedef typename traits::sync_monitor sync_monitor; ///< @ref cds_sync_monitor "Synchronization monitor" type for node-level locking
110 /// Enabled or disabled @ref bronson_avltree::relaxed_insert "relaxed insertion"
111 static bool const c_bRelaxedInsert = traits::relaxed_insert;
112 typedef typename base_class::rcu_lock rcu_lock; ///< RCU scoped lock
114 /// Returned pointer to \p mapped_type of extracted node
115 typedef typename base_class::exempt_ptr exempt_ptr;
119 typedef typename base_class::node_type node_type;
120 typedef typename base_class::node_scoped_lock node_scoped_lock;
121 typedef typename maker::cxx_allocator cxx_allocator;
123 typedef typename base_class::update_flags update_flags;
127 /// Creates empty map
135 /// Inserts new node with \p key and default value
137 The function creates a node with \p key and default value, and then inserts the node created into the map.
140 - The \p key_type should be constructible from a value of type \p K.
141 - The \p mapped_type should be default-constructible.
143 RCU \p synchronize() can be called. RCU should not be locked.
145 Returns \p true if inserting successful, \p false otherwise.
147 template <typename K>
148 bool insert( K const& key )
150 return base_class::do_update(key, key_comparator(),
151 []( node_type * pNode ) -> mapped_type*
153 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
155 return cxx_allocator().New();
157 update_flags::allow_insert
158 ) == update_flags::result_inserted;
163 The function creates a node with copy of \p val value
164 and then inserts the node created into the map.
167 - The \p key_type should be constructible from \p key of type \p K.
168 - The \p mapped_type should be constructible from \p val of type \p V.
170 RCU \p synchronize() method can be called. RCU should not be locked.
172 Returns \p true if \p val is inserted into the map, \p false otherwise.
174 template <typename K, typename V>
175 bool insert( K const& key, V const& val )
177 return base_class::do_update( key, key_comparator(),
178 [&val]( node_type * pNode ) -> mapped_type*
180 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
182 return cxx_allocator().New( val );
184 update_flags::allow_insert
185 ) == update_flags::result_inserted;
188 /// Inserts new node and initialize it by a functor
190 This function inserts new node with key \p key and if inserting is successful then it calls
191 \p func functor with signature
194 void operator()( key_type const& key, mapped_type& item );
198 The key_type should be constructible from value of type \p K.
200 The function allows to split creating of new item into two part:
201 - create item from \p key;
202 - insert new item into the map;
203 - if inserting is successful, initialize the value of item by calling \p func functor
205 This can be useful if complete initialization of object of \p value_type is heavyweight and
206 it is preferable that the initialization should be completed only if inserting is successful.
207 The functor is called under the node lock.
209 RCU \p synchronize() method can be called. RCU should not be locked.
211 template <typename K, typename Func>
212 bool insert_with( K const& key, Func func )
214 return base_class::do_update( key, key_comparator(),
215 [&func]( node_type * pNode ) -> mapped_type*
217 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
218 mapped_type * pVal = cxx_allocator().New();
219 func( pNode->m_key, *pVal );
222 update_flags::allow_insert
223 ) == update_flags::result_inserted;
226 /// For key \p key inserts data of type \p mapped_type created in-place from \p args
228 Returns \p true if inserting successful, \p false otherwise.
230 RCU \p synchronize() method can be called. RCU should not be locked.
232 template <typename K, typename... Args>
233 bool emplace( K&& key, Args&&... args )
235 return base_class::do_update( key, key_comparator(),
236 [&]( node_type * pNode ) -> mapped_type*
238 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
240 return cxx_allocator().New( std::forward<Args>(args)...);
242 update_flags::allow_insert
243 ) == update_flags::result_inserted;
246 /// Ensures that the \p key exists in the map
248 The operation performs inserting or changing data with lock-free manner.
250 If the \p key not found in the map, then the new item created from \p key
251 will be inserted into the map (note that in this case the \ref key_type should be
252 constructible from type \p K).
253 Otherwise, the functor \p func is called with item found.
254 The functor \p Func may be a functor:
257 void operator()( bool bNew, key_type const& key, mapped_type& item );
262 - \p bNew - \p true if the item has been inserted, \p false otherwise
265 The functor may change any fields of the \p item. The functor is called under the node lock.
267 RCU \p synchronize() method can be called. RCU should not be locked.
269 Returns <tt> std::pair<bool, bool> </tt> where \p first is \p true if operation is successfull,
270 \p second is \p true if new item has been added or \p false if the item with \p key
273 template <typename K, typename Func>
274 std::pair<bool, bool> update( K const& key, Func func )
276 int result = base_class::do_update( key, key_comparator(),
277 [&func]( node_type * pNode ) -> mapped_type*
279 mapped_type * pVal = pNode->m_pValue.load( memory_model::memory_order_relaxed );
281 pVal = cxx_allocator().New();
282 func( true, pNode->m_key, *pVal );
285 func( false, pNode->m_key, *pVal );
288 update_flags::allow_insert | update_flags::allow_update
290 return std::make_pair( result != 0, (result & update_flags::result_inserted) != 0 );
293 /// Delete \p key from the map
295 RCU \p synchronize() method can be called. RCU should not be locked.
297 Return \p true if \p key is found and deleted, \p false otherwise
299 template <typename K>
300 bool erase( K const& key )
302 return base_class::erase( key );
305 /// Deletes the item from the map using \p pred predicate for searching
307 The function is an analog of \p erase(K const&)
308 but \p pred is used for key comparing.
309 \p Less functor has the interface like \p std::less.
310 \p Less must imply the same element order as the comparator used for building the map.
312 template <typename K, typename Less>
313 bool erase_with( K const& key, Less pred )
315 return base_class::erase_with( key, pred );
318 /// Delete \p key from the map
319 /** \anchor cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func
321 The function searches an item with key \p key, calls \p f functor
322 and deletes the item. If \p key is not found, the functor is not called.
324 The functor \p Func interface:
327 void operator()(mapped_type& item) { ... }
331 RCU \p synchronize method can be called. RCU should not be locked.
333 Return \p true if key is found and deleted, \p false otherwise
335 template <typename K, typename Func>
336 bool erase( K const& key, Func f )
338 return base_class::erase( key, f );
341 /// Deletes the item from the map using \p pred predicate for searching
343 The function is an analog of \ref cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func "erase(K const&, Func)"
344 but \p pred is used for key comparing.
345 \p Less functor has the interface like \p std::less.
346 \p Less must imply the same element order as the comparator used for building the map.
348 template <typename K, typename Less, typename Func>
349 bool erase_with( K const& key, Less pred, Func f )
351 return base_class::erase_with( key, pred, f );
354 /// Extracts a value with minimal key from the map
356 Returns \p exempt_ptr pointer to the leftmost item.
357 If the set is empty, returns empty \p exempt_ptr.
359 Note that the function returns only the value for minimal key.
360 To retrieve its key use \p extract_min( Func ) member function.
362 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
363 It means that the function gets leftmost leaf of the tree and tries to unlink it.
364 During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
365 So, the function returns the item with minimum key at the moment of tree traversing.
367 RCU \p synchronize method can be called. RCU should NOT be locked.
368 The function does not free the item.
369 The deallocator will be implicitly invoked when the returned object is destroyed or when
370 its \p release() member function is called.
372 exempt_ptr extract_min()
374 return base_class::extract_min();
377 /// Extracts minimal key key and corresponding value
379 Returns \p exempt_ptr to the leftmost item.
380 If the tree is empty, returns empty \p exempt_ptr.
382 \p Func functor is used to store minimal key.
383 \p Func has the following signature:
386 void operator()( key_type const& key );
389 If the tree is empty, \p f is not called.
390 Otherwise, is it called with minimal key, the pointer to corresponding value is returned
393 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
394 It means that the function gets leftmost leaf of the tree and tries to unlink it.
395 During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
396 So, the function returns the item with minimum key at the moment of tree traversing.
398 RCU \p synchronize method can be called. RCU should NOT be locked.
399 The function does not free the item.
400 The deallocator will be implicitly invoked when the returned object is destroyed or when
401 its \p release() member function is called.
403 template <typename Func>
404 exempt_ptr extract_min( Func f )
406 return base_class::extract_min( f );
409 /// Extracts minimal key key and corresponding value
411 This function is a shortcut for the following call:
414 exempt_ptr xp = theTree.extract_min( [&key]( key_type const& k ) { key = k; } );
416 \p key_type should be copy-assignable. The copy of minimal key
417 is returned in \p min_key argument.
419 typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
420 extract_min_key( key_type& min_key )
422 return base_class::extract_min_key( min_key );
425 /// Extracts an item with maximal key from the map
427 Returns \p exempt_ptr pointer to the rightmost item.
428 If the set is empty, returns empty \p exempt_ptr.
430 Note that the function returns only the value for maximal key.
431 To retrieve its key use \p extract_max( Func ) or \p extract_max_key(key_type&) member function.
433 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
434 It means that the function gets rightmost leaf of the tree and tries to unlink it.
435 During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
436 So, the function returns the item with maximum key at the moment of tree traversing.
438 RCU \p synchronize method can be called. RCU should NOT be locked.
439 The function does not free the item.
440 The deallocator will be implicitly invoked when the returned object is destroyed or when
441 its \p release() is called.
443 exempt_ptr extract_max()
445 return base_class::extract_max();
448 /// Extracts the maximal key and corresponding value
450 Returns \p exempt_ptr pointer to the rightmost item.
451 If the set is empty, returns empty \p exempt_ptr.
453 \p Func functor is used to store maximal key.
454 \p Func has the following signature:
457 void operator()( key_type const& key );
460 If the tree is empty, \p f is not called.
461 Otherwise, is it called with maximal key, the pointer to corresponding value is returned
464 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
465 It means that the function gets rightmost leaf of the tree and tries to unlink it.
466 During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
467 So, the function returns the item with maximum key at the moment of tree traversing.
469 RCU \p synchronize method can be called. RCU should NOT be locked.
470 The function does not free the item.
471 The deallocator will be implicitly invoked when the returned object is destroyed or when
472 its \p release() is called.
474 template <typename Func>
475 exempt_ptr extract_max( Func f )
477 return base_class::extract_max( f );
480 /// Extracts the maximal key and corresponding value
482 This function is a shortcut for the following call:
485 exempt_ptr xp = theTree.extract_max( [&key]( key_type const& k ) { key = k; } );
487 \p key_type should be copy-assignable. The copy of maximal key
488 is returned in \p max_key argument.
490 typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
491 extract_max_key( key_type& max_key )
493 return base_class::extract_max_key( max_key );
496 /// Extracts an item from the map
498 The function searches an item with key equal to \p key in the tree,
499 unlinks it, and returns \p exempt_ptr pointer to a value found.
500 If \p key is not found the function returns an empty \p exempt_ptr.
502 RCU \p synchronize method can be called. RCU should NOT be locked.
503 The function does not destroy the value found.
504 The dealloctor will be implicitly invoked when the returned object is destroyed or when
505 its \p release() member function is called.
507 template <typename Q>
508 exempt_ptr extract( Q const& key )
510 return base_class::extract( key );
513 /// Extracts an item from the map using \p pred for searching
515 The function is an analog of \p extract(Q const&)
516 but \p pred is used for key compare.
517 \p Less has the interface like \p std::less.
518 \p pred must imply the same element order as the comparator used for building the map.
520 template <typename Q, typename Less>
521 exempt_ptr extract_with( Q const& key, Less pred )
523 return base_class::extract_with( key, pred );
526 /// Find the key \p key
528 The function searches the item with key equal to \p key and calls the functor \p f for item found.
529 The interface of \p Func functor is:
532 void operator()( key_type const& key, mapped_type& val );
535 where \p val is the item found for \p key
536 The functor is called under node-level lock.
538 The function applies RCU lock internally.
540 The function returns \p true if \p key is found, \p false otherwise.
542 template <typename K, typename Func>
543 bool find( K const& key, Func f )
545 return base_class::find( key, f );
548 /// Finds the key \p val using \p pred predicate for searching
550 The function is an analog of \p find(K const&, Func)
551 but \p pred is used for key comparing.
552 \p Less functor has the interface like \p std::less.
553 \p Less must imply the same element order as the comparator used for building the map.
555 template <typename K, typename Less, typename Func>
556 bool find_with( K const& key, Less pred, Func f )
558 return base_class::find_with( key, pred, f );
561 /// Find the key \p key
563 The function searches the item with key equal to \p key
564 and returns \p true if it is found, and \p false otherwise.
566 The function applies RCU lock internally.
568 template <typename K>
569 bool find( K const& key )
571 return base_class::find( key );
574 /// Finds the key \p val using \p pred predicate for searching
576 The function is an analog of \p find(K const&)
577 but \p pred is used for key comparing.
578 \p Less functor has the interface like \p std::less.
579 \p Less must imply the same element order as the comparator used for building the map.
581 template <typename K, typename Less>
582 bool find_with( K const& key, Less pred )
584 return base_class::find_with( key, pred );
593 /// Checks if the map is empty
596 return base_class::empty();
599 /// Returns item count in the map
601 Only leaf nodes containing user data are counted.
603 The value returned depends on item counter type provided by \p Traits template parameter.
604 If it is \p atomicity::empty_item_counter this function always returns 0.
606 The function is not suitable for checking the tree emptiness, use \p empty()
607 member function for this purpose.
611 return base_class::size();
614 /// Returns const reference to internal statistics
615 stat const& statistics() const
617 return base_class::statistics();
620 /// Checks internal consistency (not atomic, not thread-safe)
622 The debugging function to check internal consistency of the tree.
624 bool check_consistency() const
626 return base_class::check_consistency();
629 /// Checks internal consistency (not atomic, not thread-safe)
631 The debugging function to check internal consistency of the tree.
632 The functor \p Func is called if a violation of internal tree structure
636 void operator()( size_t nLevel, size_t hLeft, size_t hRight );
640 - \p nLevel - the level where the violation is found
641 - \p hLeft - the height of left subtree
642 - \p hRight - the height of right subtree
644 The functor is called for each violation found.
646 template <typename Func>
647 bool check_consistency( Func f ) const
649 return base_class::check_consistency( f );
652 }} // namespace cds::container
654 #endif // #ifndef CDSLIB_CONTAINER_IMPL_BRONSON_AVLTREE_MAP_RCU_H