3 #ifndef CDSLIB_CONTAINER_DETAILS_MULTILEVEL_HASHMAP_BASE_H
4 #define CDSLIB_CONTAINER_DETAILS_MULTILEVEL_HASHMAP_BASE_H
6 #include <cds/intrusive/details/multilevel_hashset_base.h>
7 #include <cds/container/details/base.h>
8 #include <cds/opt/hash.h>
10 namespace cds { namespace container {
11 /// \p MultiLevelHashMap related definitions
12 /** @ingroup cds_nonintrusive_helper
14 namespace multilevel_hashmap {
16 using cds::intrusive::multilevel_hashset::implementation_tag;
19 /// \p MultiLevelHashMap internal statistics, see cds::intrusive::multilevel_hashset::stat
20 template <typename EventCounter = cds::atomicity::event_counter>
21 using stat = cds::intrusive::multilevel_hashset::stat< EventCounter >;
23 /// \p MultiLevelHashMap empty internal statistics
24 typedef cds::intrusive::multilevel_hashset::empty_stat empty_stat;
26 /// Bit-wise memcmp-based comparator for hash value \p T
28 using bitwise_compare = cds::intrusive::multilevel_hashset::bitwise_compare< T >;
30 /// \p MultiLevelHashMap traits
33 /// Hash functor, default is \p std::hash
35 \p MultiLevelHashMap may use any hash functor converting a key to
36 fixed-sized bit-string, for example, <a href="https://en.wikipedia.org/wiki/Secure_Hash_Algorithm">SHA1, SHA2</a>,
37 <a href="https://en.wikipedia.org/wiki/MurmurHash">MurmurHash</a>,
38 <a href="https://en.wikipedia.org/wiki/CityHash">CityHash</a>
39 or its successor <a href="https://code.google.com/p/farmhash/">FarmHash</a>.
41 typedef opt::none hash;
43 /// Hash comparing functor
45 @copydetails cds::intrusive::multilevel_hashset::traits::compare
47 typedef cds::opt::none compare;
49 /// Specifies binary predicate used for hash compare.
51 @copydetails cds::intrusive::multilevel_hashset::traits::less
53 typedef cds::opt::none less;
57 @copydetails cds::intrusive::multilevel_hashset::traits::item_counter
59 typedef cds::atomicity::item_counter item_counter;
63 Default is \ref CDS_DEFAULT_ALLOCATOR
65 typedef CDS_DEFAULT_ALLOCATOR allocator;
67 /// Array node allocator
69 @copydetails cds::intrusive::multilevel_hashset::traits::node_allocator
71 typedef CDS_DEFAULT_ALLOCATOR node_allocator;
73 /// C++ memory ordering model
75 @copydetails cds::intrusive::multilevel_hashset::traits::memory_model
77 typedef cds::opt::v::relaxed_ordering memory_model;
80 typedef cds::backoff::Default back_off;
82 /// Internal statistics
84 @copydetails cds::intrusive::multilevel_hashset::traits::stat
86 typedef empty_stat stat;
88 /// RCU deadlock checking policy (only for \ref cds_container_MultilevelHashMap_rcu "RCU-based MultilevelHashMap")
90 @copydetails cds::intrusive::multilevel_hashset::traits::rcu_check_deadlock
92 typedef cds::opt::v::rcu_throw_deadlock rcu_check_deadlock;
95 /// Metafunction converting option list to \p multilevel_hashmap::traits
97 Supported \p Options are:
98 - \p opt::hash - a hash functor, default is \p std::hash
99 @copydetails traits::hash
100 - \p opt::allocator - item allocator
101 @copydetails traits::allocator
102 - \p opt::node_allocator - array node allocator.
103 @copydetails traits::node_allocator
104 - \p opt::compare - hash comparison functor. No default functor is provided.
105 If the option is not specified, the \p opt::less is used.
106 - \p opt::less - specifies binary predicate used for hash comparison.
107 @copydetails cds::container::multilevel_hashmap::traits::less
108 - \p opt::back_off - back-off strategy used. If the option is not specified, the \p cds::backoff::Default is used.
109 - \p opt::item_counter - the type of item counting feature.
110 @copydetails cds::container::multilevel_hashmap::traits::item_counter
111 - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
112 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
113 - \p opt::stat - internal statistics. By default, it is disabled (\p multilevel_hashmap::empty_stat).
114 To enable it use \p multilevel_hashmap::stat
115 - \p opt::rcu_check_deadlock - a deadlock checking policy for \ref cds_intrusive_MultilevelHashSet_rcu "RCU-based MultilevelHashSet"
116 Default is \p opt::v::rcu_throw_deadlock
118 template <typename... Options>
121 # ifdef CDS_DOXYGEN_INVOKED
122 typedef implementation_defined type ; ///< Metafunction result
124 typedef typename cds::opt::make_options<
125 typename cds::opt::find_type_traits< traits, Options... >::type
130 } // namespace multilevel_hashmap
133 // Forward declaration
134 template < class GC, typename Key, typename T, class Traits = multilevel_hashmap::traits >
135 class MultiLevelHashMap;
141 template <typename GC, typename Key, typename T, typename Traits>
142 struct make_multilevel_hashmap
145 typedef Key key_type;
146 typedef T mapped_type;
147 typedef Traits original_traits;
148 typedef typename cds::opt::v::hash_selector< typename original_traits::hash >::type hasher;
150 typedef typename std::decay<
151 typename std::remove_reference<
152 decltype( hasher()( std::declval<key_type>()) )
155 //typedef typename std::result_of< hasher( std::declval<key_type>()) >::type hash_type;
156 static_assert( !std::is_pointer<hash_type>::value, "hash functor should return a reference to hash value" );
160 std::pair< key_type const, mapped_type> m_Value;
161 hash_type const m_hash;
163 node_type() = delete;
164 node_type( node_type const& ) = delete;
166 template <typename Q>
167 node_type( hasher& h, Q const& key )
168 : m_Value( std::move( std::make_pair( key, mapped_type())))
169 , m_hash( h( m_Value.first ))
172 template <typename Q, typename U >
173 node_type( hasher& h, Q const& key, U const& val )
174 : m_Value( std::move( std::make_pair( key, mapped_type(val))))
175 , m_hash( h( m_Value.first ))
178 template <typename Q, typename... Args>
179 node_type( hasher& h, Q&& key, Args&&... args )
180 : m_Value( std::move( std::make_pair( std::forward<Q>(key), std::move( mapped_type( std::forward<Args>(args)... )))))
181 , m_hash( h( m_Value.first ))
185 typedef cds::details::Allocator< node_type, typename original_traits::allocator > cxx_node_allocator;
189 void operator()( node_type * p ) const
191 cxx_node_allocator().Delete( p );
197 hash_type const& operator()( node_type const& n )
203 struct intrusive_traits: public original_traits
205 typedef get_node_hash hash_accessor;
206 typedef node_disposer disposer;
209 // Metafunction result
210 typedef cds::intrusive::MultiLevelHashSet< GC, node_type, intrusive_traits > type;
212 } // namespace details
215 }} // namespace cds::container
217 #endif // #ifndef CDSLIB_CONTAINER_DETAILS_MULTILEVEL_HASHMAP_BASE_H