Remove std::ref and boost::ref from docs
[libcds.git] / cds / container / ellen_bintree_map_rcu.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_ELLEN_BINTREE_MAP_RCU_H
4 #define __CDS_CONTAINER_ELLEN_BINTREE_MAP_RCU_H
5
6 #include <cds/container/details/ellen_bintree_base.h>
7 #include <cds/intrusive/ellen_bintree_rcu.h>
8
9 namespace cds { namespace container {
10
11     /// Map based on Ellen's et al binary search tree (RCU specialization)
12     /** @ingroup cds_nonintrusive_map
13         @ingroup cds_nonintrusive_tree
14         @anchor cds_container_EllenBinTreeMap_rcu
15
16         Source:
17             - [2010] F.Ellen, P.Fatourou, E.Ruppert, F.van Breugel "Non-blocking Binary Search Tree"
18
19         %EllenBinTreeMap is an unbalanced leaf-oriented binary search tree that implements the <i>map</i>
20         abstract data type. Nodes maintains child pointers but not parent pointers.
21         Every internal node has exactly two children, and all data of type <tt>std::pair<Key const, T></tt>
22         currently in the tree are stored in the leaves. Internal nodes of the tree are used to direct \p find
23         operation along the path to the correct leaf. The keys (of \p Key type) stored in internal nodes
24         may or may not be in the map.
25         Unlike \ref cds_container_EllenBinTreeSet_rcu "EllenBinTreeSet" keys are not a part of \p T type.
26         The map can be represented as a set containing <tt>std::pair< Key const, T> </tt> values.
27
28         Due to \p extract_min and \p extract_max member functions the \p %EllenBinTreeMap can act as
29         a <i>priority queue</i>. In this case you should provide unique compound key, for example,
30         the priority value plus some uniformly distributed random value.
31
32         @warning Recall the tree is <b>unbalanced</b>. The complexity of operations is <tt>O(log N)</tt>
33         for uniformly distributed random keys, but in worst case the complexity is <tt>O(N)</tt>.
34
35         @note In the current implementation we do not use helping technique described in original paper.
36         So, the current implementation is near to fine-grained lock-based tree.
37         Helping will be implemented in future release
38
39         <b>Template arguments</b> :
40         - \p RCU - one of \ref cds_urcu_gc "RCU type"
41         - \p Key - key type
42         - \p T - value type to be stored in tree's leaf nodes.
43         - \p Traits - type traits. See ellen_bintree::type_traits for explanation.
44
45         It is possible to declare option-based tree with ellen_bintree::make_map_traits metafunction
46         instead of \p Traits template argument.
47         Template argument list \p Options of ellen_bintree::make_map_traits metafunction are:
48         - opt::compare - key compare functor. No default functor is provided.
49             If the option is not specified, \p %opt::less is used.
50         - opt::less - specifies binary predicate used for key compare. At least \p %opt::compare or \p %opt::less should be defined.
51         - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter that is no item counting.
52         - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
53             or opt::v::sequential_consistent (sequentially consisnent memory model).
54         - opt::allocator - the allocator used for \ref ellen_bintree::map_node "leaf nodes" which contains data.
55             Default is \ref CDS_DEFAULT_ALLOCATOR.
56         - opt::node_allocator - the allocator used for \ref ellen_bintree::internal_node "internal nodes".
57             Default is \ref CDS_DEFAULT_ALLOCATOR.
58         - ellen_bintree::update_desc_allocator - an allocator of \ref ellen_bintree::update_desc "update descriptors",
59             default is \ref CDS_DEFAULT_ALLOCATOR.
60             Note that update descriptor is helping data structure with short lifetime and it is good candidate for pooling.
61             The number of simultaneously existing descriptors is a relatively small number limited the number of threads
62             working with the tree and RCU buffer size.
63             Therefore, a bounded lock-free container like \p cds::container::VyukovMPMCCycleQueue is good choice for the free-list
64             of update descriptors, see cds::memory::vyukov_queue_pool free-list implementation.
65             Also notice that size of update descriptor is not dependent on the type of data
66             stored in the tree so single free-list object can be used for several EllenBinTree-based object.
67         - opt::stat - internal statistics. Available types: ellen_bintree::stat, ellen_bintree::empty_stat (the default)
68         - opt::rcu_check_deadlock - a deadlock checking policy. Default is opt::v::rcu_throw_deadlock
69         - opt::copy_policy - key copy policy defines a functor to copy leaf node's key to internal node.
70             By default, assignment operator is used.
71             The copy functor interface is:
72             \code
73             struct copy_functor {
74                 void operator()( Key& dest, Key const& src );
75             };
76             \endcode
77
78         @note Before including <tt><cds/container/ellen_bintree_map_rcu.h></tt> you should include appropriate RCU header file,
79         see \ref cds_urcu_gc "RCU type" for list of existing RCU class and corresponding header files.
80     */
81     template <
82         class RCU,
83         typename Key,
84         typename T,
85 #ifdef CDS_DOXYGEN_INVOKED
86         class Traits = ellen_bintree::type_traits
87 #else
88         class Traits
89 #endif
90     >
91     class EllenBinTreeMap< cds::urcu::gc<RCU>, Key, T, Traits >
92 #ifdef CDS_DOXYGEN_INVOKED
93         : public cds::intrusive::EllenBinTree< cds::urcu::gc<RCU>, Key, T, Traits >
94 #else
95         : public ellen_bintree::details::make_ellen_bintree_map< cds::urcu::gc<RCU>, Key, T, Traits >::type
96 #endif
97     {
98         //@cond
99         typedef ellen_bintree::details::make_ellen_bintree_map< cds::urcu::gc<RCU>, Key, T, Traits > maker;
100         typedef typename maker::type base_class;
101         //@endcond
102     public:
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 std::pair< key_type const, mapped_type >    value_type  ;   ///< Key-value pair stored in leaf node of the mp
107         typedef Traits  options         ;   ///< Traits template parameter
108
109 #   ifdef CDS_DOXYGEN_INVOKED
110         typedef implementation_defined key_comparator  ;    ///< key compare functor based on opt::compare and opt::less option setter.
111 #   else
112         typedef typename maker::intrusive_type_traits::compare   key_comparator;
113 #   endif
114         typedef typename base_class::item_counter           item_counter        ; ///< Item counting policy used
115         typedef typename base_class::memory_model           memory_model        ; ///< Memory ordering. See cds::opt::memory_model option
116         typedef typename base_class::node_allocator         node_allocator_type ; ///< allocator for maintaining internal node
117         typedef typename base_class::stat                   stat                ; ///< internal statistics type
118         typedef typename base_class::rcu_check_deadlock     rcu_check_deadlock  ; ///< Deadlock checking policy
119         typedef typename options::copy_policy               copy_policy         ; ///< key copy policy
120
121         typedef typename options::allocator                 allocator_type      ;   ///< Allocator for leaf nodes
122         typedef typename base_class::node_allocator         node_allocator      ;   ///< Internal node allocator
123         typedef typename base_class::update_desc_allocator  update_desc_allocator ; ///< Update descriptor allocator
124
125         static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal; ///< Group of \p extract_xxx functions do not require external locking
126
127     protected:
128         //@cond
129         typedef typename base_class::value_type         leaf_node;
130         typedef typename base_class::internal_node      internal_node;
131         typedef typename base_class::update_desc        update_desc;
132
133         typedef typename maker::cxx_leaf_node_allocator cxx_leaf_node_allocator;
134
135         typedef std::unique_ptr< leaf_node, typename maker::leaf_deallocator >    scoped_node_ptr;
136         //@endcond
137
138     public:
139         typedef typename gc::scoped_lock    rcu_lock ;  ///< RCU scoped lock
140
141         /// pointer to extracted node
142         typedef cds::urcu::exempt_ptr< gc, leaf_node, value_type, typename maker::intrusive_type_traits::disposer,
143             cds::urcu::details::conventional_exempt_member_cast<leaf_node, value_type>
144         > exempt_ptr;
145
146     public:
147         /// Default constructor
148         EllenBinTreeMap()
149             : base_class()
150         {}
151
152         /// Clears the map
153         ~EllenBinTreeMap()
154         {}
155
156         /// Inserts new node with key and default value
157         /**
158             The function creates a node with \p key and default value, and then inserts the node created into the map.
159
160             Preconditions:
161             - The \ref key_type should be constructible from a value of type \p K.
162                 In trivial case, \p K is equal to \ref key_type.
163             - The \ref mapped_type should be default-constructible.
164
165             RCU \p synchronize method can be called. RCU should not be locked.
166
167             Returns \p true if inserting successful, \p false otherwise.
168         */
169         template <typename K>
170         bool insert( K const& key )
171         {
172             return insert_key( key, [](value_type&){} );
173         }
174
175         /// Inserts new node
176         /**
177             The function creates a node with copy of \p val value
178             and then inserts the node created into the map.
179
180             Preconditions:
181             - The \ref key_type should be constructible from \p key of type \p K.
182             - The \ref value_type should be constructible from \p val of type \p V.
183
184             RCU \p synchronize method can be called. RCU should not be locked.
185
186             Returns \p true if \p val is inserted into the map, \p false otherwise.
187         */
188         template <typename K, typename V>
189         bool insert( K const& key, V const& val )
190         {
191             scoped_node_ptr pNode( cxx_leaf_node_allocator().New( key, val ));
192             if ( base_class::insert( *pNode ))
193             {
194                 pNode.release();
195                 return true;
196             }
197             return false;
198         }
199
200         /// Inserts new node and initialize it by a functor
201         /**
202             This function inserts new node with key \p key and if inserting is successful then it calls
203             \p func functor with signature
204             \code
205                 struct functor {
206                     void operator()( value_type& item );
207                 };
208             \endcode
209
210             The argument \p item of user-defined functor \p func is the reference
211             to the map's item inserted:
212                 - <tt>item.first</tt> is a const reference to item's key that cannot be changed.
213                 - <tt>item.second</tt> is a reference to item's value that may be changed.
214
215             The key_type should be constructible from value of type \p K.
216
217             The function allows to split creating of new item into two part:
218             - create item from \p key;
219             - insert new item into the map;
220             - if inserting is successful, initialize the value of item by calling \p func functor
221
222             This can be useful if complete initialization of object of \p value_type is heavyweight and
223             it is preferable that the initialization should be completed only if inserting is successful.
224
225             RCU \p synchronize method can be called. RCU should not be locked.
226         */
227         template <typename K, typename Func>
228         bool insert_key( const K& key, Func func )
229         {
230             scoped_node_ptr pNode( cxx_leaf_node_allocator().New( key ));
231             if ( base_class::insert( *pNode, [&func]( leaf_node& item ) { func( item.m_Value ); } )) {
232                 pNode.release();
233                 return true;
234             }
235             return false;
236         }
237
238         /// For key \p key inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
239         /**
240             Returns \p true if inserting successful, \p false otherwise.
241
242             RCU \p synchronize method can be called. RCU should not be locked.
243         */
244         template <typename K, typename... Args>
245         bool emplace( K&& key, Args&&... args )
246         {
247             scoped_node_ptr pNode( cxx_leaf_node_allocator().New( std::forward<K>(key), std::forward<Args>(args)... ));
248             if ( base_class::insert( *pNode )) {
249                 pNode.release();
250                 return true;
251             }
252             return false;
253         }
254
255         /// Ensures that the \p key exists in the map
256         /**
257             The operation performs inserting or changing data with lock-free manner.
258
259             If the \p key not found in the map, then the new item created from \p key
260             is inserted into the map (note that in this case the \ref key_type should be
261             constructible from type \p K).
262             Otherwise, the functor \p func is called with item found.
263             The functor \p Func may be a function with signature:
264             \code
265                 void func( bool bNew, value_type& item );
266             \endcode
267             or a functor:
268             \code
269                 struct my_functor {
270                     void operator()( bool bNew, value_type& item );
271                 };
272             \endcode
273
274             with arguments:
275             - \p bNew - \p true if the item has been inserted, \p false otherwise
276             - \p item - item of the list
277
278             The functor may change any fields of the \p item.second that is \ref value_type.
279
280             RCU \p synchronize method can be called. RCU should not be locked.
281
282             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
283             \p second is true if new item has been added or \p false if the item with \p key
284             already is in the list.
285         */
286         template <typename K, typename Func>
287         std::pair<bool, bool> ensure( K const& key, Func func )
288         {
289             scoped_node_ptr pNode( cxx_leaf_node_allocator().New( key ));
290             std::pair<bool, bool> res = base_class::ensure( *pNode,
291                 [&func](bool bNew, leaf_node& item, leaf_node const& ){ func( bNew, item.m_Value ); }
292             );
293             if ( res.first && res.second )
294                 pNode.release();
295             return res;
296         }
297
298         /// Delete \p key from the map
299         /**\anchor cds_nonintrusive_EllenBinTreeMap_rcu_erase_val
300
301             RCU \p synchronize method can be called. RCU should not be locked.
302
303             Return \p true if \p key is found and deleted, \p false otherwise
304         */
305         template <typename K>
306         bool erase( K const& key )
307         {
308             return base_class::erase(key);
309         }
310
311         /// Deletes the item from the map using \p pred predicate for searching
312         /**
313             The function is an analog of \ref cds_nonintrusive_EllenBinTreeMap_rcu_erase_val "erase(K const&)"
314             but \p pred is used for key comparing.
315             \p Less functor has the interface like \p std::less.
316             \p Less must imply the same element order as the comparator used for building the map.
317         */
318         template <typename K, typename Less>
319         bool erase_with( K const& key, Less pred )
320         {
321             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::key_accessor >());
322         }
323
324         /// Delete \p key from the map
325         /** \anchor cds_nonintrusive_EllenBinTreeMap_rcu_erase_func
326
327             The function searches an item with key \p key, calls \p f functor
328             and deletes the item. If \p key is not found, the functor is not called.
329
330             The functor \p Func interface:
331             \code
332             struct extractor {
333                 void operator()(value_type& item) { ... }
334             };
335             \endcode
336
337             RCU \p synchronize method can be called. RCU should not be locked.
338
339             Return \p true if key is found and deleted, \p false otherwise
340         */
341         template <typename K, typename Func>
342         bool erase( K const& key, Func f )
343         {
344             return base_class::erase( key, [&f]( leaf_node& node) { f( node.m_Value ); } );
345         }
346
347         /// Deletes the item from the map using \p pred predicate for searching
348         /**
349             The function is an analog of \ref cds_nonintrusive_EllenBinTreeMap_rcu_erase_func "erase(K const&, Func)"
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.
353         */
354         template <typename K, typename Less, typename Func>
355         bool erase_with( K const& key, Less pred, Func f )
356         {
357             return base_class::erase_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::key_accessor >(),
358                 [&f]( leaf_node& node) { f( node.m_Value ); } );
359         }
360
361         /// Extracts an item with minimal key from the map
362         /**
363             If the map is not empty, the function returns \p true, \p result contains a pointer to value.
364             If the map is empty, the function returns \p false, \p result is left unchanged.
365
366             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
367             It means that the function gets leftmost leaf of the tree and tries to unlink it.
368             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
369             So, the function returns the item with minimum key at the moment of tree traversing.
370
371             RCU \p synchronize method can be called. RCU should NOT be locked.
372             The function does not free the item.
373             The deallocator will be implicitly invoked when \p result object is destroyed or when
374             <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
375             @note Before reusing \p result object you should call its \p release() method.
376         */
377         bool extract_min( exempt_ptr& result )
378         {
379             return base_class::extract_min_( result );
380         }
381
382         /// Extracts an item with maximal key from the map
383         /**
384             If the map is not empty, the function returns \p true, \p result contains a pointer to extracted item.
385             If the map is empty, the function returns \p false, \p result is left unchanged.
386
387             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
388             It means that the function gets rightmost leaf of the tree and tries to unlink it.
389             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
390             So, the function returns the item with maximum key at the moment of tree traversing.
391
392             RCU \p synchronize method can be called. RCU should NOT be locked.
393             The function does not free the item.
394             The deallocator will be implicitly invoked when \p result object is destroyed or when
395             <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
396             @note Before reusing \p result object you should call its \p release() method.
397         */
398         bool extract_max( exempt_ptr& result )
399         {
400             return base_class::extract_max_( result );
401         }
402
403         /// Extracts an item from the map
404         /** \anchor cds_nonintrusive_EllenBinTreeMap_rcu_extract
405             The function searches an item with key equal to \p key in the tree,
406             unlinks it, and returns pointer to an item found in \p result parameter.
407             If \p key is not found the function returns \p false.
408
409             RCU \p synchronize method can be called. RCU should NOT be locked.
410             The function does not destroy the item found.
411             The dealloctor will be implicitly invoked when \p result object is destroyed or when
412             <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
413             @note Before reusing \p result object you should call its \p release() method.
414         */
415         template <typename Q>
416         bool extract( exempt_ptr& result, Q const& key )
417         {
418             return base_class::extract_( result, key, typename base_class::node_compare());
419         }
420
421         /// Extracts an item from the map using \p pred for searching
422         /**
423             The function is an analog of \ref cds_nonintrusive_EllenBinTreeMap_rcu_extract "extract(exempt_ptr&, Q const&)"
424             but \p pred is used for key compare.
425             \p Less has the interface like \p std::less and should meet \ref cds_container_EllenBinTreeSet_rcu_less
426             "predicate requirements".
427             \p pred must imply the same element order as the comparator used for building the map.
428         */
429         template <typename Q, typename Less>
430         bool extract_with( exempt_ptr& result,  Q const& val, Less pred )
431         {
432             return base_class::extract_with_( result, val,
433                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::key_accessor >() );
434         }
435
436         /// Find the key \p key
437         /** \anchor cds_nonintrusive_EllenBinTreeMap_rcu_find_cfunc
438
439             The function searches the item with key equal to \p key and calls the functor \p f for item found.
440             The interface of \p Func functor is:
441             \code
442             struct functor {
443                 void operator()( value_type& item );
444             };
445             \endcode
446             where \p item is the item found.
447
448             The functor may change \p item.second.
449
450             The function applies RCU lock internally.
451
452             The function returns \p true if \p key is found, \p false otherwise.
453         */
454         template <typename K, typename Func>
455         bool find( K const& key, Func f )
456         {
457             return base_class::find( key, [&f](leaf_node& item, K const& ) { f( item.m_Value );});
458         }
459
460         /// Finds the key \p val using \p pred predicate for searching
461         /**
462             The function is an analog of \ref cds_nonintrusive_EllenBinTreeMap_rcu_find_cfunc "find(K const&, Func)"
463             but \p pred is used for key comparing.
464             \p Less functor has the interface like \p std::less.
465             \p Less must imply the same element order as the comparator used for building the map.
466         */
467         template <typename K, typename Less, typename Func>
468         bool find_with( K const& key, Less pred, Func f )
469         {
470             return base_class::find_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::key_accessor >(),
471                 [&f](leaf_node& item, K const& ) { f( item.m_Value );});
472         }
473
474         /// Find the key \p key
475         /** \anchor cds_nonintrusive_EllenBinTreeMap_rcu_find_val
476
477             The function searches the item with key equal to \p key
478             and returns \p true if it is found, and \p false otherwise.
479
480             The function applies RCU lock internally.
481         */
482         template <typename K>
483         bool find( K const& key )
484         {
485             return base_class::find( key );
486         }
487
488         /// Finds the key \p val using \p pred predicate for searching
489         /**
490             The function is an analog of \ref cds_nonintrusive_EllenBinTreeMap_rcu_find_val "find(K const&)"
491             but \p pred is used for key comparing.
492             \p Less functor has the interface like \p std::less.
493             \p Less must imply the same element order as the comparator used for building the map.
494         */
495         template <typename K, typename Less>
496         bool find_with( K const& key, Less pred )
497         {
498             return base_class::find_with( key, cds::details::predicate_wrapper< leaf_node, Less, typename maker::key_accessor >() );
499         }
500
501         /// Finds \p key and return the item found
502         /** \anchor cds_nonintrusive_EllenBinTreeMap_rcu_get
503             The function searches the item with key equal to \p key and returns the pointer to item found.
504             If \p key is not found it returns \p nullptr.
505
506             RCU should be locked before call the function.
507             Returned pointer is valid while RCU is locked.
508         */
509         template <typename Q>
510         value_type * get( Q const& key ) const
511         {
512             leaf_node * pNode = base_class::get( key );
513             return pNode ? &pNode->m_Value : nullptr;
514         }
515
516         /// Finds \p key with \p pred predicate and return the item found
517         /**
518             The function is an analog of \ref cds_nonintrusive_EllenBinTreeMap_rcu_get "get(Q const&)"
519             but \p pred is used for comparing the keys.
520
521             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type
522             and \p Q in any order.
523             \p pred must imply the same element order as the comparator used for building the map.
524         */
525         template <typename Q, typename Less>
526         value_type * get_with( Q const& key, Less pred ) const
527         {
528             leaf_node * pNode = base_class::get_with( key,
529                 cds::details::predicate_wrapper< leaf_node, Less, typename maker::key_accessor >());
530             return pNode ? &pNode->m_Value : nullptr;
531         }
532
533         /// Clears the map
534         void clear()
535         {
536             base_class::clear();
537         }
538
539         /// Checks if the map is empty
540         /**
541             Emptiness is checked by item counting: if item count is zero then the map is empty.
542         */
543         bool empty() const
544         {
545             return base_class::empty();
546         }
547
548         /// Returns item count in the map
549         size_t size() const
550         {
551             return base_class::size();
552         }
553
554         /// Returns const reference to internal statistics
555         stat const& statistics() const
556         {
557             return base_class::statistics();
558         }
559
560         /// Checks internal consistency (not atomic, not thread-safe)
561         /**
562             The debugging function to check internal consistency of the tree.
563         */
564         bool check_consistency() const
565         {
566             return base_class::check_consistency();
567         }
568
569     };
570 }} // namespace cds::container
571
572 #endif //#ifndef __CDS_CONTAINER_ELLEN_BINTREE_MAP_RCU_H