[FeldmanHashSet/Map]: hash splitter algo can be specified in Traits
authorkhizmax <libcds.dev@gmail.com>
Sun, 19 Feb 2017 08:54:34 +0000 (11:54 +0300)
committerkhizmax <libcds.dev@gmail.com>
Sun, 19 Feb 2017 08:54:34 +0000 (11:54 +0300)
cds/algo/split_bitstring.h
cds/container/details/feldman_hashset_base.h
cds/intrusive/details/feldman_hashset_base.h

index 4f56fc56459a3bf36ed8478ed5962cf21ec08338..7935e8e7f69cd2bd305d154a631d9c4d8de31b87 100644 (file)
@@ -37,7 +37,7 @@ namespace cds { namespace algo {
 
     /// Cuts a bit sequence from fixed-size bit-string
     /**
-        The splitter can be used as iterator over bit-string.
+        The splitter can be used as an iterator over bit-string.
         Each call of \p cut() or \p safe_cut() cuts the bit count specified
         and keeps the position inside bit-string for the next call.
 
@@ -48,7 +48,7 @@ namespace cds { namespace algo {
         - \p BitString - a fixed-sized type that interprets as bit string
         - \p BitStringSize - the size of \p BitString in bytes, default is <tt>sizeof( BitString )</tt>.
              You can specify 0 for default.
-        - \p UInt - an unsigned integer, return type of \p cut()
+        - \p UInt - an unsigned integer, return type for \p cut()
     */
     template <typename BitString, size_t BitStringSize = sizeof( BitString ), typename UInt = typename std::conditional< BitStringSize % sizeof(size_t) == 0, size_t, unsigned >::type >
     class split_bitstring
@@ -58,6 +58,9 @@ namespace cds { namespace algo {
         typedef UInt      uint_type;    ///< Bit-string portion type
         static CDS_CONSTEXPR size_t const c_bitstring_size = BitStringSize ? BitStringSize : sizeof( BitString ); ///< size of \p BitString in bytes
 
+        /// Minimum count of bits to be cut
+        static CDS_CONSTEXPR size_t const c_nMinBitCut = 1;
+
         //@cond
         static CDS_CONSTEXPR size_t const c_nHashSize   = (c_bitstring_size + sizeof(uint_type) - 1) / sizeof(uint_type);
         static CDS_CONSTEXPR size_t const c_nBitPerByte = 8;
index 02016d699b885f3d88b4407bda8617f2749b4b45..56074a3b751ab4968824d7d5d660783d84be162d 100644 (file)
@@ -53,6 +53,13 @@ namespace cds { namespace container {
         template <size_t Size>
         using hash_size = cds::intrusive::feldman_hashset::hash_size< Size >;
 
+        /// Hash splitter
+        /**
+            @copydetails cds::intrusive::feldman_hashset::traits::hash_splitter
+        */
+        template <typename Splitter>
+        using hash_splitter = cds::intrusive::feldman_hashset::hash_splitter< Splitter >;
+
         /// \p FeldmanHashSet internal statistics, see cds::intrusive::feldman_hashset::stat
         template <typename EventCounter = cds::atomicity::event_counter>
         using stat = cds::intrusive::feldman_hashset::stat< EventCounter >;
@@ -82,6 +89,12 @@ namespace cds { namespace container {
             */
             static CDS_CONSTEXPR size_t const hash_size = 0;
 
+            /// Hash splitter
+            /**
+                @copydetails cds::intrusive::feldman_hashset::traits::hash_splitter
+            */
+            typedef cds::opt::none hash_splitter;
+
             /// Hash comparing functor
             /**
                 @copydetails cds::intrusive::feldman_hashset::traits::compare
@@ -141,6 +154,8 @@ namespace cds { namespace container {
                 @copydetails traits::hash_accessor
             - \p feldman_hashset::hash_size - the size of hash value in bytes.
                 @copydetails traits::hash_size
+            - \p feldman_hashset::hash_splitter - a hash splitter algorithm
+                @copydetails traits::hash_splitter
             - \p opt::allocator - item allocator
                 @copydetails traits::allocator
             - \p opt::node_allocator - array node allocator.
index 00707e068a2d5b7a370b4473aaaa4367d05d4e0f..75abfe260cfa3934980cde21c0aad3ea46f286e9 100644 (file)
@@ -77,6 +77,21 @@ namespace cds { namespace intrusive {
             //@endcond
         };
 
+        /// Hash splitter option
+        /**
+            @copydetails traits::hash_splitter
+        */
+        template <typename Splitter>
+        struct hash_splitter {
+            //@cond
+            template <typename Base> struct pack: public Base
+            {
+                typedef Splitter hash_splitter;
+            };
+            //@endcond
+        };
+
+
         /// \p FeldmanHashSet internal statistics
         template <typename EventCounter = cds::atomicity::event_counter>
         struct stat {
@@ -197,6 +212,13 @@ namespace cds { namespace intrusive {
             */
             static CDS_CONSTEXPR size_t const hash_size = 0;
 
+            /// Hash splitter
+            /**
+                This trait specifies hash bit-string splitter algorithm.
+                By default, \p cds::algo::split_bitstring< HashType, HashSize > is used
+            */
+            typedef cds::opt::none hash_splitter;
+
             /// Disposer for removing data nodes
             typedef cds::intrusive::opt::v::empty_disposer disposer;
 
@@ -262,6 +284,8 @@ namespace cds { namespace intrusive {
                 @copydetails traits::hash_accessor
             - \p feldman_hashset::hash_size - the size of hash value in bytes.
                 @copydetails traits::hash_size
+            - \p feldman_hashset::hash_splitter - a hash splitter algorithm
+                @copydetails traits::hash_splitter
             - \p opt::node_allocator - array node allocator.
                 @copydetails traits::node_allocator
             - \p opt::compare - hash comparison functor. No default functor is provided.
@@ -404,7 +428,11 @@ namespace cds { namespace intrusive {
             /// The size of hash_type in bytes, see \p traits::hash_size for explanation
             static CDS_CONSTEXPR size_t const c_hash_size = traits::hash_size == 0 ? sizeof( hash_type ) : static_cast<size_t>( traits::hash_size );
 
-            typedef feldman_hashset::details::hash_splitter< hash_type, c_hash_size > hash_splitter;
+            typedef typename std::conditional<
+                std::is_same< typename traits::hash_splitter, cds::opt::none >::value,
+                feldman_hashset::details::hash_splitter< hash_type, c_hash_size >,
+                typename traits::hash_splitter
+            >::type hash_splitter;
 
             enum node_flags {
                 flag_array_converting = 1,   ///< the cell is converting from data node to an array node