Merge commit 'a9213ce45072f66144284647ccae242f91ca30af' into dev
[libcds.git] / cds / container / bronson_avltree_map_rcu.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
4 #define CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
5
6 #include <cds/container/impl/bronson_avltree_map_rcu.h>
7
8 namespace cds { namespace container {
9
10     namespace bronson_avltree {
11         //@cond
12         namespace details {
13             template < class RCU, typename Key, typename T, typename Traits>
14             struct make_map
15             {
16                 typedef Key key_type;
17                 typedef T mapped_type;
18                 typedef Traits original_traits;
19
20                 typedef cds::details::Allocator< mapped_type, typename original_traits::allocator > cxx_allocator;
21
22                 struct traits : public original_traits
23                 {
24                     struct disposer {
25                         void operator()( mapped_type * p ) const
26                         {
27                             cxx_allocator().Delete( p );
28                         }
29                     };
30                 };
31
32                 // Metafunction result
33                 typedef BronsonAVLTreeMap< RCU, Key, mapped_type *, traits > type;
34             };
35         } // namespace details
36         //@endcond
37     } // namespace bronson_avltree
38
39     /// Bronson et al AVL-tree (RCU specialization)
40     /** @ingroup cds_nonintrusive_map
41         @ingroup cds_nonintrusive_tree
42         @anchor cds_container_BronsonAVLTreeMap_rcu
43
44         Source:
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>
47
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.
58
59         <b>Template arguments</b>:
60         - \p RCU - one of \ref cds_urcu_gc "RCU type"
61         - \p Key - key 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.
66             
67         There is \ref cds_container_BronsonAVLTreeMap_rcu_ptr "a specialization" for "key -> value pointer" map.
68
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.
71     */
72     template <
73         typename RCU,
74         typename Key,
75         typename T,
76 #   ifdef CDS_DOXYGEN_INVOKED
77         typename Traits = bronson_avltree::traits
78 #else
79         typename Traits
80 #endif
81     >
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 >
85 #else
86         : private bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits >::type
87 #endif
88     {
89         //@cond
90         typedef bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits > maker;
91         typedef typename maker::type base_class;
92         //@endcond
93
94     public:
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
99
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
109
110         /// Enabled or disabled @ref bronson_avltree::relaxed_insert "relaxed insertion"
111         static bool const c_bRelaxedInsert = traits::relaxed_insert;
112
113         /// Group of \p extract_xxx functions does not require external locking
114         static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal;
115
116         typedef typename base_class::rcu_lock   rcu_lock;  ///< RCU scoped lock
117
118         /// Returned pointer to \p mapped_type of extracted node
119         typedef typename base_class::exempt_ptr exempt_ptr;
120
121     protected:
122         //@cond
123         typedef typename base_class::node_type        node_type;
124         typedef typename base_class::node_scoped_lock node_scoped_lock;
125         typedef typename maker::cxx_allocator         cxx_allocator;
126
127         typedef typename base_class::update_flags update_flags;
128         //@endcond
129
130     public:
131         /// Creates empty map
132         BronsonAVLTreeMap()
133         {}
134
135         /// Destroys the map
136         ~BronsonAVLTreeMap()
137         {}
138
139         /// Inserts new node with \p key and default value
140         /**
141             The function creates a node with \p key and default value, and then inserts the node created into the map.
142
143             Preconditions:
144             - The \p key_type should be constructible from a value of type \p K.
145             - The \p mapped_type should be default-constructible.
146
147             RCU \p synchronize() can be called. RCU should not be locked.
148
149             Returns \p true if inserting successful, \p false otherwise.
150         */
151         template <typename K>
152         bool insert( K const& key )
153         {
154             return base_class::do_update(key, key_comparator(),
155                 []( node_type * pNode ) -> mapped_type*
156                 {
157                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
158                     CDS_UNUSED( pNode );
159                     return cxx_allocator().New();
160                 },
161                 update_flags::allow_insert
162             ) == update_flags::result_inserted;
163         }
164
165         /// Inserts new node
166         /**
167             The function creates a node with copy of \p val value
168             and then inserts the node created into the map.
169
170             Preconditions:
171             - The \p key_type should be constructible from \p key of type \p K.
172             - The \p mapped_type should be constructible from \p val of type \p V.
173
174             RCU \p synchronize() method can be called. RCU should not be locked.
175
176             Returns \p true if \p val is inserted into the map, \p false otherwise.
177         */
178         template <typename K, typename V>
179         bool insert( K const& key, V const& val )
180         {
181             return base_class::do_update( key, key_comparator(),
182                 [&val]( node_type * pNode ) -> mapped_type*
183                 {
184                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
185                     CDS_UNUSED( pNode );
186                     return cxx_allocator().New( val );
187                 },
188                 update_flags::allow_insert
189             ) == update_flags::result_inserted;
190         }
191
192         /// Inserts new node and initialize it by a functor
193         /**
194             This function inserts new node with key \p key and if inserting is successful then it calls
195             \p func functor with signature
196             \code
197                 struct functor {
198                     void operator()( key_type const& key, mapped_type& item );
199                 };
200             \endcode
201
202             The key_type should be constructible from value of type \p K.
203
204             The function allows to split creating of new item into two part:
205             - create item from \p key;
206             - insert new item into the map;
207             - if inserting is successful, initialize the value of item by calling \p func functor
208
209             This can be useful if complete initialization of object of \p value_type is heavyweight and
210             it is preferable that the initialization should be completed only if inserting is successful.
211             The functor is called under the node lock.
212
213             RCU \p synchronize() method can be called. RCU should not be locked.
214         */
215         template <typename K, typename Func>
216         bool insert_with( K const& key, Func func )
217         {
218             return base_class::do_update( key, key_comparator(),
219                 [&func]( node_type * pNode ) -> mapped_type*
220                 {
221                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
222                     mapped_type * pVal = cxx_allocator().New();
223                     func( pNode->m_key, *pVal );
224                     return pVal;
225                 },
226                 update_flags::allow_insert
227             ) == update_flags::result_inserted;
228         }
229
230         /// For key \p key inserts data of type \p mapped_type created in-place from \p args
231         /**
232             Returns \p true if inserting successful, \p false otherwise.
233
234             RCU \p synchronize() method can be called. RCU should not be locked.
235         */
236         template <typename K, typename... Args>
237         bool emplace( K&& key, Args&&... args )
238         {
239             return base_class::do_update( key, key_comparator(),
240                 [&]( node_type * pNode ) -> mapped_type* 
241                 {
242                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
243                     CDS_UNUSED( pNode );
244                     return cxx_allocator().New( std::forward<Args>(args)...);
245                 },
246                 update_flags::allow_insert
247             ) == update_flags::result_inserted;
248         }
249
250         /// Ensures that the \p key exists in the map
251         /**
252             The operation performs inserting or changing data with lock-free manner.
253
254             If the \p key not found in the map, then the new item created from \p key
255             will be inserted into the map (note that in this case the \ref key_type should be
256             constructible from type \p K).
257             Otherwise, the functor \p func is called with item found.
258             The functor \p Func may be a functor:
259             \code
260                 struct my_functor {
261                     void operator()( bool bNew, key_type const& key, mapped_type& item );
262                 };
263             \endcode
264
265             with arguments:
266             - \p bNew - \p true if the item has been inserted, \p false otherwise
267             - \p item - value
268
269             The functor may change any fields of the \p item. The functor is called under the node lock.
270
271             RCU \p synchronize() method can be called. RCU should not be locked.
272
273             Returns <tt> std::pair<bool, bool> </tt> where \p first is \p true if operation is successfull,
274             \p second is \p true if new item has been added or \p false if the item with \p key
275             already exists.
276         */
277         template <typename K, typename Func>
278         std::pair<bool, bool> update( K const& key, Func func )
279         {
280             int result = base_class::do_update( key, key_comparator(),
281                 [&func]( node_type * pNode ) -> mapped_type* 
282                 {
283                     mapped_type * pVal = pNode->m_pValue.load( memory_model::memory_order_relaxed );
284                     if ( !pVal ) {
285                         pVal = cxx_allocator().New();
286                         func( true, pNode->m_key, *pVal );
287                     }
288                     else
289                         func( false, pNode->m_key, *pVal );
290                     return pVal;
291                 },
292                 update_flags::allow_insert | update_flags::allow_update 
293             );
294             return std::make_pair( result != 0, (result & update_flags::result_inserted) != 0 );
295         }
296
297         //@cond
298         template <typename K, typename Func>
299         std::pair<bool, bool> ensure( K const& key, Func func )
300         {
301             return update( key, func );
302         }
303         //@endcond
304
305
306         /// Delete \p key from the map
307         /**
308             RCU \p synchronize() method can be called. RCU should not be locked.
309
310             Return \p true if \p key is found and deleted, \p false otherwise
311         */
312         template <typename K>
313         bool erase( K const& key )
314         {
315             return base_class::erase( key );
316         }
317
318         /// Deletes the item from the map using \p pred predicate for searching
319         /**
320             The function is an analog of \p erase(K const&)
321             but \p pred is used for key comparing.
322             \p Less functor has the interface like \p std::less.
323             \p Less must imply the same element order as the comparator used for building the map.
324         */
325         template <typename K, typename Less>
326         bool erase_with( K const& key, Less pred )
327         {
328             return base_class::erase_with( key, pred );
329         }
330
331         /// Delete \p key from the map
332         /** \anchor cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func
333
334             The function searches an item with key \p key, calls \p f functor
335             and deletes the item. If \p key is not found, the functor is not called.
336
337             The functor \p Func interface:
338             \code
339             struct extractor {
340                 void operator()(mapped_type& item) { ... }
341             };
342             \endcode
343
344             RCU \p synchronize method can be called. RCU should not be locked.
345
346             Return \p true if key is found and deleted, \p false otherwise
347         */
348         template <typename K, typename Func>
349         bool erase( K const& key, Func f )
350         {
351             return base_class::erase( key, f );
352         }
353
354         /// Deletes the item from the map using \p pred predicate for searching
355         /**
356             The function is an analog of \ref cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func "erase(K const&, Func)"
357             but \p pred is used for key comparing.
358             \p Less functor has the interface like \p std::less.
359             \p Less must imply the same element order as the comparator used for building the map.
360         */
361         template <typename K, typename Less, typename Func>
362         bool erase_with( K const& key, Less pred, Func f )
363         {
364             return base_class::erase_with( key, pred, f );
365         }
366
367         /// Extracts a value with minimal key from the map
368         /**
369             Returns \p exempt_ptr pointer to the leftmost item.
370             If the set is empty, returns empty \p exempt_ptr.
371
372             Note that the function returns only the value for minimal key.
373             To retrieve its key use \p extract_min( Func ) member function.
374
375             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
376             It means that the function gets leftmost leaf of the tree and tries to unlink it.
377             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
378             So, the function returns the item with minimum key at the moment of tree traversing.
379
380             RCU \p synchronize method can be called. RCU should NOT be locked.
381             The function does not free the item.
382             The deallocator will be implicitly invoked when the returned object is destroyed or when
383             its \p release() member function is called.
384         */
385         exempt_ptr extract_min()
386         {
387             return base_class::extract_min();
388         }
389
390         /// Extracts minimal key key and corresponding value
391         /**
392             Returns \p exempt_ptr to the leftmost item.
393             If the tree is empty, returns empty \p exempt_ptr.
394
395             \p Func functor is used to store minimal key.
396             \p Func has the following signature:
397             \code
398                 struct functor {
399                     void operator()( key_type const& key );
400                 };
401             \endcode
402             If the tree is empty, \p f is not called.
403             Otherwise, is it called with minimal key, the pointer to corresponding value is returned
404             as \p exempt_ptr.
405
406             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
407             It means that the function gets leftmost leaf of the tree and tries to unlink it.
408             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
409             So, the function returns the item with minimum key at the moment of tree traversing.
410
411             RCU \p synchronize method can be called. RCU should NOT be locked.
412             The function does not free the item.
413             The deallocator will be implicitly invoked when the returned object is destroyed or when
414             its \p release() member function is called.
415         */
416         template <typename Func>
417         exempt_ptr extract_min( Func f )
418         {
419             return base_class::extract_min( f );
420         }
421
422         /// Extracts minimal key key and corresponding value
423         /**
424             This function is a shortcut for the following call:
425             \code
426                 key_type key;
427                 exempt_ptr xp = theTree.extract_min( [&key]( key_type const& k ) { key = k; } );
428             \endcode
429             \p key_type should be copy-assignable. The copy of minimal key
430             is returned in \p min_key argument.
431         */
432         typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
433         extract_min_key( key_type& min_key )
434         {
435             return base_class::extract_min_key( min_key );
436         }
437
438         /// Extracts an item with maximal key from the map
439         /**
440             Returns \p exempt_ptr pointer to the rightmost item.
441             If the set is empty, returns empty \p exempt_ptr.
442
443             Note that the function returns only the value for maximal key.
444             To retrieve its key use \p extract_max( Func ) or \p extract_max_key(key_type&) member function.
445
446             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
447             It means that the function gets rightmost leaf of the tree and tries to unlink it.
448             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
449             So, the function returns the item with maximum key at the moment of tree traversing.
450
451             RCU \p synchronize method can be called. RCU should NOT be locked.
452             The function does not free the item.
453             The deallocator will be implicitly invoked when the returned object is destroyed or when
454             its \p release() is called.
455         */
456         exempt_ptr extract_max()
457         {
458             return base_class::extract_max();
459         }
460
461         /// Extracts the maximal key and corresponding value
462         /**
463             Returns \p exempt_ptr pointer to the rightmost item.
464             If the set is empty, returns empty \p exempt_ptr.
465
466             \p Func functor is used to store maximal key.
467             \p Func has the following signature:
468             \code
469                 struct functor {
470                     void operator()( key_type const& key );
471                 };
472             \endcode
473             If the tree is empty, \p f is not called.
474             Otherwise, is it called with maximal key, the pointer to corresponding value is returned
475             as \p exempt_ptr.
476
477             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
478             It means that the function gets rightmost leaf of the tree and tries to unlink it.
479             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
480             So, the function returns the item with maximum key at the moment of tree traversing.
481
482             RCU \p synchronize method can be called. RCU should NOT be locked.
483             The function does not free the item.
484             The deallocator will be implicitly invoked when the returned object is destroyed or when
485             its \p release() is called.
486         */
487         template <typename Func>
488         exempt_ptr extract_max( Func f )
489         {
490             return base_class::extract_max( f );
491         }
492
493         /// Extracts the maximal key and corresponding value
494         /**
495             This function is a shortcut for the following call:
496             \code
497                 key_type key;
498                 exempt_ptr xp = theTree.extract_max( [&key]( key_type const& k ) { key = k; } );
499             \endcode
500             \p key_type should be copy-assignable. The copy of maximal key
501             is returned in \p max_key argument.
502         */
503         typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
504         extract_max_key( key_type& max_key )
505         {
506             return base_class::extract_max_key( max_key );
507         }
508
509         /// Extracts an item from the map
510         /**
511             The function searches an item with key equal to \p key in the tree,
512             unlinks it, and returns \p exempt_ptr pointer to a value found.
513             If \p key is not found the function returns an empty \p exempt_ptr.
514
515             RCU \p synchronize method can be called. RCU should NOT be locked.
516             The function does not destroy the value found.
517             The dealloctor will be implicitly invoked when the returned object is destroyed or when
518             its \p release() member function is called.
519         */
520         template <typename Q>
521         exempt_ptr extract( Q const& key )
522         {
523             return base_class::extract( key );
524         }
525
526         /// Extracts an item from the map using \p pred for searching
527         /**
528             The function is an analog of \p extract(Q const&)
529             but \p pred is used for key compare.
530             \p Less has the interface like \p std::less.
531             \p pred must imply the same element order as the comparator used for building the map.
532         */
533         template <typename Q, typename Less>
534         exempt_ptr extract_with( Q const& key, Less pred )
535         {
536             return base_class::extract_with( key, pred );
537         }
538
539         /// Find the key \p key
540         /**
541             The function searches the item with key equal to \p key and calls the functor \p f for item found.
542             The interface of \p Func functor is:
543             \code
544             struct functor {
545                 void operator()( key_type const& key, mapped_type& val );
546             };
547             \endcode
548             where \p val is the item found for \p key
549             The functor is called under node-level lock.
550
551             The function applies RCU lock internally.
552
553             The function returns \p true if \p key is found, \p false otherwise.
554         */
555         template <typename K, typename Func>
556         bool find( K const& key, Func f )
557         {
558             return base_class::find( key, f );
559         }
560
561         /// Finds the key \p val using \p pred predicate for searching
562         /**
563             The function is an analog of \p find(K const&, Func)
564             but \p pred is used for key comparing.
565             \p Less functor has the interface like \p std::less.
566             \p Less must imply the same element order as the comparator used for building the map.
567         */
568         template <typename K, typename Less, typename Func>
569         bool find_with( K const& key, Less pred, Func f )
570         {
571             return base_class::find_with( key, pred, f );
572         }
573
574         /// Find the key \p key
575         /**
576             The function searches the item with key equal to \p key
577             and returns \p true if it is found, and \p false otherwise.
578
579             The function applies RCU lock internally.
580         */
581         template <typename K>
582         bool find( K const& key )
583         {
584             return base_class::find( key );
585         }
586
587         /// Finds the key \p val using \p pred predicate for searching
588         /**
589             The function is an analog of \p find(K const&)
590             but \p pred is used for key comparing.
591             \p Less functor has the interface like \p std::less.
592             \p Less must imply the same element order as the comparator used for building the map.
593         */
594         template <typename K, typename Less>
595         bool find_with( K const& key, Less pred )
596         {
597             return base_class::find_with( key, pred );
598         }
599
600         /// Clears the map
601         void clear()
602         {
603             base_class::clear();
604         }
605
606         /// Checks if the map is empty
607         bool empty() const
608         {
609             return base_class::empty();
610         }
611
612         /// Returns item count in the map
613         /**
614             Only leaf nodes containing user data are counted.
615
616             The value returned depends on item counter type provided by \p Traits template parameter.
617             If it is \p atomicity::empty_item_counter this function always returns 0.
618
619             The function is not suitable for checking the tree emptiness, use \p empty()
620             member function for this purpose.
621         */
622         size_t size() const
623         {
624             return base_class::size();
625         }
626
627         /// Returns const reference to internal statistics
628         stat const& statistics() const
629         {
630             return base_class::statistics();
631         }
632
633         /// Checks internal consistency (not atomic, not thread-safe)
634         /**
635             The debugging function to check internal consistency of the tree.
636         */
637         bool check_consistency() const
638         {
639             return base_class::check_consistency();
640         }
641
642         /// Checks internal consistency (not atomic, not thread-safe)
643         /**
644             The debugging function to check internal consistency of the tree.
645             The functor \p Func is called if a violation of internal tree structure
646             is found:
647             \code
648             struct functor {
649                 void operator()( size_t nLevel, size_t hLeft, size_t hRight );
650             };
651             \endcode
652             where 
653             - \p nLevel - the level where the violation is found
654             - \p hLeft - the height of left subtree
655             - \p hRight - the height of right subtree
656
657             The functor is called for each violation found.
658         */
659         template <typename Func>
660         bool check_consistency( Func f ) const
661         {
662             return base_class::check_consistency( f );
663         }
664     };
665 }} // namespace cds::container
666
667 #endif // #ifndef CDSLIB_CONTAINER_IMPL_BRONSON_AVLTREE_MAP_RCU_H