Removed redundant spaces
[libcds.git] / cds / intrusive / details / skip_list_base.h
index d4e6de1577764eb7759c7add9d34db992f8c21c9..a3c0ea230830813f1b6825b96cb9e529b212ca72 100644 (file)
@@ -1,7 +1,35 @@
-//$$CDS-header$$
+/*
+    This file is a part of libcds - Concurrent Data Structures library
 
-#ifndef __CDS_INTRUSIVE_DETAILS_SKIP_LIST_BASE_H
-#define __CDS_INTRUSIVE_DETAILS_SKIP_LIST_BASE_H
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    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.
+*/
+
+#ifndef CDSLIB_INTRUSIVE_DETAILS_SKIP_LIST_BASE_H
+#define CDSLIB_INTRUSIVE_DETAILS_SKIP_LIST_BASE_H
 
 #include <cds/intrusive/details/base.h>
 #include <cds/details/marked_ptr.h>
@@ -14,7 +42,6 @@ namespace cds { namespace intrusive {
     /** @ingroup cds_intrusive_helper
     */
     namespace skip_list {
-
         /// The maximum possible height of any skip-list
         static unsigned int const c_nHeightLimit = 32;
 
@@ -80,19 +107,35 @@ namespace cds { namespace intrusive {
             /// Access to element of next pointer array
             atomic_marked_ptr& next( unsigned int nLevel )
             {
-                assert( nLevel < height() );
-                assert( nLevel == 0 || (nLevel > 0 && m_arrNext != nullptr) );
-
+                assert( nLevel < height());
+                assert( nLevel == 0 || (nLevel > 0 && m_arrNext != nullptr));
+
+#           ifdef CDS_THREAD_SANITIZER_ENABLED
+                // TSan false positive: m_arrNext is read-only array
+                CDS_TSAN_ANNOTATE_IGNORE_READS_BEGIN;
+                atomic_marked_ptr& r = nLevel ? m_arrNext[ nLevel - 1] : m_pNext;
+                CDS_TSAN_ANNOTATE_IGNORE_READS_END;
+                return r;
+#           else
                 return nLevel ? m_arrNext[ nLevel - 1] : m_pNext;
+#           endif
             }
 
             /// Access to element of next pointer array (const version)
             atomic_marked_ptr const& next( unsigned int nLevel ) const
             {
-                assert( nLevel < height() );
+                assert( nLevel < height());
                 assert( nLevel == 0 || nLevel > 0 && m_arrNext != nullptr );
 
+#           ifdef CDS_THREAD_SANITIZER_ENABLED
+                // TSan false positive: m_arrNext is read-only array
+                CDS_TSAN_ANNOTATE_IGNORE_READS_BEGIN;
+                atomic_marked_ptr const& r = nLevel ? m_arrNext[ nLevel - 1] : m_pNext;
+                CDS_TSAN_ANNOTATE_IGNORE_READS_END;
+                return r;
+#           else
                 return nLevel ? m_arrNext[ nLevel - 1] : m_pNext;
+#           endif
             }
 
             /// Access to element of next pointer array (same as \ref next function)
@@ -347,12 +390,13 @@ namespace cds { namespace intrusive {
             event_counter   m_nInsertSuccess        ; ///< Count of success insertion
             event_counter   m_nInsertFailed         ; ///< Count of failed insertion
             event_counter   m_nInsertRetries        ; ///< Count of unsuccessful retries of insertion
-            event_counter   m_nEnsureExist          ; ///< Count of \p ensure call for existed node
-            event_counter   m_nEnsureNew            ; ///< Count of \p ensure call for new node
+            event_counter   m_nUpdateExist          ; ///< Count of \p update() call for existed node
+            event_counter   m_nUpdateNew            ; ///< Count of \p update() call for new node
             event_counter   m_nUnlinkSuccess        ; ///< Count of successful call of \p unlink
             event_counter   m_nUnlinkFailed         ; ///< Count of failed call of \p unlink
             event_counter   m_nEraseSuccess         ; ///< Count of successful call of \p erase
             event_counter   m_nEraseFailed          ; ///< Count of failed call of \p erase
+            event_counter   m_nEraseRetry           ; ///< Count of retries while erasing node
             event_counter   m_nFindFastSuccess      ; ///< Count of successful call of \p find and all derivatives (via fast-path)
             event_counter   m_nFindFastFailed       ; ///< Count of failed call of \p find and all derivatives (via fast-path)
             event_counter   m_nFindSlowSuccess      ; ///< Count of successful call of \p find and all derivatives (via slow-path)
@@ -391,12 +435,13 @@ namespace cds { namespace intrusive {
             void onInsertSuccess()          { ++m_nInsertSuccess    ; }
             void onInsertFailed()           { ++m_nInsertFailed     ; }
             void onInsertRetry()            { ++m_nInsertRetries    ; }
-            void onEnsureExist()            { ++m_nEnsureExist      ; }
-            void onEnsureNew()              { ++m_nEnsureNew        ; }
+            void onUpdateExist()            { ++m_nUpdateExist      ; }
+            void onUpdateNew()              { ++m_nUpdateNew        ; }
             void onUnlinkSuccess()          { ++m_nUnlinkSuccess    ; }
             void onUnlinkFailed()           { ++m_nUnlinkFailed     ; }
             void onEraseSuccess()           { ++m_nEraseSuccess     ; }
             void onEraseFailed()            { ++m_nEraseFailed      ; }
+            void onEraseRetry()             { ++m_nEraseRetry; }
             void onFindFastSuccess()        { ++m_nFindFastSuccess  ; }
             void onFindFastFailed()         { ++m_nFindFastFailed   ; }
             void onFindSlowSuccess()        { ++m_nFindSlowSuccess  ; }
@@ -431,12 +476,13 @@ namespace cds { namespace intrusive {
             void onInsertSuccess()          const {}
             void onInsertFailed()           const {}
             void onInsertRetry()            const {}
-            void onEnsureExist()            const {}
-            void onEnsureNew()              const {}
+            void onUpdateExist()            const {}
+            void onUpdateNew()              const {}
             void onUnlinkSuccess()          const {}
             void onUnlinkFailed()           const {}
             void onEraseSuccess()           const {}
             void onEraseFailed()            const {}
+            void onEraseRetry()             const {}
             void onFindFastSuccess()        const {}
             void onFindFastFailed()         const {}
             void onFindSlowSuccess()        const {}
@@ -505,7 +551,7 @@ namespace cds { namespace intrusive {
             /// Item counter
             /**
                 The type for item counting feature.
-                By default, item counting is disabled (\p atomicity::empty_item_counter)
+                By default, item counting is disabled (\p atomicity::empty_item_counter),
                 \p atomicity::item_counter enables it.
             */
             typedef atomicity::empty_item_counter     item_counter;
@@ -583,7 +629,7 @@ namespace cds { namespace intrusive {
                 an allocator should be provided to maintain variable randomly-calculated height of the node
                 since the node can contain up to 32 next pointers. The allocator option is used to allocate an array of next pointers
                 for nodes which height is more than 1. Default is \ref CDS_DEFAULT_ALLOCATOR.
-            - \p opt::back_off - back-off strategy, default is \รง cds::backoff::Default.
+            - \p opt::back_off - back-off strategy, default is \p cds::backoff::Default.
             - \p opt::stat - internal statistics. By default, it is disabled (\p skip_list::empty_stat).
                 To enable it use \p skip_list::stat
         */
@@ -640,7 +686,7 @@ namespace cds { namespace intrusive {
                 static node_type * make_tower( node_type * pNode, unsigned int nHeight )
                 {
                     if ( nHeight > 1 )
-                        pNode->make_tower( nHeight, tower_allocator().NewArray( nHeight - 1, nullptr ) );
+                        pNode->make_tower( nHeight, tower_allocator().NewArray( nHeight - 1, nullptr ));
                     return pNode;
                 }
 
@@ -674,4 +720,4 @@ namespace cds { namespace intrusive {
 
 }}   // namespace cds::intrusive
 
-#endif // #ifndef __CDS_INTRUSIVE_DETAILS_SKIP_LIST_BASE_H
+#endif // #ifndef CDSLIB_INTRUSIVE_DETAILS_SKIP_LIST_BASE_H