3 #ifndef CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
4 #define CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
7 #include <cds/container/impl/bronson_avltree_map_rcu.h>
9 namespace cds { namespace container {
11 namespace bronson_avltree {
14 template < class RCU, typename Key, typename T, typename Traits>
18 typedef T mapped_type;
19 typedef Traits original_traits;
21 typedef cds::details::Allocator< mapped_type, typename original_traits::allocator > cxx_allocator;
23 struct traits : public original_traits
26 void operator()( mapped_type * p ) const
28 cxx_allocator().Delete( p );
33 // Metafunction result
34 typedef BronsonAVLTreeMap< RCU, Key, mapped_type *, traits > type;
36 } // namespace details
38 } // namespace bronson_avltree
40 /// Bronson et al AVL-tree (RCU specialization)
41 /** @ingroup cds_nonintrusive_map
42 @ingroup cds_nonintrusive_tree
43 @anchor cds_container_BronsonAVLTreeMap_rcu
46 - [2010] N.Bronson, J.Casper, H.Chafi, K.Olukotun "A Practical Concurrent Binary Search Tree"
47 - <a href="http://github.com/nbronson/snaptree">Java implementation</a>
49 This is a concurrent AVL tree algorithm that uses hand-over-hand optimistic validation,
50 a concurrency control mechanism for searching and navigating a binary search tree.
51 This mechanism minimizes spurious retries when concurrent structural changes cannot
52 affect the correctness of the search or navigation result.
53 The algorithm is based on partially external trees, a simple scheme that simplifies deletions
54 by leaving a routing node in the tree when deleting a node that has two children,
55 then opportunistically unlinking routing nodes during rebalancing. As in external trees,
56 which store values only in leaf nodes, deletions can be performed locally while holding
57 a fixed number of locks. Partially external trees, however, require far fewer routing nodes
58 than an external tree for most sequences of insertions and deletions.
59 The algorithm uses optimistic concurrency control, but carefully manage the
60 tree in such a way that all atomic regions have fixed read and write sets
61 that are known ahead of time. This allows to reduce practical overheads by embedding
62 the concurrency control directly. To perform tree operations using only fixed sized
63 atomic regions the algo uses the following mechanisms: search operations overlap atomic blocks as
64 in the hand-over-hand locking technique; mutations perform rebalancing separately;
65 and deletions occasionally leave a routing node in the tree.
67 <b>Template arguments</b>:
68 - \p RCU - one of \ref cds_urcu_gc "RCU type"
70 - \p T - value type to be stored in tree's nodes.
71 - \p Traits - tree traits, default is \p bronson_avltree::traits
72 It is possible to declare option-based tree with \p bronson_avltree::make_traits metafunction
73 instead of \p Traits template argument.
75 There is \ref cds_container_BronsonAVLTreeMap_rcu_ptr "a specialization" for "key -> value pointer" map.
77 @note Before including <tt><cds/container/bronson_avltree_map_rcu.h></tt> you should include appropriate RCU header file,
78 see \ref cds_urcu_gc "RCU type" for list of existing RCU class and corresponding header files.
84 # ifdef CDS_DOXYGEN_INVOKED
85 typename Traits = bronson_avltree::traits
90 class BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T, Traits >
91 #ifdef CDS_DOXYGEN_INVOKED
92 : private BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T*, Traits >
94 : private bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits >::type
98 typedef bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits > maker;
99 typedef typename maker::type base_class;
103 typedef cds::urcu::gc<RCU> gc; ///< RCU Garbage collector
104 typedef Key key_type; ///< type of a key stored in the map
105 typedef T mapped_type; ///< type of value stored in the map
106 typedef Traits traits; ///< Traits template parameter
108 typedef typename base_class::key_comparator key_comparator; ///< key compare functor based on \p Traits::compare and \p Traits::less
109 typedef typename traits::item_counter item_counter; ///< Item counting policy
110 typedef typename traits::memory_model memory_model; ///< Memory ordering, see \p cds::opt::memory_model option
111 typedef typename traits::allocator allocator_type; ///< allocator for value
112 typedef typename traits::node_allocator node_allocator_type;///< allocator for maintaining internal nodes
113 typedef typename traits::stat stat; ///< internal statistics
114 typedef typename traits::rcu_check_deadlock rcu_check_deadlock; ///< Deadlock checking policy
115 typedef typename traits::back_off back_off; ///< Back-off strategy
116 typedef typename traits::sync_monitor sync_monitor; ///< @ref cds_sync_monitor "Synchronization monitor" type for node-level locking
118 /// Enabled or disabled @ref bronson_avltree::relaxed_insert "relaxed insertion"
119 static bool const c_bRelaxedInsert = traits::relaxed_insert;
121 /// Group of \p extract_xxx functions does not require external locking
122 static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal;
124 typedef typename base_class::rcu_lock rcu_lock; ///< RCU scoped lock
126 /// Returned pointer to \p mapped_type of extracted node
127 typedef typename base_class::exempt_ptr exempt_ptr;
131 typedef typename base_class::node_type node_type;
132 typedef typename base_class::node_scoped_lock node_scoped_lock;
133 typedef typename maker::cxx_allocator cxx_allocator;
135 typedef typename base_class::update_flags update_flags;
139 /// Creates empty map
147 /// Inserts new node with \p key and default value
149 The function creates a node with \p key and default value, and then inserts the node created into the map.
152 - The \p key_type should be constructible from a value of type \p K.
153 - The \p mapped_type should be default-constructible.
155 RCU \p synchronize() can be called. RCU should not be locked.
157 Returns \p true if inserting successful, \p false otherwise.
159 template <typename K>
160 bool insert( K const& key )
162 return base_class::do_update(key, key_comparator(),
163 []( node_type * pNode ) -> mapped_type*
165 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
167 return cxx_allocator().New();
169 update_flags::allow_insert
170 ) == update_flags::result_inserted;
175 The function creates a node with copy of \p val value
176 and then inserts the node created into the map.
179 - The \p key_type should be constructible from \p key of type \p K.
180 - The \p mapped_type should be constructible from \p val of type \p V.
182 RCU \p synchronize() method can be called. RCU should not be locked.
184 Returns \p true if \p val is inserted into the map, \p false otherwise.
186 template <typename K, typename V>
187 bool insert( K const& key, V const& val )
189 return base_class::do_update( key, key_comparator(),
190 [&val]( node_type * pNode ) -> mapped_type*
192 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
194 return cxx_allocator().New( val );
196 update_flags::allow_insert
197 ) == update_flags::result_inserted;
200 /// Inserts new node and initialize it by a functor
202 This function inserts new node with key \p key and if inserting is successful then it calls
203 \p func functor with signature
206 void operator()( key_type const& key, mapped_type& item );
210 The key_type should be constructible from value of type \p K.
212 The function allows to split creating of new item into two part:
213 - create item from \p key;
214 - insert new item into the map;
215 - if inserting is successful, initialize the value of item by calling \p func functor
217 This can be useful if complete initialization of object of \p value_type is heavyweight and
218 it is preferable that the initialization should be completed only if inserting is successful.
219 The functor is called under the node lock.
221 RCU \p synchronize() method can be called. RCU should not be locked.
223 template <typename K, typename Func>
224 bool insert_with( K const& key, Func func )
226 return base_class::do_update( key, key_comparator(),
227 [&func]( node_type * pNode ) -> mapped_type*
229 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
230 mapped_type * pVal = cxx_allocator().New();
231 func( pNode->m_key, *pVal );
234 update_flags::allow_insert
235 ) == update_flags::result_inserted;
238 /// For key \p key inserts data of type \p mapped_type created in-place from \p args
240 Returns \p true if inserting successful, \p false otherwise.
242 RCU \p synchronize() method can be called. RCU should not be locked.
244 template <typename K, typename... Args>
245 bool emplace( K&& key, Args&&... args )
247 # if !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40800 && CDS_COMPILER_VERSION < 40900 )
248 // Probably, the following code is not so efficient, since we pass lvalues instead rvalues to lambda
249 //TODO: study how to pass a parameter pack to a lambda efficiently using perfect forwarding
250 // see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#904 - this is what we need
251 return base_class::do_update( key, key_comparator(),
252 [&args...]( node_type * pNode ) -> mapped_type *
254 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
256 return cxx_allocator().New( std::forward<Args>(args)...);
258 update_flags::allow_insert
259 ) == update_flags::result_inserted;
261 // gcc 4.8 error: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
262 // workaround (from http://stackoverflow.com/questions/14191989/how-do-i-use-variadic-perfect-forwarding-into-a-lambda)
263 auto f = std::bind<mapped_type *>(
264 []( Args... args) -> mapped_type* { return cxx_allocator().New( std::move(args)...); },
265 std::forward<Args>(args)...
267 return base_class::do_update( key, key_comparator(),
268 [&f]( node_type * pNode ) -> mapped_type *
270 assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
274 update_flags::allow_insert
275 ) == update_flags::result_inserted;
279 /// Ensures that the \p key exists in the map
281 The operation performs inserting or changing data with lock-free manner.
283 If the \p key not found in the map, then the new item created from \p key
284 will be inserted into the map (note that in this case the \ref key_type should be
285 constructible from type \p K).
286 Otherwise, the functor \p func is called with item found.
287 The functor \p Func may be a functor:
290 void operator()( bool bNew, key_type const& key, mapped_type& item );
295 - \p bNew - \p true if the item has been inserted, \p false otherwise
298 The functor may change any fields of the \p item. The functor is called under the node lock.
300 RCU \p synchronize() method can be called. RCU should not be locked.
302 Returns <tt> std::pair<bool, bool> </tt> where \p first is \p true if operation is successfull,
303 \p second is \p true if new item has been added or \p false if the item with \p key
306 template <typename K, typename Func>
307 std::pair<bool, bool> update( K const& key, Func func )
309 int result = base_class::do_update( key, key_comparator(),
310 [&func]( node_type * pNode ) -> mapped_type*
312 mapped_type * pVal = pNode->m_pValue.load( memory_model::memory_order_relaxed );
314 pVal = cxx_allocator().New();
315 func( true, pNode->m_key, *pVal );
318 func( false, pNode->m_key, *pVal );
321 update_flags::allow_insert | update_flags::allow_update
323 return std::make_pair( result != 0, (result & update_flags::result_inserted) != 0 );
327 template <typename K, typename Func>
328 std::pair<bool, bool> ensure( K const& key, Func func )
330 return update( key, func );
335 /// Delete \p key from the map
337 RCU \p synchronize() method can be called. RCU should not be locked.
339 Return \p true if \p key is found and deleted, \p false otherwise
341 template <typename K>
342 bool erase( K const& key )
344 return base_class::erase( key );
347 /// Deletes the item from the map using \p pred predicate for searching
349 The function is an analog of \p erase(K const&)
350 but \p pred is used for key comparing.
351 \p Less functor has the interface like \p std::less.
352 \p Less must imply the same element order as the comparator used for building the map.
354 template <typename K, typename Less>
355 bool erase_with( K const& key, Less pred )
357 return base_class::erase_with( key, pred );
360 /// Delete \p key from the map
361 /** \anchor cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func
363 The function searches an item with key \p key, calls \p f functor
364 and deletes the item. If \p key is not found, the functor is not called.
366 The functor \p Func interface:
369 void operator()(key_type const& key, mapped_type& item) { ... }
373 RCU \p synchronize method can be called. RCU should not be locked.
375 Return \p true if key is found and deleted, \p false otherwise
377 template <typename K, typename Func>
378 bool erase( K const& key, Func f )
380 return base_class::erase( key, f );
383 /// Deletes the item from the map using \p pred predicate for searching
385 The function is an analog of \ref cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func "erase(K const&, Func)"
386 but \p pred is used for key comparing.
387 \p Less functor has the interface like \p std::less.
388 \p Less must imply the same element order as the comparator used for building the map.
390 template <typename K, typename Less, typename Func>
391 bool erase_with( K const& key, Less pred, Func f )
393 return base_class::erase_with( key, pred, f );
396 /// Extracts a value with minimal key from the map
398 Returns \p exempt_ptr pointer to the leftmost item.
399 If the set is empty, returns empty \p exempt_ptr.
401 Note that the function returns only the value for minimal key.
402 To retrieve its key use \p extract_min( Func ) member function.
404 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
405 It means that the function gets leftmost leaf of the tree and tries to unlink it.
406 During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
407 So, the function returns the item with minimum key at the moment of tree traversing.
409 RCU \p synchronize method can be called. RCU should NOT be locked.
410 The function does not free the item.
411 The deallocator will be implicitly invoked when the returned object is destroyed or when
412 its \p release() member function is called.
414 exempt_ptr extract_min()
416 return base_class::extract_min();
419 /// Extracts minimal key key and corresponding value
421 Returns \p exempt_ptr to the leftmost item.
422 If the tree is empty, returns empty \p exempt_ptr.
424 \p Func functor is used to store minimal key.
425 \p Func has the following signature:
428 void operator()( key_type const& key );
431 If the tree is empty, \p f is not called.
432 Otherwise, is it called with minimal key, the pointer to corresponding value is returned
435 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
436 It means that the function gets leftmost leaf of the tree and tries to unlink it.
437 During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
438 So, the function returns the item with minimum key at the moment of tree traversing.
440 RCU \p synchronize method can be called. RCU should NOT be locked.
441 The function does not free the item.
442 The deallocator will be implicitly invoked when the returned object is destroyed or when
443 its \p release() member function is called.
445 template <typename Func>
446 exempt_ptr extract_min( Func f )
448 return base_class::extract_min( f );
451 /// Extracts minimal key key and corresponding value
453 This function is a shortcut for the following call:
456 exempt_ptr xp = theTree.extract_min( [&key]( key_type const& k ) { key = k; } );
458 \p key_type should be copy-assignable. The copy of minimal key
459 is returned in \p min_key argument.
461 typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
462 extract_min_key( key_type& min_key )
464 return base_class::extract_min_key( min_key );
467 /// Extracts an item with maximal key from the map
469 Returns \p exempt_ptr pointer to the rightmost item.
470 If the set is empty, returns empty \p exempt_ptr.
472 Note that the function returns only the value for maximal key.
473 To retrieve its key use \p extract_max( Func ) or \p extract_max_key(key_type&) member function.
475 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
476 It means that the function gets rightmost leaf of the tree and tries to unlink it.
477 During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
478 So, the function returns the item with maximum key at the moment of tree traversing.
480 RCU \p synchronize method can be called. RCU should NOT be locked.
481 The function does not free the item.
482 The deallocator will be implicitly invoked when the returned object is destroyed or when
483 its \p release() is called.
485 exempt_ptr extract_max()
487 return base_class::extract_max();
490 /// Extracts the maximal key and corresponding value
492 Returns \p exempt_ptr pointer to the rightmost item.
493 If the set is empty, returns empty \p exempt_ptr.
495 \p Func functor is used to store maximal key.
496 \p Func has the following signature:
499 void operator()( key_type const& key );
502 If the tree is empty, \p f is not called.
503 Otherwise, is it called with maximal key, the pointer to corresponding value is returned
506 @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
507 It means that the function gets rightmost leaf of the tree and tries to unlink it.
508 During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
509 So, the function returns the item with maximum key at the moment of tree traversing.
511 RCU \p synchronize method can be called. RCU should NOT be locked.
512 The function does not free the item.
513 The deallocator will be implicitly invoked when the returned object is destroyed or when
514 its \p release() is called.
516 template <typename Func>
517 exempt_ptr extract_max( Func f )
519 return base_class::extract_max( f );
522 /// Extracts the maximal key and corresponding value
524 This function is a shortcut for the following call:
527 exempt_ptr xp = theTree.extract_max( [&key]( key_type const& k ) { key = k; } );
529 \p key_type should be copy-assignable. The copy of maximal key
530 is returned in \p max_key argument.
532 typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
533 extract_max_key( key_type& max_key )
535 return base_class::extract_max_key( max_key );
538 /// Extracts an item from the map
540 The function searches an item with key equal to \p key in the tree,
541 unlinks it, and returns \p exempt_ptr pointer to a value found.
542 If \p key is not found the function returns an empty \p exempt_ptr.
544 RCU \p synchronize method can be called. RCU should NOT be locked.
545 The function does not destroy the value found.
546 The dealloctor will be implicitly invoked when the returned object is destroyed or when
547 its \p release() member function is called.
549 template <typename Q>
550 exempt_ptr extract( Q const& key )
552 return base_class::extract( key );
555 /// Extracts an item from the map using \p pred for searching
557 The function is an analog of \p extract(Q const&)
558 but \p pred is used for key compare.
559 \p Less has the interface like \p std::less.
560 \p pred must imply the same element order as the comparator used for building the map.
562 template <typename Q, typename Less>
563 exempt_ptr extract_with( Q const& key, Less pred )
565 return base_class::extract_with( key, pred );
568 /// Find the key \p key
570 The function searches the item with key equal to \p key and calls the functor \p f for item found.
571 The interface of \p Func functor is:
574 void operator()( key_type const& key, mapped_type& val );
577 where \p val is the item found for \p key
578 The functor is called under node-level lock.
580 The function applies RCU lock internally.
582 The function returns \p true if \p key is found, \p false otherwise.
584 template <typename K, typename Func>
585 bool find( K const& key, Func f )
587 return base_class::find( key, f );
590 /// Finds the key \p val using \p pred predicate for searching
592 The function is an analog of \p find(K const&, Func)
593 but \p pred is used for key comparing.
594 \p Less functor has the interface like \p std::less.
595 \p Less must imply the same element order as the comparator used for building the map.
597 template <typename K, typename Less, typename Func>
598 bool find_with( K const& key, Less pred, Func f )
600 return base_class::find_with( key, pred, f );
603 /// Find the key \p key
605 The function searches the item with key equal to \p key
606 and returns \p true if it is found, and \p false otherwise.
608 The function applies RCU lock internally.
610 template <typename K>
611 bool find( K const& key )
613 return base_class::find( key );
616 /// Finds the key \p val using \p pred predicate for searching
618 The function is an analog of \p find(K const&)
619 but \p pred is used for key comparing.
620 \p Less functor has the interface like \p std::less.
621 \p Less must imply the same element order as the comparator used for building the map.
623 template <typename K, typename Less>
624 bool find_with( K const& key, Less pred )
626 return base_class::find_with( key, pred );
635 /// Checks if the map is empty
638 return base_class::empty();
641 /// Returns item count in the map
643 Only leaf nodes containing user data are counted.
645 The value returned depends on item counter type provided by \p Traits template parameter.
646 If it is \p atomicity::empty_item_counter this function always returns 0.
648 The function is not suitable for checking the tree emptiness, use \p empty()
649 member function for this purpose.
653 return base_class::size();
656 /// Returns const reference to internal statistics
657 stat const& statistics() const
659 return base_class::statistics();
662 /// Returns reference to \p sync_monitor object
663 sync_monitor& monitor()
665 return base_class::monitor();
668 sync_monitor const& monitor() const
670 return base_class::monitor();
674 /// Checks internal consistency (not atomic, not thread-safe)
676 The debugging function to check internal consistency of the tree.
678 bool check_consistency() const
680 return base_class::check_consistency();
683 /// Checks internal consistency (not atomic, not thread-safe)
685 The debugging function to check internal consistency of the tree.
686 The functor \p Func is called if a violation of internal tree structure
690 void operator()( size_t nLevel, size_t hLeft, size_t hRight );
694 - \p nLevel - the level where the violation is found
695 - \p hLeft - the height of left subtree
696 - \p hRight - the height of right subtree
698 The functor is called for each violation found.
700 template <typename Func>
701 bool check_consistency( Func f ) const
703 return base_class::check_consistency( f );
706 }} // namespace cds::container
708 #endif // #ifndef CDSLIB_CONTAINER_IMPL_BRONSON_AVLTREE_MAP_RCU_H