Add rational load factor resizing policy
authorMike Krinkin <krinkin.m.u@gmail.com>
Sun, 26 Apr 2015 07:27:01 +0000 (10:27 +0300)
committerMike Krinkin <krinkin.m.u@gmail.com>
Sun, 26 Apr 2015 10:13:05 +0000 (13:13 +0300)
Add separate rational load factor resizing policy so that users
don't need to pay for additional multiplication if they don't need
it. The rational load factor resizing allows to exchange memory for
a bit of performance (about 5-10 %).

cds/container/striped_set/adapter.h
cds/intrusive/striped_set/resizing_policy.h

index f4f56b8d46111874351b81cb1c470de07d190f76..72b78908b6933f44bc0d816fd459d1dd3dd97a88 100644 (file)
@@ -180,6 +180,7 @@ namespace cds { namespace container {
         using cds::intrusive::striped_set::adapted_container;
 
         using cds::intrusive::striped_set::load_factor_resizing;
+        using cds::intrusive::striped_set::rational_load_factor_resizing;
         using cds::intrusive::striped_set::single_bucket_size_threshold;
         using cds::intrusive::striped_set::no_resizing;
 
index 15cb293dcec339991c405155497ad7466b028755..43cb3f3c86f242d46f04b46c06e4ab7132e5edc2 100644 (file)
@@ -84,6 +84,70 @@ namespace cds { namespace intrusive { namespace striped_set {
         {}
     };
 
+    template <size_t Numerator, size_t Denominator = 1>
+    struct rational_load_factor_resizing
+    {
+        static_assert( Denominator != 0, "Denominator must not be zero" );
+
+        /// Main policy operator returns \p true when resizing is needed
+        template <typename Container, typename Bucket>
+        bool operator ()(
+            size_t nSize,                   ///< Current item count of \p container
+            Container const& container,     ///< Container
+            Bucket const& /*bucket*/        ///< reference to a container's bucket (not used)
+        ) const
+        {
+            return nSize * Denominator > container.bucket_count() * Numerator;
+        }
+
+        /// Resets internal state of the policy (does nothing)
+        void reset()
+        {}
+    };
+
+    template <size_t Denominator>
+    struct rational_load_factor_resizing<0, Denominator>
+    {
+        ///@cond
+        const size_t m_nNumerator;
+        const size_t m_nDenominator;
+        //@endcond
+    public:
+        /// Default ctor, load factor is 1/2
+        rational_load_factor_resizing()
+            : m_nNumerator(1), m_nDenominator(2)
+        {}
+
+        /// Ctor with explicitly defined \p nLoadFactor
+        rational_load_factor_resizing( size_t nNumerator, size_t nDenominator )
+            : m_nNumerator( nNumerator ), m_nDenominator( nDenominator )
+        {}
+
+        /// Copy ctor
+        rational_load_factor_resizing( rational_load_factor_resizing const& src )
+            : m_nNumerator( src.m_nNumerator ), m_nDenominator( src.m_nDenominator )
+        {}
+
+        /// Move ctor
+        rational_load_factor_resizing( rational_load_factor_resizing&& src )
+            : m_nNumerator( src.m_nNumerator ), m_nDenominator( src.m_nDenominator )
+        {}
+
+        /// Main policy operator returns \p true when resizing is needed
+        template <typename Container, typename Bucket>
+        bool operator ()(
+            size_t nSize,                   ///< Current item count of \p container
+            Container const& container,     ///< Container
+            Bucket const& /*bucket*/        ///< reference to a container's bucket (not used)
+        )
+        {
+            return nSize * m_nDenominator > container.bucket_count() * m_nNumerator;
+        }
+
+        /// Resets internal state of the policy (does nothing)
+        void reset()
+        {}
+    };
 
     /// Single bucket threshold resizing policy
     /** @ingroup cds_striped_resizing_policy