Fixed passing parameter pack into lambda
[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             auto helper = []( Args&&... args ) -> mapped_type *
240                             {
241                                 return cxx_allocator().New( std::forward<Args>(args)...);
242                             };
243             
244             return base_class::do_update( key, key_comparator(),
245                 [=]( node_type * pNode ) -> mapped_type * 
246                 {
247                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
248                     CDS_UNUSED( pNode );
249                     return helper( args... );
250                     // gcc/clang error: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
251                     //return cxx_allocator().New( std::forward<Args>(args)...);
252                 },
253                 update_flags::allow_insert
254             ) == update_flags::result_inserted;
255         }
256
257         /// Ensures that the \p key exists in the map
258         /**
259             The operation performs inserting or changing data with lock-free manner.
260
261             If the \p key not found in the map, then the new item created from \p key
262             will be inserted into the map (note that in this case the \ref key_type should be
263             constructible from type \p K).
264             Otherwise, the functor \p func is called with item found.
265             The functor \p Func may be a functor:
266             \code
267                 struct my_functor {
268                     void operator()( bool bNew, key_type const& key, mapped_type& item );
269                 };
270             \endcode
271
272             with arguments:
273             - \p bNew - \p true if the item has been inserted, \p false otherwise
274             - \p item - value
275
276             The functor may change any fields of the \p item. The functor is called under the node lock.
277
278             RCU \p synchronize() method can be called. RCU should not be locked.
279
280             Returns <tt> std::pair<bool, bool> </tt> where \p first is \p true if operation is successfull,
281             \p second is \p true if new item has been added or \p false if the item with \p key
282             already exists.
283         */
284         template <typename K, typename Func>
285         std::pair<bool, bool> update( K const& key, Func func )
286         {
287             int result = base_class::do_update( key, key_comparator(),
288                 [&func]( node_type * pNode ) -> mapped_type* 
289                 {
290                     mapped_type * pVal = pNode->m_pValue.load( memory_model::memory_order_relaxed );
291                     if ( !pVal ) {
292                         pVal = cxx_allocator().New();
293                         func( true, pNode->m_key, *pVal );
294                     }
295                     else
296                         func( false, pNode->m_key, *pVal );
297                     return pVal;
298                 },
299                 update_flags::allow_insert | update_flags::allow_update 
300             );
301             return std::make_pair( result != 0, (result & update_flags::result_inserted) != 0 );
302         }
303
304         //@cond
305         template <typename K, typename Func>
306         std::pair<bool, bool> ensure( K const& key, Func func )
307         {
308             return update( key, func );
309         }
310         //@endcond
311
312
313         /// Delete \p key from the map
314         /**
315             RCU \p synchronize() method can be called. RCU should not be locked.
316
317             Return \p true if \p key is found and deleted, \p false otherwise
318         */
319         template <typename K>
320         bool erase( K const& key )
321         {
322             return base_class::erase( key );
323         }
324
325         /// Deletes the item from the map using \p pred predicate for searching
326         /**
327             The function is an analog of \p erase(K const&)
328             but \p pred is used for key comparing.
329             \p Less functor has the interface like \p std::less.
330             \p Less must imply the same element order as the comparator used for building the map.
331         */
332         template <typename K, typename Less>
333         bool erase_with( K const& key, Less pred )
334         {
335             return base_class::erase_with( key, pred );
336         }
337
338         /// Delete \p key from the map
339         /** \anchor cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func
340
341             The function searches an item with key \p key, calls \p f functor
342             and deletes the item. If \p key is not found, the functor is not called.
343
344             The functor \p Func interface:
345             \code
346             struct extractor {
347                 void operator()(key_type const& key, mapped_type& item) { ... }
348             };
349             \endcode
350
351             RCU \p synchronize method can be called. RCU should not be locked.
352
353             Return \p true if key is found and deleted, \p false otherwise
354         */
355         template <typename K, typename Func>
356         bool erase( K const& key, Func f )
357         {
358             return base_class::erase( key, f );
359         }
360
361         /// Deletes the item from the map using \p pred predicate for searching
362         /**
363             The function is an analog of \ref cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func "erase(K const&, Func)"
364             but \p pred is used for key comparing.
365             \p Less functor has the interface like \p std::less.
366             \p Less must imply the same element order as the comparator used for building the map.
367         */
368         template <typename K, typename Less, typename Func>
369         bool erase_with( K const& key, Less pred, Func f )
370         {
371             return base_class::erase_with( key, pred, f );
372         }
373
374         /// Extracts a value with minimal key from the map
375         /**
376             Returns \p exempt_ptr pointer to the leftmost item.
377             If the set is empty, returns empty \p exempt_ptr.
378
379             Note that the function returns only the value for minimal key.
380             To retrieve its key use \p extract_min( Func ) member function.
381
382             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
383             It means that the function gets leftmost leaf of the tree and tries to unlink it.
384             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
385             So, the function returns the item with minimum key at the moment of tree traversing.
386
387             RCU \p synchronize method can be called. RCU should NOT be locked.
388             The function does not free the item.
389             The deallocator will be implicitly invoked when the returned object is destroyed or when
390             its \p release() member function is called.
391         */
392         exempt_ptr extract_min()
393         {
394             return base_class::extract_min();
395         }
396
397         /// Extracts minimal key key and corresponding value
398         /**
399             Returns \p exempt_ptr to the leftmost item.
400             If the tree is empty, returns empty \p exempt_ptr.
401
402             \p Func functor is used to store minimal key.
403             \p Func has the following signature:
404             \code
405                 struct functor {
406                     void operator()( key_type const& key );
407                 };
408             \endcode
409             If the tree is empty, \p f is not called.
410             Otherwise, is it called with minimal key, the pointer to corresponding value is returned
411             as \p exempt_ptr.
412
413             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
414             It means that the function gets leftmost leaf of the tree and tries to unlink it.
415             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
416             So, the function returns the item with minimum key at the moment of tree traversing.
417
418             RCU \p synchronize method can be called. RCU should NOT be locked.
419             The function does not free the item.
420             The deallocator will be implicitly invoked when the returned object is destroyed or when
421             its \p release() member function is called.
422         */
423         template <typename Func>
424         exempt_ptr extract_min( Func f )
425         {
426             return base_class::extract_min( f );
427         }
428
429         /// Extracts minimal key key and corresponding value
430         /**
431             This function is a shortcut for the following call:
432             \code
433                 key_type key;
434                 exempt_ptr xp = theTree.extract_min( [&key]( key_type const& k ) { key = k; } );
435             \endcode
436             \p key_type should be copy-assignable. The copy of minimal key
437             is returned in \p min_key argument.
438         */
439         typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
440         extract_min_key( key_type& min_key )
441         {
442             return base_class::extract_min_key( min_key );
443         }
444
445         /// Extracts an item with maximal key from the map
446         /**
447             Returns \p exempt_ptr pointer to the rightmost item.
448             If the set is empty, returns empty \p exempt_ptr.
449
450             Note that the function returns only the value for maximal key.
451             To retrieve its key use \p extract_max( Func ) or \p extract_max_key(key_type&) member function.
452
453             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
454             It means that the function gets rightmost leaf of the tree and tries to unlink it.
455             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
456             So, the function returns the item with maximum key at the moment of tree traversing.
457
458             RCU \p synchronize method can be called. RCU should NOT be locked.
459             The function does not free the item.
460             The deallocator will be implicitly invoked when the returned object is destroyed or when
461             its \p release() is called.
462         */
463         exempt_ptr extract_max()
464         {
465             return base_class::extract_max();
466         }
467
468         /// Extracts the maximal key and corresponding value
469         /**
470             Returns \p exempt_ptr pointer to the rightmost item.
471             If the set is empty, returns empty \p exempt_ptr.
472
473             \p Func functor is used to store maximal key.
474             \p Func has the following signature:
475             \code
476                 struct functor {
477                     void operator()( key_type const& key );
478                 };
479             \endcode
480             If the tree is empty, \p f is not called.
481             Otherwise, is it called with maximal key, the pointer to corresponding value is returned
482             as \p exempt_ptr.
483
484             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
485             It means that the function gets rightmost leaf of the tree and tries to unlink it.
486             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
487             So, the function returns the item with maximum key at the moment of tree traversing.
488
489             RCU \p synchronize method can be called. RCU should NOT be locked.
490             The function does not free the item.
491             The deallocator will be implicitly invoked when the returned object is destroyed or when
492             its \p release() is called.
493         */
494         template <typename Func>
495         exempt_ptr extract_max( Func f )
496         {
497             return base_class::extract_max( f );
498         }
499
500         /// Extracts the maximal key and corresponding value
501         /**
502             This function is a shortcut for the following call:
503             \code
504                 key_type key;
505                 exempt_ptr xp = theTree.extract_max( [&key]( key_type const& k ) { key = k; } );
506             \endcode
507             \p key_type should be copy-assignable. The copy of maximal key
508             is returned in \p max_key argument.
509         */
510         typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
511         extract_max_key( key_type& max_key )
512         {
513             return base_class::extract_max_key( max_key );
514         }
515
516         /// Extracts an item from the map
517         /**
518             The function searches an item with key equal to \p key in the tree,
519             unlinks it, and returns \p exempt_ptr pointer to a value found.
520             If \p key is not found the function returns an empty \p exempt_ptr.
521
522             RCU \p synchronize method can be called. RCU should NOT be locked.
523             The function does not destroy the value found.
524             The dealloctor will be implicitly invoked when the returned object is destroyed or when
525             its \p release() member function is called.
526         */
527         template <typename Q>
528         exempt_ptr extract( Q const& key )
529         {
530             return base_class::extract( key );
531         }
532
533         /// Extracts an item from the map using \p pred for searching
534         /**
535             The function is an analog of \p extract(Q const&)
536             but \p pred is used for key compare.
537             \p Less has the interface like \p std::less.
538             \p pred must imply the same element order as the comparator used for building the map.
539         */
540         template <typename Q, typename Less>
541         exempt_ptr extract_with( Q const& key, Less pred )
542         {
543             return base_class::extract_with( key, pred );
544         }
545
546         /// Find the key \p key
547         /**
548             The function searches the item with key equal to \p key and calls the functor \p f for item found.
549             The interface of \p Func functor is:
550             \code
551             struct functor {
552                 void operator()( key_type const& key, mapped_type& val );
553             };
554             \endcode
555             where \p val is the item found for \p key
556             The functor is called under node-level lock.
557
558             The function applies RCU lock internally.
559
560             The function returns \p true if \p key is found, \p false otherwise.
561         */
562         template <typename K, typename Func>
563         bool find( K const& key, Func f )
564         {
565             return base_class::find( key, f );
566         }
567
568         /// Finds the key \p val using \p pred predicate for searching
569         /**
570             The function is an analog of \p find(K const&, Func)
571             but \p pred is used for key comparing.
572             \p Less functor has the interface like \p std::less.
573             \p Less must imply the same element order as the comparator used for building the map.
574         */
575         template <typename K, typename Less, typename Func>
576         bool find_with( K const& key, Less pred, Func f )
577         {
578             return base_class::find_with( key, pred, f );
579         }
580
581         /// Find the key \p key
582         /**
583             The function searches the item with key equal to \p key
584             and returns \p true if it is found, and \p false otherwise.
585
586             The function applies RCU lock internally.
587         */
588         template <typename K>
589         bool find( K const& key )
590         {
591             return base_class::find( key );
592         }
593
594         /// Finds the key \p val using \p pred predicate for searching
595         /**
596             The function is an analog of \p find(K const&)
597             but \p pred is used for key comparing.
598             \p Less functor has the interface like \p std::less.
599             \p Less must imply the same element order as the comparator used for building the map.
600         */
601         template <typename K, typename Less>
602         bool find_with( K const& key, Less pred )
603         {
604             return base_class::find_with( key, pred );
605         }
606
607         /// Clears the map
608         void clear()
609         {
610             base_class::clear();
611         }
612
613         /// Checks if the map is empty
614         bool empty() const
615         {
616             return base_class::empty();
617         }
618
619         /// Returns item count in the map
620         /**
621             Only leaf nodes containing user data are counted.
622
623             The value returned depends on item counter type provided by \p Traits template parameter.
624             If it is \p atomicity::empty_item_counter this function always returns 0.
625
626             The function is not suitable for checking the tree emptiness, use \p empty()
627             member function for this purpose.
628         */
629         size_t size() const
630         {
631             return base_class::size();
632         }
633
634         /// Returns const reference to internal statistics
635         stat const& statistics() const
636         {
637             return base_class::statistics();
638         }
639
640         /// Checks internal consistency (not atomic, not thread-safe)
641         /**
642             The debugging function to check internal consistency of the tree.
643         */
644         bool check_consistency() const
645         {
646             return base_class::check_consistency();
647         }
648
649         /// Checks internal consistency (not atomic, not thread-safe)
650         /**
651             The debugging function to check internal consistency of the tree.
652             The functor \p Func is called if a violation of internal tree structure
653             is found:
654             \code
655             struct functor {
656                 void operator()( size_t nLevel, size_t hLeft, size_t hRight );
657             };
658             \endcode
659             where 
660             - \p nLevel - the level where the violation is found
661             - \p hLeft - the height of left subtree
662             - \p hRight - the height of right subtree
663
664             The functor is called for each violation found.
665         */
666         template <typename Func>
667         bool check_consistency( Func f ) const
668         {
669             return base_class::check_consistency( f );
670         }
671     };
672 }} // namespace cds::container
673
674 #endif // #ifndef CDSLIB_CONTAINER_IMPL_BRONSON_AVLTREE_MAP_RCU_H