MichaelList, LazyList, MichaelMap:
[libcds.git] / cds / container / lazy_list_rcu.h
index 757e57dac0776a74e5d9b50cc147559d095f61da..91d1284ae91f07403f19941597f4b1bb2779cbc4 100644 (file)
@@ -1,7 +1,7 @@
 //$$CDS-header$$
 
-#ifndef __CDS_CONTAINER_LAZY_LIST_RCU_H
-#define __CDS_CONTAINER_LAZY_LIST_RCU_H
+#ifndef CDSLIB_CONTAINER_LAZY_LIST_RCU_H
+#define CDSLIB_CONTAINER_LAZY_LIST_RCU_H
 
 #include <memory>
 #include <cds/container/details/lazy_list_base.h>
@@ -130,6 +130,8 @@ namespace cds { namespace container {
 
     public:
         using exempt_ptr = cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer >; ///< pointer to extracted node
+        /// Type of \p get() member function return value
+        typedef value_type * raw_ptr;
 
     private:
         //@cond
@@ -382,12 +384,14 @@ namespace cds { namespace container {
             return emplace_at( head(), std::forward<Args>(args)... );
         }
 
-        /// Ensures that the \p key exists in the list
+        /// Updates data by \p key
         /**
-            The operation performs inserting or changing data with lock-free manner.
+            The operation performs inserting or replacing the element with lock-free manner.
 
             If the \p key not found in the list, then the new item created from \p key
-            is inserted into the list. Otherwise, the functor \p func is called with the item found.
+            will be inserted iff \p bAllowInsert is \p true.
+            Otherwise, if \p key is found, the functor \p func is called with item found.
+
             The functor \p Func signature is:
             \code
                 struct my_functor {
@@ -398,23 +402,31 @@ namespace cds { namespace container {
             with arguments:
             - \p bNew - \p true if the item has been inserted, \p false otherwise
             - \p item - item of the list
-            - \p val - argument \p key passed into the \p ensure function
+            - \p val - argument \p key passed into the \p %update() function
 
-            The functor may change non-key fields of the \p item.
+            The functor may change non-key fields of the \p item;
+            during \p func call \p item is locked so it is safe to modify the item in
+            multi-threaded environment.
 
             The function applies RCU lock internally.
 
             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
             \p second is true if new item has been added or \p false if the item with \p key
-            already is in the list.
-
-            @warning See \ref cds_intrusive_item_creating "insert item troubleshooting"
+            already exists.
         */
         template <typename Q, typename Func>
+        std::pair<bool, bool> update( Q const& key, Func func, bool bAllowInsert = true )
+        {
+            return update_at( head(), key, func, bAllowInsert );
+        }
+        //@cond
+        // Deprecated, use update()
+        template <typename Q, typename Func>
         std::pair<bool, bool> ensure( Q const& key, Func f )
         {
-            return ensure_at( head(), key, f );
+            return update( key, f, true );
         }
+        //@endcond
 
         /// Deletes \p key from the list
         /** \anchor cds_nonintrusive_LazyList_rcu_erase
@@ -536,7 +548,7 @@ namespace cds { namespace container {
 
         /// Extracts an item from the list using \p pred predicate for searching
         /**
-            This function is the analog for \ref cds_nonintrusive_LazyList_rcu_extract "extract(exempt_ptr&, Q const&)".
+            This function is the analog for \p extract(Q const&).
 
             The \p pred is a predicate used for key comparing.
             \p Less has the interface like \p std::less.
@@ -549,32 +561,47 @@ namespace cds { namespace container {
             return exempt_ptr( extract_at( head(), key, typename maker::template less_wrapper<Less>::type()));
         }
 
-        /// Finds the key \p key
-        /** \anchor cds_nonintrusive_LazyList_rcu_find_val
+        /// Checks whether the list contains \p key
+        /**
             The function searches the item with key equal to \p key
             and returns \p true if it is found, and \p false otherwise.
 
-            The function makes RCU lock internally.
+            The function applies RCU lock internally.
         */
         template <typename Q>
-        bool find( Q const& key ) const
+        bool contains( Q const& key ) const
         {
             return find_at( head(), key, intrusive_key_comparator() );
         }
+        //@cond
+        // Deprecated, use contains()
+        template <typename Q>
+        bool find( Q const& key ) const
+        {
+            return contains( key );
+        }
+        //@endcond
 
-        /// Finds the key \p key using \p pred predicate for searching
+        /// Checks whether the list contains \p key using \p pred predicate for searching
         /**
-            The function is an analog of \ref cds_nonintrusive_LazyList_rcu_find_val "find(Q const&)"
-            but \p pred is used for key comparing.
+            The function is an analog of <tt>contains( key )</tt> but \p pred is used for key comparing.
             \p Less functor has the interface like \p std::less.
             \p pred must imply the same element order as the comparator used for building the list.
         */
         template <typename Q, typename Less>
-        bool find_with( Q const& key, Less pred ) const
+        bool contains( Q const& key, Less pred ) const
         {
             CDS_UNUSED( pred );
             return find_at( head(), key, typename maker::template less_wrapper<Less>::type() );
         }
+        //@cond
+        // Deprecated, use contains()
+        template <typename Q, typename Less>
+        bool find_with( Q const& key, Less pred ) const
+        {
+            return contains( key, pred );
+        }
+        //@endcond
 
         /// Finds the key \p key and performs an action with it
         /** \anchor cds_nonintrusive_LazyList_rcu_find_func
@@ -760,12 +787,13 @@ namespace cds { namespace container {
         }
 
         template <typename Q, typename Func>
-        std::pair<bool, bool> ensure_at( head_type& refHead, Q const& key, Func f )
+        std::pair<bool, bool> update_at( head_type& refHead, Q const& key, Func f, bool bAllowInsert )
         {
             scoped_node_ptr pNode( alloc_node( key ));
 
-            std::pair<bool, bool> ret = base_class::ensure_at( &refHead, *pNode,
-                [&f, &key](bool bNew, node_type& node, node_type&){f( bNew, node_to_value(node), key ); });
+            std::pair<bool, bool> ret = base_class::update_at( &refHead, *pNode,
+                [&f, &key](bool bNew, node_type& node, node_type&){f( bNew, node_to_value(node), key );},
+                bAllowInsert );
             if ( ret.first && ret.second )
                 pNode.release();
 
@@ -796,4 +824,4 @@ namespace cds { namespace container {
 
 }} // namespace cds::container
 
-#endif // #ifndef __CDS_CONTAINER_LAZY_LIST_RCU_H
+#endif // #ifndef CDSLIB_CONTAINER_LAZY_LIST_RCU_H