HP refactoring:
[libcds.git] / cds / container / split_list_map.h
index b323be270546c85719922cb793727ed450be9616..29cd7fc8c7a7ac840323a924fda0db4125cf7946 100644 (file)
@@ -25,7 +25,7 @@
     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_H
@@ -155,7 +155,7 @@ namespace cds { namespace container {
         typedef GC     gc;          ///< Garbage collector
         typedef Key    key_type;    ///< key type
         typedef Value  mapped_type; ///< type of value to be stored in the map
-        typedef Traits options;     ///< Map traits
+        typedef Traits traits;      ///< Map traits
 
         typedef std::pair<key_type const, mapped_type>  value_type  ;   ///< key-value pair type
         typedef typename base_class::ordered_list       ordered_list;   ///< Underlying ordered list class
@@ -165,6 +165,9 @@ namespace cds { namespace container {
         typedef typename base_class::item_counter   item_counter; ///< Item counter type
         typedef typename base_class::stat           stat;         ///< Internal statistics
 
+        /// Count of hazard pointer required
+        static CDS_CONSTEXPR const size_t c_nHazardPtrCount = base_class::c_nHazardPtrCount;
+
     protected:
         //@cond
         typedef typename base_class::maker::traits::key_accessor key_accessor;
@@ -176,14 +179,51 @@ namespace cds { namespace container {
         typedef typename gc::template guarded_ptr< node_type, value_type, details::guarded_ptr_cast_set<node_type, value_type> > guarded_ptr;
 
     public:
-        /// Forward iterator (see \p SplitListSet::iterator)
+    ///@name Forward iterators (only for debugging purpose)
+    //@{
+        /// Forward iterator
         /**
-            Remember, the iterator <tt>operator -> </tt> and <tt>operator *</tt> returns \ref value_type pointer and reference.
-            To access item key and value use <tt>it->first</tt> and <tt>it->second</tt> respectively.
+            The forward iterator for a split-list has the following features:
+            - it has no post-increment operator
+            - it depends on underlying ordered list iterator
+            - The iterator object cannot be moved across thread boundary because it contains GC's guard that is thread-private GC data.
+            - Iterator ensures thread-safety even if you delete the item that iterator points to. However, in case of concurrent
+              deleting operations it is no guarantee that you iterate all item in the split-list.
+              Moreover, a crash is possible when you try to iterate the next element that has been deleted by concurrent thread.
+
+              @warning Use this iterator on the concurrent container for debugging purpose only.
+
+              The iterator interface:
+              \code
+              class iterator {
+              public:
+                  // Default constructor
+                  iterator();
+
+                  // Copy construtor
+                  iterator( iterator const& src );
+
+                  // Dereference operator
+                  value_type * operator ->() const;
+
+                  // Dereference operator
+                  value_type& operator *() const;
+
+                  // Preincrement operator
+                  iterator& operator ++();
+
+                  // Assignment operator
+                  iterator& operator = (iterator const& src);
+
+                  // Equality operators
+                  bool operator ==(iterator const& i ) const;
+                  bool operator !=(iterator const& i ) const;
+              };
+              \endcode
         */
         typedef typename base_class::iterator iterator;
 
-        /// Const forward iterator (see SplitListSet::const_iterator)
+        /// Const forward iterator
         typedef typename base_class::const_iterator const_iterator;
 
         /// Returns a forward iterator addressing the first element in a map
@@ -207,28 +247,29 @@ namespace cds { namespace container {
         }
 
         /// Returns a forward const iterator addressing the first element in a map
-        //@{
         const_iterator begin() const
         {
             return base_class::begin();
         }
+
+        /// Returns a forward const iterator addressing the first element in a map
         const_iterator cbegin() const
         {
             return base_class::cbegin();
         }
-        //@}
 
         /// Returns an const iterator that addresses the location succeeding the last element in a map
-        //@{
         const_iterator end() const
         {
             return base_class::end();
         }
+
+        /// Returns an const iterator that addresses the location succeeding the last element in a map
         const_iterator cend() const
         {
             return base_class::cend();
         }
-        //@}
+    //@}
 
     public:
         /// Initializes split-ordered map of default capacity
@@ -264,8 +305,7 @@ namespace cds { namespace container {
         template <typename K>
         bool insert( K const& key )
         {
-            //TODO: pass arguments by reference (make_pair makes copy)
-            return base_class::insert( std::make_pair( key, mapped_type()));
+            return base_class::emplace( key_type( key ), mapped_type() );
         }
 
         /// Inserts new node
@@ -282,8 +322,7 @@ namespace cds { namespace container {
         template <typename K, typename V>
         bool insert( K const& key, V const& val )
         {
-            //TODO: pass arguments by reference (make_pair makes copy)
-            return base_class::insert( std::make_pair(key, val));
+            return base_class::emplace( key_type( key ), mapped_type( val ));
         }
 
         /// Inserts new node and initialize it by a functor
@@ -321,7 +360,7 @@ namespace cds { namespace container {
         bool insert_with( K const& key, Func func )
         {
             //TODO: pass arguments by reference (make_pair makes copy)
-            return base_class::insert( std::make_pair( key, mapped_type()), func );
+            return base_class::insert( std::make_pair( key_type( key ), mapped_type()), func );
         }
 
         /// For key \p key inserts data of type \p mapped_type created from \p args
@@ -333,7 +372,7 @@ namespace cds { namespace container {
         template <typename K, typename... Args>
         bool emplace( K&& key, Args&&... args )
         {
-            return base_class::emplace( std::forward<K>(key), std::move(mapped_type(std::forward<Args>(args)...)));
+            return base_class::emplace( key_type( std::forward<K>(key)), mapped_type( std::forward<Args>(args)...));
         }
 
         /// Updates the node
@@ -354,7 +393,7 @@ namespace cds { namespace container {
             - \p bNew - \p true if the item has been inserted, \p false otherwise
             - \p item - item of the map
 
-            Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
+            Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successful,
             \p second is true if new item has been added or \p false if the item with \p key
             already is in the map.
 
@@ -366,8 +405,10 @@ namespace cds { namespace container {
         std::pair<bool, bool> update( K const& key, Func func, bool bAllowInsert = true )
         {
             //TODO: pass arguments by reference (make_pair makes copy)
-            return base_class::update( std::make_pair( key, mapped_type()),
-                [&func](bool bNew, value_type& item, value_type const& /*val*/) {
+            typedef decltype( std::make_pair( key_type( key ), mapped_type() )) arg_pair_type;
+
+            return base_class::update( std::make_pair( key_type( key ), mapped_type()),
+                [&func]( bool bNew, value_type& item, arg_pair_type const& /*val*/ ) {
                     func( bNew, item );
                 },
                 bAllowInsert );
@@ -470,9 +511,7 @@ namespace cds { namespace container {
         template <typename K>
         guarded_ptr extract( K const& key )
         {
-            guarded_ptr gp;
-            base_class::extract_( gp.guard(), key );
-            return gp;
+            return base_class::extract_( key );
         }
 
         /// Extracts the item using compare functor \p pred
@@ -488,9 +527,7 @@ namespace cds { namespace container {
         guarded_ptr extract_with( K const& key, Less pred )
         {
             CDS_UNUSED( pred );
-            guarded_ptr gp;
-            base_class::extract_with_( gp.guard(), key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
-            return gp;
+            return base_class::extract_with_( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
         }
 
         /// Finds the key \p key
@@ -607,9 +644,7 @@ namespace cds { namespace container {
         template <typename K>
         guarded_ptr get( K const& key )
         {
-            guarded_ptr gp;
-            base_class::get_( gp.guard(), key );
-            return gp;
+            return base_class::get_( key );
         }
 
         /// Finds \p key and return the item found
@@ -625,9 +660,7 @@ namespace cds { namespace container {
         guarded_ptr get_with( K const& key, Less pred )
         {
             CDS_UNUSED( pred );
-            guarded_ptr gp;
-            base_class::get_with_( gp.guard(), key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
-            return gp;
+            return base_class::get_with_( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>());
         }
 
         /// Clears the map (not atomic)