X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=cds%2Fcontainer%2Fmichael_set_rcu.h;h=868ae8906d5ca6303277a703c49c396f074829bd;hb=87ca48743e139e11be544799cc58f4064453c5c0;hp=3bf12d8c41827bdc34115b1530b8ab89ffb80aed;hpb=f6e850d5045fe1fad28e440907b0f3b710d7a0be;p=libcds.git diff --git a/cds/container/michael_set_rcu.h b/cds/container/michael_set_rcu.h index 3bf12d8c..868ae890 100644 --- a/cds/container/michael_set_rcu.h +++ b/cds/container/michael_set_rcu.h @@ -123,6 +123,7 @@ namespace cds { namespace container { typedef typename bucket_type::rcu_lock rcu_lock; ///< RCU scoped lock typedef typename bucket_type::exempt_ptr exempt_ptr; ///< pointer to extracted node + typedef typename bucket_type::raw_ptr raw_ptr; ///< Return type of \p get() member function and its derivatives /// Group of \p extract_xxx functions require external locking if underlying ordered list requires that static CDS_CONSTEXPR const bool c_bExtractLockExternal = bucket_type::c_bExtractLockExternal; @@ -237,7 +238,13 @@ namespace cds { namespace container { public: /// Initialize hash set - /** @copydetails cds_nonintrusive_MichaelHashSet_hp_ctor + /** + The Michael's hash set is non-expandable container. You should point the average count of items \p nMaxItemCount + when you create an object. + \p nLoadFactor parameter defines average count of items per bucket and it should be small number between 1 and 10. + Remember, since the bucket implementation is an ordered list, searching in the bucket is linear [O(nLoadFactor)]. + + The ctor defines hash table size as rounding nMaxItemCount / nLoadFactor up to nearest power of two. */ MichaelHashSet( size_t nMaxItemCount, ///< estimation of max item count in the hash set @@ -456,11 +463,11 @@ namespace cds { namespace container { unlinks it from the set, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item found. If the item with the key equal to \p key is not found the function return an empty \p exempt_ptr. - @note The function does NOT call RCU read-side lock or synchronization, - and does NOT dispose the item found. It just excludes the item from the set - and returns a pointer to item found. - You should lock RCU before calling of the function, and you should synchronize RCU - outside the RCU lock to free extracted item + The function just excludes the item from the set and returns a pointer to item found. + Depends on \p bucket_type you should or should not lock RCU before calling of this function: + - for the set based on \ref cds_nonintrusive_MichaelList_rcu "MichaelList" RCU should not be locked + - for the set based on \ref cds_nonintrusive_LazyList_rcu "LazyList" RCU should be locked + See ordered list implementation for details. \code #include @@ -474,18 +481,15 @@ namespace cds { namespace container { rcu_michael_set theSet; // ... - rcu_michael_set::exempt_ptr p; - { - // first, we should lock RCU - rcu_michael_set::rcu_lock lock; - - // Now, you can apply extract function - // Note that you must not delete the item found inside the RCU lock - p = theSet.extract( 10 ); - if ( p ) { - // do something with p - ... - } + typename rcu_michael_set::exempt_ptr p; + + // For MichaelList we should not lock RCU + + // Note that you must not delete the item found inside the RCU lock + p = theSet.extract( 10 ); + if ( p ) { + // do something with p + ... } // We may safely release p here @@ -545,13 +549,13 @@ namespace cds { namespace container { The function returns \p true if \p key is found, \p false otherwise. */ template - bool find( Q& key, Func f ) const + bool find( Q& key, Func f ) { return bucket( key ).find( key, f ); } //@cond template - bool find( Q const& key, Func f ) const + bool find( Q const& key, Func f ) { return bucket( key ).find( key, f ); } @@ -565,13 +569,13 @@ namespace cds { namespace container { \p Less must imply the same element order as the comparator used for building the set. */ template - bool find_with( Q& key, Less pred, Func f ) const + bool find_with( Q& key, Less pred, Func f ) { return bucket( key ).find_with( key, pred, f ); } //@cond template - bool find_with( Q const& key, Less pred, Func f ) const + bool find_with( Q const& key, Less pred, Func f ) { return bucket( key ).find_with( key, pred, f ); } @@ -587,7 +591,7 @@ namespace cds { namespace container { should accept a parameter of type \p Q that may be not the same as \p value_type. */ template - bool find( Q const & key ) const + bool find( Q const & key ) { return bucket( key ).find( key ); } @@ -600,7 +604,7 @@ namespace cds { namespace container { \p Less must imply the same element order as the comparator used for building the set. */ template - bool find_with( Q const & key, Less pred ) const + bool find_with( Q const & key, Less pred ) { return bucket( key ).find_with( key, pred ); } @@ -609,6 +613,8 @@ namespace cds { namespace container { /** \anchor cds_nonintrusive_MichaelHashSet_rcu_get The function searches the item with key equal to \p key and returns the pointer to item found. If \p key is not found it returns \p nullptr. + Note the type of returned value depends on underlying \p bucket_type. + For details, see documentation of ordered list you use. Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type. @@ -617,23 +623,24 @@ namespace cds { namespace container { \code typedef cds::container::MichaelHashSet< your_template_parameters > hash_set; hash_set theSet; + typename hash_set::raw_ptr gp; // ... { // Lock RCU hash_set::rcu_lock lock; - foo * pVal = theSet.get( 5 ); - if ( pVal ) { + gp = theSet.get( 5 ); + if ( gp ) { // Deal with pVal //... } // Unlock RCU by rcu_lock destructor - // pVal can be freed at any time after RCU has been unlocked + // gp can be reclaimed at any time after RCU has been unlocked } \endcode */ template - value_type * get( Q const& key ) const + raw_ptr get( Q const& key ) { return bucket( key ).get( key ); } @@ -648,7 +655,7 @@ namespace cds { namespace container { \p pred must imply the same element order as the comparator used for building the set. */ template - value_type * get_with( Q const& key, Less pred ) const + raw_ptr get_with( Q const& key, Less pred ) { return bucket( key ).get_with( key, pred ); }