Fixed doc
[libcds.git] / cds / container / bronson_avltree_map_rcu.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
29 */
30
31 #ifndef CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
32 #define CDSLIB_CONTAINER_BRONSON_AVLTREE_MAP_RCU_H
33
34 #include <functional>
35 #include <cds/container/impl/bronson_avltree_map_rcu.h>
36
37 namespace cds { namespace container {
38
39     namespace bronson_avltree {
40         //@cond
41         namespace details {
42             template < class RCU, typename Key, typename T, typename Traits>
43             struct make_map
44             {
45                 typedef Key key_type;
46                 typedef T mapped_type;
47                 typedef Traits original_traits;
48
49                 typedef cds::details::Allocator< mapped_type, typename original_traits::allocator > cxx_allocator;
50
51                 struct traits : public original_traits
52                 {
53                     struct disposer {
54                         void operator()( mapped_type * p ) const
55                         {
56                             cxx_allocator().Delete( p );
57                         }
58                     };
59                 };
60
61                 // Metafunction result
62                 typedef BronsonAVLTreeMap< RCU, Key, mapped_type *, traits > type;
63             };
64         } // namespace details
65         //@endcond
66     } // namespace bronson_avltree
67
68     /// Bronson et al AVL-tree (RCU specialization)
69     /** @ingroup cds_nonintrusive_map
70         @ingroup cds_nonintrusive_tree
71         @anchor cds_container_BronsonAVLTreeMap_rcu
72
73         Source:
74             - [2010] N.Bronson, J.Casper, H.Chafi, K.Olukotun "A Practical Concurrent Binary Search Tree"
75             - <a href="http://github.com/nbronson/snaptree">Java implementation</a>
76
77         This is a concurrent AVL tree algorithm that uses hand-over-hand optimistic validation,
78         a concurrency control mechanism for searching and navigating a binary search tree.
79         This mechanism minimizes spurious retries when concurrent structural changes cannot
80         affect the correctness of the search or navigation result.
81         The algorithm is based on partially external trees, a simple scheme that simplifies deletions
82         by leaving a routing node in the tree when deleting a node that has two children,
83         then opportunistically unlinking routing nodes during rebalancing. As in external trees,
84         which store values only in leaf nodes, deletions can be performed locally while holding
85         a fixed number of locks. Partially external trees, however, require far fewer routing nodes
86         than an external tree for most sequences of insertions and deletions.
87         The algorithm uses optimistic concurrency control, but carefully manage the
88         tree in such a way that all atomic regions have fixed read and write sets
89         that are known ahead of time. This allows to reduce practical overheads by embedding
90         the concurrency control directly. To perform tree operations using only fixed sized
91         atomic regions the algo uses the following mechanisms: search operations overlap atomic blocks as
92         in the hand-over-hand locking technique; mutations perform rebalancing separately;
93         and deletions occasionally leave a routing node in the tree.
94
95         <b>Template arguments</b>:
96         - \p RCU - one of \ref cds_urcu_gc "RCU type"
97         - \p Key - key type
98         - \p T - value type to be stored in tree's nodes.
99         - \p Traits - tree traits, default is \p bronson_avltree::traits
100             It is possible to declare option-based tree with \p bronson_avltree::make_traits metafunction
101             instead of \p Traits template argument.
102
103         There is \ref cds_container_BronsonAVLTreeMap_rcu_ptr "a specialization" for "key -> value pointer" map.
104
105         @note Before including <tt><cds/container/bronson_avltree_map_rcu.h></tt> you should include appropriate RCU header file,
106         see \ref cds_urcu_gc "RCU type" for list of existing RCU class and corresponding header files.
107     */
108     template <
109         typename RCU,
110         typename Key,
111         typename T,
112 #   ifdef CDS_DOXYGEN_INVOKED
113         typename Traits = bronson_avltree::traits
114 #else
115         typename Traits
116 #endif
117     >
118     class BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T, Traits >
119 #ifdef CDS_DOXYGEN_INVOKED
120         : private BronsonAVLTreeMap< cds::urcu::gc<RCU>, Key, T*, Traits >
121 #else
122         : private bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits >::type
123 #endif
124     {
125         //@cond
126         typedef bronson_avltree::details::make_map< cds::urcu::gc<RCU>, Key, T, Traits > maker;
127         typedef typename maker::type base_class;
128         //@endcond
129
130     public:
131         typedef cds::urcu::gc<RCU>  gc;   ///< RCU Garbage collector
132         typedef Key     key_type;    ///< type of a key stored in the map
133         typedef T       mapped_type; ///< type of value stored in the map
134         typedef Traits  traits;      ///< Traits template parameter
135
136         typedef typename base_class::key_comparator     key_comparator;     ///< key compare functor based on \p Traits::compare and \p Traits::less
137         typedef typename traits::item_counter           item_counter;       ///< Item counting policy
138         typedef typename traits::memory_model           memory_model;       ///< Memory ordering, see \p cds::opt::memory_model option
139         typedef typename traits::allocator              allocator_type;     ///< allocator for value
140         typedef typename traits::node_allocator         node_allocator_type;///< allocator for maintaining internal nodes
141         typedef typename traits::stat                   stat;               ///< internal statistics
142         typedef typename traits::rcu_check_deadlock     rcu_check_deadlock; ///< Deadlock checking policy
143         typedef typename traits::back_off               back_off;           ///< Back-off strategy
144         typedef typename traits::sync_monitor           sync_monitor;       ///< @ref cds_sync_monitor "Synchronization monitor" type for node-level locking
145
146         /// Enabled or disabled @ref bronson_avltree::relaxed_insert "relaxed insertion"
147         static bool const c_bRelaxedInsert = traits::relaxed_insert;
148
149         /// Group of \p extract_xxx functions does not require external locking
150         static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal;
151
152         typedef typename base_class::rcu_lock   rcu_lock;  ///< RCU scoped lock
153
154         /// Returned pointer to \p mapped_type of extracted node
155         typedef typename base_class::exempt_ptr exempt_ptr;
156
157     protected:
158         //@cond
159         typedef typename base_class::node_type        node_type;
160         typedef typename base_class::node_scoped_lock node_scoped_lock;
161         typedef typename maker::cxx_allocator         cxx_allocator;
162
163         typedef typename base_class::update_flags update_flags;
164         //@endcond
165
166     public:
167         /// Creates empty map
168         BronsonAVLTreeMap()
169         {}
170
171         /// Destroys the map
172         ~BronsonAVLTreeMap()
173         {}
174
175         /// Inserts new node with \p key and default value
176         /**
177             The function creates a node with \p key and default value, and then inserts the node created into the map.
178
179             Preconditions:
180             - The \p key_type should be constructible from a value of type \p K.
181             - The \p mapped_type should be default-constructible.
182
183             RCU \p synchronize() can be called. RCU should not be locked.
184
185             Returns \p true if inserting successful, \p false otherwise.
186         */
187         template <typename K>
188         bool insert( K const& key )
189         {
190             return base_class::do_update(key, key_comparator(),
191                 []( node_type * pNode ) -> mapped_type*
192                 {
193                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
194                     CDS_UNUSED( pNode );
195                     return cxx_allocator().New();
196                 },
197                 update_flags::allow_insert
198             ) == update_flags::result_inserted;
199         }
200
201         /// Inserts new node
202         /**
203             The function creates a node with copy of \p val value
204             and then inserts the node created into the map.
205
206             Preconditions:
207             - The \p key_type should be constructible from \p key of type \p K.
208             - The \p mapped_type should be constructible from \p val of type \p V.
209
210             RCU \p synchronize() method can be called. RCU should not be locked.
211
212             Returns \p true if \p val is inserted into the map, \p false otherwise.
213         */
214         template <typename K, typename V>
215         bool insert( K const& key, V const& val )
216         {
217             return base_class::do_update( key, key_comparator(),
218                 [&val]( node_type * pNode ) -> mapped_type*
219                 {
220                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
221                     CDS_UNUSED( pNode );
222                     return cxx_allocator().New( val );
223                 },
224                 update_flags::allow_insert
225             ) == update_flags::result_inserted;
226         }
227
228         /// Inserts new node and initialize it by a functor
229         /**
230             This function inserts new node with key \p key and if inserting is successful then it calls
231             \p func functor with signature
232             \code
233                 struct functor {
234                     void operator()( key_type const& key, mapped_type& item );
235                 };
236             \endcode
237
238             The key_type should be constructible from value of type \p K.
239
240             The function allows to split creating of new item into two part:
241             - create item from \p key;
242             - insert new item into the map;
243             - if inserting is successful, initialize the value of item by calling \p func functor
244
245             This can be useful if complete initialization of object of \p value_type is heavyweight and
246             it is preferable that the initialization should be completed only if inserting is successful.
247             The functor is called under the node lock.
248
249             RCU \p synchronize() method can be called. RCU should not be locked.
250         */
251         template <typename K, typename Func>
252         bool insert_with( K const& key, Func func )
253         {
254             return base_class::do_update( key, key_comparator(),
255                 [&func]( node_type * pNode ) -> mapped_type*
256                 {
257                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
258                     mapped_type * pVal = cxx_allocator().New();
259                     func( pNode->m_key, *pVal );
260                     return pVal;
261                 },
262                 update_flags::allow_insert
263             ) == update_flags::result_inserted;
264         }
265
266         /// For key \p key inserts data of type \p mapped_type created in-place from \p args
267         /**
268             Returns \p true if inserting successful, \p false otherwise.
269
270             RCU \p synchronize() method can be called. RCU should not be locked.
271         */
272         template <typename K, typename... Args>
273         bool emplace( K&& key, Args&&... args )
274         {
275 #       if !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40800 && CDS_COMPILER_VERSION < 40900 )
276             // Probably, the following code is not so efficient, since we pass lvalues instead rvalues to lambda
277             //TODO: study how to pass a parameter pack to a lambda efficiently using perfect forwarding
278             // see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#904 - this is what we need
279             return base_class::do_update( key, key_comparator(),
280                 [&args...]( node_type * pNode ) -> mapped_type *
281                 {
282                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
283                     CDS_UNUSED( pNode );
284                     return cxx_allocator().New( std::forward<Args>(args)...);
285                 },
286                 update_flags::allow_insert
287             ) == update_flags::result_inserted;
288 #       else
289             // gcc 4.8 error: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
290             // workaround (from http://stackoverflow.com/questions/14191989/how-do-i-use-variadic-perfect-forwarding-into-a-lambda)
291             auto f = std::bind<mapped_type *>(
292                         []( Args... args) -> mapped_type* { return cxx_allocator().New( std::move(args)...); },
293                         std::forward<Args>(args)...
294                         );
295             return base_class::do_update( key, key_comparator(),
296                 [&f]( node_type * pNode ) -> mapped_type *
297                 {
298                     assert( pNode->m_pValue.load( memory_model::memory_order_relaxed ) == nullptr );
299                     CDS_UNUSED( pNode );
300                     return f();
301                 },
302                 update_flags::allow_insert
303             ) == update_flags::result_inserted;
304 #       endif
305         }
306
307         /// Updates the value for \p key
308         /**
309             The operation performs inserting or changing data with lock-free manner.
310
311             If the \p key not found in the map, then the new item created from \p key
312             will be inserted into the map iff \p bAllowInsert is \p true
313             (note that in this case the \ref key_type should be constructible from type \p K).
314             Otherwise, the functor \p func is called with item found.
315             The functor \p Func signature is:
316             \code
317                 struct my_functor {
318                     void operator()( bool bNew, key_type const& key, mapped_type& item );
319                 };
320             \endcode
321
322             with arguments:
323             - \p bNew - \p true if the item has been inserted, \p false otherwise
324             - \p item - value
325
326             The functor may change any fields of the \p item. The functor is called under the node lock,
327             the caller can change any field of \p item.
328
329             RCU \p synchronize() method can be called. RCU should not be locked.
330
331             Returns <tt> std::pair<bool, bool> </tt> where \p first is \p true if operation is successfull,
332             \p second is \p true if new item has been added or \p false if the item with \p key
333             already exists.
334         */
335         template <typename K, typename Func>
336         std::pair<bool, bool> update( K const& key, Func func, bool bAllowInsert = true )
337         {
338             int result = base_class::do_update( key, key_comparator(),
339                 [&func]( node_type * pNode ) -> mapped_type*
340                 {
341                     mapped_type * pVal = pNode->m_pValue.load( memory_model::memory_order_relaxed );
342                     if ( !pVal ) {
343                         pVal = cxx_allocator().New();
344                         func( true, pNode->m_key, *pVal );
345                     }
346                     else
347                         func( false, pNode->m_key, *pVal );
348                     return pVal;
349                 },
350                 (bAllowInsert ? update_flags::allow_insert : 0) | update_flags::allow_update
351             );
352             return std::make_pair( result != 0, (result & update_flags::result_inserted) != 0 );
353         }
354
355
356         /// Delete \p key from the map
357         /**
358             RCU \p synchronize() method can be called. RCU should not be locked.
359
360             Return \p true if \p key is found and deleted, \p false otherwise
361         */
362         template <typename K>
363         bool erase( K const& key )
364         {
365             return base_class::erase( key );
366         }
367
368         /// Deletes the item from the map using \p pred predicate for searching
369         /**
370             The function is an analog of \p erase(K const&)
371             but \p pred is used for key comparing.
372             \p Less functor has the interface like \p std::less.
373             \p Less must imply the same element order as the comparator used for building the map.
374         */
375         template <typename K, typename Less>
376         bool erase_with( K const& key, Less pred )
377         {
378             return base_class::erase_with( key, pred );
379         }
380
381         /// Delete \p key from the map
382         /** \anchor cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func
383
384             The function searches an item with key \p key, calls \p f functor
385             and deletes the item. If \p key is not found, the functor is not called.
386
387             The functor \p Func interface:
388             \code
389             struct extractor {
390                 void operator()(key_type const& key, mapped_type& item) { ... }
391             };
392             \endcode
393
394             RCU \p synchronize method can be called. RCU should not be locked.
395
396             Return \p true if key is found and deleted, \p false otherwise
397         */
398         template <typename K, typename Func>
399         bool erase( K const& key, Func f )
400         {
401             return base_class::erase( key, f );
402         }
403
404         /// Deletes the item from the map using \p pred predicate for searching
405         /**
406             The function is an analog of \ref cds_nonintrusive_BronsonAVLTreeMap_rcu_erase_func "erase(K const&, Func)"
407             but \p pred is used for key comparing.
408             \p Less functor has the interface like \p std::less.
409             \p Less must imply the same element order as the comparator used for building the map.
410         */
411         template <typename K, typename Less, typename Func>
412         bool erase_with( K const& key, Less pred, Func f )
413         {
414             return base_class::erase_with( key, pred, f );
415         }
416
417         /// Extracts a value with minimal key from the map
418         /**
419             Returns \p exempt_ptr pointer to the leftmost item.
420             If the set is empty, returns empty \p exempt_ptr.
421
422             Note that the function returns only the value for minimal key.
423             To retrieve its key use \p extract_min( Func ) member function.
424
425             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
426             It means that the function gets leftmost leaf of the tree and tries to unlink it.
427             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
428             So, the function returns the item with minimum key at the moment of tree traversing.
429
430             RCU \p synchronize method can be called. RCU should NOT be locked.
431             The function does not free the item.
432             The deallocator will be implicitly invoked when the returned object is destroyed or when
433             its \p release() member function is called.
434         */
435         exempt_ptr extract_min()
436         {
437             return base_class::extract_min();
438         }
439
440         /// Extracts minimal key key and corresponding value
441         /**
442             Returns \p exempt_ptr to the leftmost item.
443             If the tree is empty, returns empty \p exempt_ptr.
444
445             \p Func functor is used to store minimal key.
446             \p Func has the following signature:
447             \code
448                 struct functor {
449                     void operator()( key_type const& key );
450                 };
451             \endcode
452             If the tree is empty, \p f is not called.
453             Otherwise, is it called with minimal key, the pointer to corresponding value is returned
454             as \p exempt_ptr.
455
456             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> minimum key.
457             It means that the function gets leftmost leaf of the tree and tries to unlink it.
458             During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
459             So, the function returns the item with minimum key at the moment of tree traversing.
460
461             RCU \p synchronize method can be called. RCU should NOT be locked.
462             The function does not free the item.
463             The deallocator will be implicitly invoked when the returned object is destroyed or when
464             its \p release() member function is called.
465         */
466         template <typename Func>
467         exempt_ptr extract_min( Func f )
468         {
469             return base_class::extract_min( f );
470         }
471
472         /// Extracts minimal key key and corresponding value
473         /**
474             This function is a shortcut for the following call:
475             \code
476                 key_type key;
477                 exempt_ptr xp = theTree.extract_min( [&key]( key_type const& k ) { key = k; } );
478             \endcode
479             \p key_type should be copy-assignable. The copy of minimal key
480             is returned in \p min_key argument.
481         */
482         typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
483         extract_min_key( key_type& min_key )
484         {
485             return base_class::extract_min_key( min_key );
486         }
487
488         /// Extracts an item with maximal key from the map
489         /**
490             Returns \p exempt_ptr pointer to the rightmost item.
491             If the set is empty, returns empty \p exempt_ptr.
492
493             Note that the function returns only the value for maximal key.
494             To retrieve its key use \p extract_max( Func ) or \p extract_max_key(key_type&) member function.
495
496             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
497             It means that the function gets rightmost leaf of the tree and tries to unlink it.
498             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
499             So, the function returns the item with maximum key at the moment of tree traversing.
500
501             RCU \p synchronize method can be called. RCU should NOT be locked.
502             The function does not free the item.
503             The deallocator will be implicitly invoked when the returned object is destroyed or when
504             its \p release() is called.
505         */
506         exempt_ptr extract_max()
507         {
508             return base_class::extract_max();
509         }
510
511         /// Extracts the maximal key and corresponding value
512         /**
513             Returns \p exempt_ptr pointer to the rightmost item.
514             If the set is empty, returns empty \p exempt_ptr.
515
516             \p Func functor is used to store maximal key.
517             \p Func has the following signature:
518             \code
519                 struct functor {
520                     void operator()( key_type const& key );
521                 };
522             \endcode
523             If the tree is empty, \p f is not called.
524             Otherwise, is it called with maximal key, the pointer to corresponding value is returned
525             as \p exempt_ptr.
526
527             @note Due the concurrent nature of the map, the function extracts <i>nearly</i> maximal key.
528             It means that the function gets rightmost leaf of the tree and tries to unlink it.
529             During unlinking, a concurrent thread may insert an item with key great than leftmost item's key.
530             So, the function returns the item with maximum key at the moment of tree traversing.
531
532             RCU \p synchronize method can be called. RCU should NOT be locked.
533             The function does not free the item.
534             The deallocator will be implicitly invoked when the returned object is destroyed or when
535             its \p release() is called.
536         */
537         template <typename Func>
538         exempt_ptr extract_max( Func f )
539         {
540             return base_class::extract_max( f );
541         }
542
543         /// Extracts the maximal key and corresponding value
544         /**
545             This function is a shortcut for the following call:
546             \code
547                 key_type key;
548                 exempt_ptr xp = theTree.extract_max( [&key]( key_type const& k ) { key = k; } );
549             \endcode
550             \p key_type should be copy-assignable. The copy of maximal key
551             is returned in \p max_key argument.
552         */
553         typename std::enable_if< std::is_copy_assignable<key_type>::value, exempt_ptr >::type
554         extract_max_key( key_type& max_key )
555         {
556             return base_class::extract_max_key( max_key );
557         }
558
559         /// Extracts an item from the map
560         /**
561             The function searches an item with key equal to \p key in the tree,
562             unlinks it, and returns \p exempt_ptr pointer to a value found.
563             If \p key is not found the function returns an empty \p exempt_ptr.
564
565             RCU \p synchronize method can be called. RCU should NOT be locked.
566             The function does not destroy the value found.
567             The dealloctor will be implicitly invoked when the returned object is destroyed or when
568             its \p release() member function is called.
569         */
570         template <typename Q>
571         exempt_ptr extract( Q const& key )
572         {
573             return base_class::extract( key );
574         }
575
576         /// Extracts an item from the map using \p pred for searching
577         /**
578             The function is an analog of \p extract(Q const&)
579             but \p pred is used for key compare.
580             \p Less has the interface like \p std::less.
581             \p pred must imply the same element order as the comparator used for building the map.
582         */
583         template <typename Q, typename Less>
584         exempt_ptr extract_with( Q const& key, Less pred )
585         {
586             return base_class::extract_with( key, pred );
587         }
588
589         /// Find the key \p key
590         /**
591             The function searches the item with key equal to \p key and calls the functor \p f for item found.
592             The interface of \p Func functor is:
593             \code
594             struct functor {
595                 void operator()( key_type const& key, mapped_type& val );
596             };
597             \endcode
598             where \p val is the item found for \p key
599             The functor is called under node-level lock.
600
601             The function applies RCU lock internally.
602
603             The function returns \p true if \p key is found, \p false otherwise.
604         */
605         template <typename K, typename Func>
606         bool find( K const& key, Func f )
607         {
608             return base_class::find( key, f );
609         }
610
611         /// Finds the key \p val using \p pred predicate for searching
612         /**
613             The function is an analog of \p find(K const&, Func)
614             but \p pred is used for key comparing.
615             \p Less functor has the interface like \p std::less.
616             \p Less must imply the same element order as the comparator used for building the map.
617         */
618         template <typename K, typename Less, typename Func>
619         bool find_with( K const& key, Less pred, Func f )
620         {
621             return base_class::find_with( key, pred, f );
622         }
623
624         /// Checks whether the map contains \p key
625         /**
626             The function searches the item with key equal to \p key
627             and returns \p true if it is found, and \p false otherwise.
628
629             The function applies RCU lock internally.
630         */
631         template <typename K>
632         bool contains( K const& key )
633         {
634             return base_class::contains( key );
635         }
636
637         /// Checks whether the map contains \p key using \p pred predicate for searching
638         /**
639             The function is similar to <tt>contains( key )</tt> but \p pred is used for key comparing.
640             \p Less functor has the interface like \p std::less.
641             \p Less must imply the same element order as the comparator used for building the set.
642         */
643         template <typename K, typename Less>
644         bool contains( K const& key, Less pred )
645         {
646             return base_class::contains( key, pred );
647         }
648
649         /// Clears the map
650         void clear()
651         {
652             base_class::clear();
653         }
654
655         /// Checks if the map is empty
656         bool empty() const
657         {
658             return base_class::empty();
659         }
660
661         /// Returns item count in the map
662         /**
663             Only leaf nodes containing user data are counted.
664
665             The value returned depends on item counter type provided by \p Traits template parameter.
666             If it is \p atomicity::empty_item_counter this function always returns 0.
667
668             The function is not suitable for checking the tree emptiness, use \p empty()
669             member function for this purpose.
670         */
671         size_t size() const
672         {
673             return base_class::size();
674         }
675
676         /// Returns const reference to internal statistics
677         stat const& statistics() const
678         {
679             return base_class::statistics();
680         }
681
682         /// Returns reference to \p sync_monitor object
683         sync_monitor& monitor()
684         {
685             return base_class::monitor();
686         }
687         //@cond
688         sync_monitor const& monitor() const
689         {
690             return base_class::monitor();
691         }
692         //@endcond
693
694         /// Checks internal consistency (not atomic, not thread-safe)
695         /**
696             The debugging function to check internal consistency of the tree.
697         */
698         bool check_consistency() const
699         {
700             return base_class::check_consistency();
701         }
702
703         /// Checks internal consistency (not atomic, not thread-safe)
704         /**
705             The debugging function to check internal consistency of the tree.
706             The functor \p Func is called if a violation of internal tree structure
707             is found:
708             \code
709             struct functor {
710                 void operator()( size_t nLevel, size_t hLeft, size_t hRight );
711             };
712             \endcode
713             where
714             - \p nLevel - the level where the violation is found
715             - \p hLeft - the height of left subtree
716             - \p hRight - the height of right subtree
717
718             The functor is called for each violation found.
719         */
720         template <typename Func>
721         bool check_consistency( Func f ) const
722         {
723             return base_class::check_consistency( f );
724         }
725     };
726 }} // namespace cds::container
727
728 #endif // #ifndef CDSLIB_CONTAINER_IMPL_BRONSON_AVLTREE_MAP_RCU_H