Remove MichaelMap<gc::HRC> specializations
[libcds.git] / cds / container / michael_map.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_MICHAEL_MAP_H
4 #define __CDS_CONTAINER_MICHAEL_MAP_H
5
6 #include <cds/container/details/michael_map_base.h>
7 #include <cds/details/allocator.h>
8
9 namespace cds { namespace container {
10
11     /// Michael's hash map
12     /** @ingroup cds_nonintrusive_map
13         \anchor cds_nonintrusive_MichaelHashMap_hp
14
15         Source:
16             - [2002] Maged Michael "High performance dynamic lock-free hash tables and list-based sets"
17
18         Michael's hash table algorithm is based on lock-free ordered list and it is very simple.
19         The main structure is an array \p T of size \p M. Each element in \p T is basically a pointer
20         to a hash bucket, implemented as a singly linked list. The array of buckets cannot be dynamically expanded.
21         However, each bucket may contain unbounded number of items.
22
23         Template parameters are:
24         - \p GC - Garbage collector used. You may use any \ref cds_garbage_collector "Garbage collector"
25             from the \p libcds library.
26             Note the \p GC must be the same as the GC used for \p OrderedList
27         - \p OrderedList - ordered key-value list implementation used as bucket for hash map, for example, MichaelKVList
28             or LazyKVList. The ordered list implementation specifies the \p Key and \p Value types stored in the hash-map,
29             the reclamation schema \p GC used by hash-map, the comparison functor for the type \p Key and other features
30             specific for the ordered list.
31         - \p Traits - type traits. See michael_map::type_traits for explanation.
32
33         Instead of defining \p Traits struct you may use option-based syntax with \p michael_map::make_traits metafunction
34         (this metafunction is a synonym for michael_set::make_traits).
35         For \p michael_map::make_traits the following option may be used:
36         - opt::hash - mandatory option, specifies hash functor.
37         - opt::item_counter - optional, specifies item counting policy. See michael_map::type_traits for explanation.
38         - opt::allocator - optional, bucket table allocator. Default is \ref CDS_DEFAULT_ALLOCATOR.
39
40         Many of the class function take a key argument of type \p K that in general is not \ref key_type.
41         \p key_type and an argument of template type \p K must meet the following requirements:
42         - \p key_type should be constructible from value of type \p K;
43         - the hash functor should be able to calculate correct hash value from argument \p key of type \p K:
44             <tt> hash( key_type(key) ) == hash( key ) </tt>
45         - values of type \p key_type and \p K should be comparable
46
47         There are the specializations:
48         - for \ref cds_urcu_desc "RCU" - declared in <tt>cd/container/michael_map_rcu.h</tt>,
49             see \ref cds_nonintrusive_MichaelHashMap_rcu "MichaelHashMap<RCU>".
50         - for \ref cds::gc::nogc declared in <tt>cds/container/michael_map_nogc.h</tt>,
51             see \ref cds_nonintrusive_MichaelHashMap_nogc "MichaelHashMap<gc::nogc>".
52
53         <b>Iterators</b>
54
55         The class supports a forward iterator (\ref iterator and \ref const_iterator).
56         The iteration is unordered.
57         The iterator object is thread-safe: the element pointed by the iterator object is guarded,
58         so, the element cannot be reclaimed while the iterator object is alive.
59         However, passing an iterator object between threads is dangerous.
60
61         \warning Due to concurrent nature of Michael's set it is not guarantee that you can iterate
62         all elements in the set: any concurrent deletion can exclude the element
63         pointed by the iterator from the set, and your iteration can be terminated
64         before end of the set. Therefore, such iteration is more suitable for debugging purpose only
65
66         Remember, each iterator object requires an additional hazard pointer, that may be
67         a limited resource for \p GC like \p gc::HP (for gc::PTB the count of
68         guards is unlimited).
69
70         The iterator class supports the following minimalistic interface:
71         \code
72         struct iterator {
73         // Default ctor
74         iterator();
75
76         // Copy ctor
77         iterator( iterator const& s);
78
79         value_type * operator ->() const;
80         value_type& operator *() const;
81
82         // Pre-increment
83         iterator& operator ++();
84
85         // Copy assignment
86         iterator& operator = (const iterator& src);
87
88         bool operator ==(iterator const& i ) const;
89         bool operator !=(iterator const& i ) const;
90         };
91         \endcode
92         Note, the iterator object returned by \ref end, \p cend member functions points to \p nullptr and should not be dereferenced.
93
94         \anchor cds_nonintrusive_MichaelHashMap_how_touse
95         <b>How to use</b>
96
97         Suppose, you want to make \p int to \p int map for Hazard Pointer garbage collector. You should
98         choose suitable ordered list class that will be used as a bucket for the map; it may be MichaelKVList.
99         \code
100         #include <cds/container/michael_kvlist_hp.h>    // MichaelKVList for gc::HP
101         #include <cds/container/michael_map.h>          // MIchaelHashMap
102
103         // List traits based on std::less predicate
104         struct list_traits: public cds::container::michael_list::type_traits
105         {
106             typedef std::less<int>      less;
107         };
108
109         // Ordered list
110         typedef cds::container::MichaelKVList< cds::gc::HP, int, int, list_traits> int2int_list;
111
112         // Map traits
113         struct map_traits: public cds::container::michael_map::type_traits
114         {
115             struct hash {
116                 size_t operator()( int i ) const
117                 {
118                     return cds::opt::v::hash<int>()( i );
119                 }
120             }
121         };
122
123         // Your map
124         typedef cds::container::MichaelHashMap< cds::gc::HP, int2int_list, map_traits > int2int_map;
125
126         // Now you can use int2int_map class
127
128         int main()
129         {
130             int2int_map theMap;
131
132             theMap.insert( 100 );
133             ...
134         }
135         \endcode
136
137         You may use option-based declaration:
138         \code
139         #include <cds/container/michael_kvlist_hp.h>    // MichaelKVList for gc::HP
140         #include <cds/container/michael_map.h>          // MIchaelHashMap
141
142         // Ordered list
143         typedef cds::container::MichaelKVList< cds::gc::HP, int, int,
144             typename cds::container::michael_list::make_traits<
145                 cds::container::opt::less< std::less<int> >     // item comparator option
146             >::type
147         >  int2int_list;
148
149         // Map
150         typedef cds::container::MichaelHashMap< cds::gc::HP, int2int_list,
151             cds::container::michael_map::make_traits<
152                 cc::opt::hash< cds::opt::v::hash<int> >
153             >
154         > int2int_map;
155         \endcode
156     */
157     template <
158         class GC,
159         class OrderedList,
160 #ifdef CDS_DOXYGEN_INVOKED
161         class Traits = michael_map::type_traits
162 #else
163         class Traits
164 #endif
165     >
166     class MichaelHashMap
167     {
168     public:
169         typedef OrderedList bucket_type     ;   ///< type of ordered list used as a bucket implementation
170         typedef Traits      options         ;   ///< Traits template parameters
171
172         typedef typename bucket_type::key_type          key_type        ;   ///< key type
173         typedef typename bucket_type::mapped_type       mapped_type     ;   ///< value type
174         typedef typename bucket_type::value_type        value_type      ;   ///< key/value pair stored in the map
175
176         typedef GC                                      gc              ;   ///< Garbage collector
177         typedef typename bucket_type::key_comparator    key_comparator  ;   ///< key compare functor
178
179         /// Hash functor for \ref key_type and all its derivatives that you use
180         typedef typename cds::opt::v::hash_selector< typename options::hash >::type   hash;
181         typedef typename options::item_counter          item_counter    ;   ///< Item counter type
182
183         /// Bucket table allocator
184         typedef cds::details::Allocator< bucket_type, typename options::allocator >  bucket_table_allocator;
185         typedef typename bucket_type::guarded_ptr      guarded_ptr; ///< Guarded pointer
186
187     protected:
188         item_counter    m_ItemCounter   ;   ///< Item counter
189         hash            m_HashFunctor   ;   ///< Hash functor
190
191         bucket_type *   m_Buckets       ;   ///< bucket table
192
193     private:
194         //@cond
195         const size_t    m_nHashBitmask;
196         //@endcond
197
198     protected:
199         /// Calculates hash value of \p key
200         template <typename Q>
201         size_t hash_value( Q const& key ) const
202         {
203             return m_HashFunctor( key ) & m_nHashBitmask;
204         }
205
206         /// Returns the bucket (ordered list) for \p key
207         template <typename Q>
208         bucket_type&    bucket( Q const& key )
209         {
210             return m_Buckets[ hash_value( key ) ];
211         }
212
213     protected:
214         //@cond
215         /// Forward iterator
216         template <bool IsConst>
217         class iterator_type: private cds::intrusive::michael_set::details::iterator< bucket_type, IsConst >
218         {
219             typedef cds::intrusive::michael_set::details::iterator< bucket_type, IsConst >  base_class;
220             friend class MichaelHashMap;
221
222         protected:
223             typedef typename base_class::bucket_ptr     bucket_ptr;
224             typedef typename base_class::list_iterator  list_iterator;
225
226         public:
227             /// Value pointer type (const for const_iterator)
228             typedef typename cds::details::make_const_type<typename MichaelHashMap::mapped_type, IsConst>::pointer   value_ptr;
229             /// Value reference type (const for const_iterator)
230             typedef typename cds::details::make_const_type<typename MichaelHashMap::mapped_type, IsConst>::reference value_ref;
231
232             /// Key-value pair pointer type (const for const_iterator)
233             typedef typename cds::details::make_const_type<typename MichaelHashMap::value_type, IsConst>::pointer   pair_ptr;
234             /// Key-value pair reference type (const for const_iterator)
235             typedef typename cds::details::make_const_type<typename MichaelHashMap::value_type, IsConst>::reference pair_ref;
236
237         protected:
238             iterator_type( list_iterator const& it, bucket_ptr pFirst, bucket_ptr pLast )
239                 : base_class( it, pFirst, pLast )
240             {}
241
242         public:
243             /// Default ctor
244             iterator_type()
245                 : base_class()
246             {}
247
248             /// Copy ctor
249             iterator_type( const iterator_type& src )
250                 : base_class( src )
251             {}
252
253             /// Dereference operator
254             pair_ptr operator ->() const
255             {
256                 assert( base_class::m_pCurBucket != nullptr );
257                 return base_class::m_itList.operator ->();
258             }
259
260             /// Dereference operator
261             pair_ref operator *() const
262             {
263                 assert( base_class::m_pCurBucket != nullptr );
264                 return base_class::m_itList.operator *();
265             }
266
267             /// Pre-increment
268             iterator_type& operator ++()
269             {
270                 base_class::operator++();
271                 return *this;
272             }
273
274             /// Assignment operator
275             iterator_type& operator = (const iterator_type& src)
276             {
277                 base_class::operator =(src);
278                 return *this;
279             }
280
281             /// Returns current bucket (debug function)
282             bucket_ptr bucket() const
283             {
284                 return base_class::bucket();
285             }
286
287             /// Equality operator
288             template <bool C>
289             bool operator ==(iterator_type<C> const& i )
290             {
291                 return base_class::operator ==( i );
292             }
293             /// Equality operator
294             template <bool C>
295             bool operator !=(iterator_type<C> const& i )
296             {
297                 return !( *this == i );
298             }
299         };
300         //@endcond
301
302     public:
303         /// Forward iterator
304         typedef iterator_type< false >    iterator;
305
306         /// Const forward iterator
307         typedef iterator_type< true >     const_iterator;
308
309         /// Returns a forward iterator addressing the first element in a map
310         /**
311             For empty map \code begin() == end() \endcode
312         */
313         iterator begin()
314         {
315             return iterator( m_Buckets[0].begin(), m_Buckets, m_Buckets + bucket_count() );
316         }
317
318         /// Returns an iterator that addresses the location succeeding the last element in a map
319         /**
320             Do not use the value returned by <tt>end</tt> function to access any item.
321             The returned value can be used only to control reaching the end of the map.
322             For empty map \code begin() == end() \endcode
323         */
324         iterator end()
325         {
326             return iterator( m_Buckets[bucket_count() - 1].end(), m_Buckets + bucket_count() - 1, m_Buckets + bucket_count() );
327         }
328
329         /// Returns a forward const iterator addressing the first element in a map
330         //@{
331         const_iterator begin() const
332         {
333             return get_const_begin();
334         }
335         const_iterator cbegin()
336         {
337             return get_const_begin();
338         }
339         //@}
340
341         /// Returns an const iterator that addresses the location succeeding the last element in a map
342         //@{
343         const_iterator end() const
344         {
345             return get_const_end();
346         }
347         const_iterator cend()
348         {
349             return get_const_end();
350         }
351         //@}
352
353     private:
354         //@cond
355         const_iterator get_const_begin() const
356         {
357             return const_iterator( const_cast<bucket_type const&>(m_Buckets[0]).begin(), m_Buckets, m_Buckets + bucket_count() );
358         }
359         const_iterator get_const_end() const
360         {
361             return const_iterator( const_cast<bucket_type const&>(m_Buckets[bucket_count() - 1]).end(), m_Buckets + bucket_count() - 1, m_Buckets + bucket_count() );
362         }
363         //@endcond
364
365     public:
366         /// Initializes the map
367         /**
368             The Michael's hash map is non-expandable container. You should point the average count of items \p nMaxItemCount
369             when you create an object.
370             \p nLoadFactor parameter defines average count of items per bucket and it should be small number between 1 and 10.
371             Remember, since the bucket implementation is an ordered list, searching in the bucket is linear [<tt>O(nLoadFactor)</tt>].
372             Note, that many popular STL hash map implementation uses load factor 1.
373
374             The ctor defines hash table size as rounding <tt>nMacItemCount / nLoadFactor</tt> up to nearest power of two.
375         */
376         MichaelHashMap(
377             size_t nMaxItemCount,   ///< estimation of max item count in the hash map
378             size_t nLoadFactor      ///< load factor: estimation of max number of items in the bucket
379         ) : m_nHashBitmask( michael_map::details::init_hash_bitmask( nMaxItemCount, nLoadFactor ))
380         {
381             // GC and OrderedList::gc must be the same
382             static_assert(( std::is_same<gc, typename bucket_type::gc>::value ), "GC and OrderedList::gc must be the same");
383
384             // atomicity::empty_item_counter is not allowed as a item counter
385             static_assert(( !std::is_same<item_counter, atomicity::empty_item_counter>::value ), "atomicity::empty_item_counter is not allowed as a item counter");
386
387             m_Buckets = bucket_table_allocator().NewArray( bucket_count() );
388         }
389
390         /// Clears hash map and destroys it
391         ~MichaelHashMap()
392         {
393             clear();
394             bucket_table_allocator().Delete( m_Buckets, bucket_count() );
395         }
396
397         /// Inserts new node with key and default value
398         /**
399             The function creates a node with \p key and default value, and then inserts the node created into the map.
400
401             Preconditions:
402             - The \p key_type should be constructible from value of type \p K.
403                 In trivial case, \p K is equal to \p key_type.
404             - The \p mapped_type should be default-constructible.
405
406             Returns \p true if inserting successful, \p false otherwise.
407         */
408         template <typename K>
409         bool insert( const K& key )
410         {
411             const bool bRet = bucket( key ).insert( key );
412             if ( bRet )
413                 ++m_ItemCounter;
414             return bRet;
415         }
416
417         /// Inserts new node
418         /**
419             The function creates a node with copy of \p val value
420             and then inserts the node created into the map.
421
422             Preconditions:
423             - The \p key_type should be constructible from \p key of type \p K.
424             - The \p mapped_type should be constructible from \p val of type \p V.
425
426             Returns \p true if \p val is inserted into the map, \p false otherwise.
427         */
428         template <typename K, typename V>
429         bool insert( K const& key, V const& val )
430         {
431             const bool bRet = bucket( key ).insert( key, val );
432             if ( bRet )
433                 ++m_ItemCounter;
434             return bRet;
435         }
436
437         /// Inserts new node and initialize it by a functor
438         /**
439             This function inserts new node with key \p key and if inserting is successful then it calls
440             \p func functor with signature
441             \code
442                 struct functor {
443                     void operator()( value_type& item );
444                 };
445             \endcode
446
447             The argument \p item of user-defined functor \p func is the reference
448             to the map's item inserted:
449                 - <tt>item.first</tt> is a const reference to item's key that cannot be changed.
450                 - <tt>item.second</tt> is a reference to item's value that may be changed.
451
452             User-defined functor \p func should guarantee that during changing item's value no any other changes
453             could be made on this map's item by concurrent threads.
454             The user-defined functor can be passed by reference using \p std::ref
455             and it is called only if inserting is successful.
456
457             The key_type should be constructible from value of type \p K.
458
459             The function allows to split creating of new item into two part:
460             - create item from \p key;
461             - insert new item into the map;
462             - if inserting is successful, initialize the value of item by calling \p func functor
463
464             This can be useful if complete initialization of object of \p mapped_type is heavyweight and
465             it is preferable that the initialization should be completed only if inserting is successful.
466         */
467         template <typename K, typename Func>
468         bool insert_key( const K& key, Func func )
469         {
470             const bool bRet = bucket( key ).insert_key( key, func );
471             if ( bRet )
472                 ++m_ItemCounter;
473             return bRet;
474         }
475
476
477         /// Ensures that the \p key exists in the map
478         /**
479             The operation performs inserting or changing data with lock-free manner.
480
481             If the \p key not found in the map, then the new item created from \p key
482             is inserted into the map (note that in this case the \p key_type should be
483             constructible from type \p K).
484             Otherwise, the functor \p func is called with item found.
485             The functor \p Func may be a function with signature:
486             \code
487                 void func( bool bNew, value_type& item );
488             \endcode
489             or a functor:
490             \code
491                 struct my_functor {
492                     void operator()( bool bNew, value_type& item );
493                 };
494             \endcode
495
496             with arguments:
497             - \p bNew - \p true if the item has been inserted, \p false otherwise
498             - \p item - item of the list
499
500             The functor may change any fields of the \p item.second that is \p mapped_type;
501             however, \p func must guarantee that during changing no any other modifications
502             could be made on this item by concurrent threads.
503
504             You may pass \p func argument by reference using \p std::ref
505
506             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
507             \p second is true if new item has been added or \p false if the item with \p key
508             already is in the list.
509         */
510         template <typename K, typename Func>
511         std::pair<bool, bool> ensure( K const& key, Func func )
512         {
513             std::pair<bool, bool> bRet = bucket( key ).ensure( key, func );
514             if ( bRet.first && bRet.second )
515                 ++m_ItemCounter;
516             return bRet;
517         }
518
519         /// For key \p key inserts data of type \p mapped_type constructed with <tt>std::forward<Args>(args)...</tt>
520         /**
521             \p key_type should be constructible from type \p K
522
523             Returns \p true if inserting successful, \p false otherwise.
524         */
525         template <typename K, typename... Args>
526         bool emplace( K&& key, Args&&... args )
527         {
528             const bool bRet = bucket( key ).emplace( std::forward<K>(key), std::forward<Args>(args)... );
529             if ( bRet )
530                 ++m_ItemCounter;
531             return bRet;
532         }
533
534         /// Deletes \p key from the map
535         /** \anchor cds_nonintrusive_MichaelMap_erase_val
536
537             Return \p true if \p key is found and deleted, \p false otherwise
538         */
539         template <typename K>
540         bool erase( K const& key )
541         {
542             const bool bRet = bucket( key ).erase( key );
543             if ( bRet )
544                 --m_ItemCounter;
545             return bRet;
546         }
547
548         /// Deletes the item from the map using \p pred predicate for searching
549         /**
550             The function is an analog of \ref cds_nonintrusive_MichaelMap_erase_val "erase(K const&)"
551             but \p pred is used for key comparing.
552             \p Less functor has the interface like \p std::less.
553             \p Less must imply the same element order as the comparator used for building the map.
554         */
555         template <typename K, typename Less>
556         bool erase_with( K const& key, Less pred )
557         {
558             const bool bRet = bucket( key ).erase_with( key, pred );
559             if ( bRet )
560                 --m_ItemCounter;
561             return bRet;
562         }
563
564         /// Deletes \p key from the map
565         /** \anchor cds_nonintrusive_MichaelMap_erase_func
566
567             The function searches an item with key \p key, calls \p f functor
568             and deletes the item. If \p key is not found, the functor is not called.
569
570             The functor \p Func interface:
571             \code
572             struct extractor {
573                 void operator()(value_type& item) { ... }
574             };
575             \endcode
576             The functor may be passed by reference using <tt>boost:ref</tt>
577
578             Return \p true if key is found and deleted, \p false otherwise
579         */
580         template <typename K, typename Func>
581         bool erase( K const& key, Func f )
582         {
583             const bool bRet = bucket( key ).erase( key, f );
584             if ( bRet )
585                 --m_ItemCounter;
586             return bRet;
587         }
588
589         /// Deletes the item from the map using \p pred predicate for searching
590         /**
591             The function is an analog of \ref cds_nonintrusive_MichaelMap_erase_func "erase(K const&, Func)"
592             but \p pred is used for key comparing.
593             \p Less functor has the interface like \p std::less.
594             \p Less must imply the same element order as the comparator used for building the map.
595         */
596         template <typename K, typename Less, typename Func>
597         bool erase_with( K const& key, Less pred, Func f )
598         {
599             const bool bRet = bucket( key ).erase_with( key, pred, f );
600             if ( bRet )
601                 --m_ItemCounter;
602             return bRet;
603         }
604
605         /// Extracts the item with specified \p key
606         /** \anchor cds_nonintrusive_MichaelHashMap_hp_extract
607             The function searches an item with key equal to \p key,
608             unlinks it from the set, and returns it in \p dest parameter.
609             If the item with key equal to \p key is not found the function returns \p false.
610
611             Note the compare functor should accept a parameter of type \p K that may be not the same as \p key_type.
612
613             The extracted item is freed automatically when returned \ref guarded_ptr object will be destroyed or released.
614             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
615
616             Usage:
617             \code
618             typedef cds::container::MichaelHashMap< your_template_args > michael_map;
619             michael_map theMap;
620             // ...
621             {
622                 michael_map::guarded_ptr gp;
623                 theMap.extract( gp, 5 );
624                 // Deal with gp
625                 // ...
626
627                 // Destructor of gp releases internal HP guard
628             }
629             \endcode
630         */
631         template <typename K>
632         bool extract( guarded_ptr& dest, K const& key )
633         {
634             const bool bRet = bucket( key ).extract( dest, key );
635             if ( bRet )
636                 --m_ItemCounter;
637             return bRet;
638         }
639
640         /// Extracts the item using compare functor \p pred
641         /**
642             The function is an analog of \ref cds_nonintrusive_MichaelHashMap_hp_extract "extract(guarded_ptr&, K const&)"
643             but \p pred predicate is used for key comparing.
644
645             \p Less functor has the semantics like \p std::less but should take arguments of type \ref key_type and \p K
646             in any order.
647             \p pred must imply the same element order as the comparator used for building the map.
648         */
649         template <typename K, typename Less>
650         bool extract_with( guarded_ptr& dest, K const& key, Less pred )
651         {
652             const bool bRet = bucket( key ).extract_with( dest, key, pred );
653             if ( bRet )
654                 --m_ItemCounter;
655             return bRet;
656         }
657
658         /// Finds the key \p key
659         /** \anchor cds_nonintrusive_MichaelMap_find_cfunc
660
661             The function searches the item with key equal to \p key and calls the functor \p f for item found.
662             The interface of \p Func functor is:
663             \code
664             struct functor {
665                 void operator()( value_type& item );
666             };
667             \endcode
668             where \p item is the item found.
669
670             You may pass \p f argument by reference using \p std::ref.
671
672             The functor may change \p item.second. Note that the functor is only guarantee
673             that \p item cannot be disposed during functor is executing.
674             The functor does not serialize simultaneous access to the map's \p item. If such access is
675             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
676
677             The function returns \p true if \p key is found, \p false otherwise.
678         */
679         template <typename K, typename Func>
680         bool find( K const& key, Func f )
681         {
682             return bucket( key ).find( key, f );
683         }
684
685         /// Finds the key \p val using \p pred predicate for searching
686         /**
687             The function is an analog of \ref cds_nonintrusive_MichaelMap_find_cfunc "find(K const&, Func)"
688             but \p pred is used for key comparing.
689             \p Less functor has the interface like \p std::less.
690             \p Less must imply the same element order as the comparator used for building the map.
691         */
692         template <typename K, typename Less, typename Func>
693         bool find_with( K const& key, Less pred, Func f )
694         {
695             return bucket( key ).find_with( key, pred, f );
696         }
697
698         /// Finds the key \p key
699         /** \anchor cds_nonintrusive_MichaelMap_find_val
700             The function searches the item with key equal to \p key
701             and returns \p true if it is found, and \p false otherwise.
702         */
703         template <typename K>
704         bool find( K const& key )
705         {
706             return bucket( key ).find( key );
707         }
708
709         /// Finds the key \p val using \p pred predicate for searching
710         /**
711             The function is an analog of \ref cds_nonintrusive_MichaelMap_find_val "find(K const&)"
712             but \p pred is used for key comparing.
713             \p Less functor has the interface like \p std::less.
714             \p Less must imply the same element order as the comparator used for building the map.
715         */
716         template <typename K, typename Less>
717         bool find_with( K const& key, Less pred )
718         {
719             return bucket( key ).find_with( key, pred );
720         }
721
722         /// Finds \p key and return the item found
723         /** \anchor cds_nonintrusive_MichaelHashMap_hp_get
724             The function searches the item with key equal to \p key
725             and assigns the item found to guarded pointer \p ptr.
726             The function returns \p true if \p key is found, and \p false otherwise.
727             If \p key is not found the \p ptr parameter is not changed.
728
729             @note Each \p guarded_ptr object uses one GC's guard which can be limited resource.
730
731             Usage:
732             \code
733             typedef cds::container::MichaeHashMap< your_template_params >  michael_map;
734             michael_map theMap;
735             // ...
736             {
737                 michael_map::guarded_ptr gp;
738                 if ( theMap.get( gp, 5 )) {
739                     // Deal with gp
740                     //...
741                 }
742                 // Destructor of guarded_ptr releases internal HP guard
743             }
744             \endcode
745
746             Note the compare functor specified for \p OrderedList template parameter
747             should accept a parameter of type \p K that can be not the same as \p key_type.
748         */
749         template <typename K>
750         bool get( guarded_ptr& ptr, K const& key )
751         {
752             return bucket( key ).get( ptr, key );
753         }
754
755         /// Finds \p key and return the item found
756         /**
757             The function is an analog of \ref cds_nonintrusive_MichaelHashMap_hp_get "get( guarded_ptr& ptr, K const&)"
758             but \p pred is used for comparing the keys.
759
760             \p Less functor has the semantics like \p std::less but should take arguments of type \ref key_type and \p K
761             in any order.
762             \p pred must imply the same element order as the comparator used for building the map.
763         */
764         template <typename K, typename Less>
765         bool get_with( guarded_ptr& ptr, K const& key, Less pred )
766         {
767             return bucket( key ).get_with( ptr, key, pred );
768         }
769
770         /// Clears the map (non-atomic)
771         /**
772             The function erases all items from the map.
773
774             The function is not atomic. It cleans up each bucket and then resets the item counter to zero.
775             If there are a thread that performs insertion while \p clear is working the result is undefined in general case:
776             <tt> empty() </tt> may return \p true but the map may contain item(s).
777             Therefore, \p clear may be used only for debugging purposes.
778         */
779         void clear()
780         {
781             for ( size_t i = 0; i < bucket_count(); ++i )
782                 m_Buckets[i].clear();
783             m_ItemCounter.reset();
784         }
785
786         /// Checks if the map is empty
787         /**
788             Emptiness is checked by item counting: if item count is zero then the map is empty.
789             Thus, the correct item counting is an important part of the map implementation.
790         */
791         bool empty() const
792         {
793             return size() == 0;
794         }
795
796         /// Returns item count in the map
797         size_t size() const
798         {
799             return m_ItemCounter;
800         }
801
802         /// Returns the size of hash table
803         /**
804             Since MichaelHashMap cannot dynamically extend the hash table size,
805             the value returned is an constant depending on object initialization parameters;
806             see MichaelHashMap::MichaelHashMap for explanation.
807         */
808         size_t bucket_count() const
809         {
810             return m_nHashBitmask + 1;
811         }
812     };
813 }}  // namespace cds::container
814
815 #endif // ifndef __CDS_CONTAINER_MICHAEL_MAP_H