+ template <typename Q, typename Compare, typename Func>
+ bool find_( Q& val, Compare cmp, Func f )
+ {
+ size_t nHash = hash_value( val );
+ split_list::details::search_value_type<Q> sv( val, split_list::regular_hash<bit_reversal>( nHash ));
+ aux_node_type * pHead = get_bucket( nHash );
+ assert( pHead != nullptr );
+
+ return m_Stat.onFind(
+ m_List.find_at( pHead, sv, cmp,
+ [&f]( value_type& item, split_list::details::search_value_type<Q>& val ) { f( item, val.val ); } )
+ );
+ }
+
+ template <typename Q, typename Compare>
+ bool find_( Q const& val, Compare cmp )
+ {
+ size_t nHash = hash_value( val );
+ split_list::details::search_value_type<Q const> sv( val, split_list::regular_hash<bit_reversal>( nHash ));
+ aux_node_type * pHead = get_bucket( nHash );
+ assert( pHead != nullptr );
+
+ return m_Stat.onFind( m_List.find_at( pHead, sv, cmp ));
+ }
+
+ template <typename Q, typename Compare>
+ iterator find_iterator_( Q const& val, Compare cmp )
+ {
+ size_t nHash = hash_value( val );
+ split_list::details::search_value_type<Q const> sv( val, split_list::regular_hash<bit_reversal>( nHash ));
+ aux_node_type * pHead = get_bucket( nHash );
+ assert( pHead != nullptr );
+
+ return iterator( m_List.find_iterator_at( pHead, sv, cmp ), m_List.end());
+ }
+
+ template <typename Q, typename Compare>
+ guarded_ptr get_( Q const& val, Compare cmp )
+ {
+ size_t nHash = hash_value( val );
+ split_list::details::search_value_type<Q const> sv( val, split_list::regular_hash<bit_reversal>( nHash ));
+ aux_node_type * pHead = get_bucket( nHash );
+ assert( pHead != nullptr );
+
+ guarded_ptr gp = m_List.get_at( pHead, sv, cmp );
+ m_Stat.onFind( !gp.empty());
+ return gp;
+ }
+
+ template <typename Q>
+ guarded_ptr get_( Q const& key )
+ {
+ return get_( key, key_comparator());
+ }
+
+ template <typename Q, typename Less>
+ guarded_ptr get_with_( Q const& key, Less )
+ {
+ return get_( key, typename ordered_list_adapter::template make_compare_from_less<Less>());
+ }
+
+ template <typename Q, typename Compare, typename Func>
+ bool erase_( Q const& val, Compare cmp, Func f )
+ {
+ size_t nHash = hash_value( val );
+ split_list::details::search_value_type<Q const> sv( val, split_list::regular_hash<bit_reversal>( nHash ));
+ aux_node_type * pHead = get_bucket( nHash );
+ assert( pHead != nullptr );
+
+ if ( m_List.erase_at( pHead, sv, cmp, f )) {
+ --m_ItemCounter;
+ m_Stat.onEraseSuccess();
+ return true;
+ }
+ m_Stat.onEraseFailed();
+ return false;
+ }
+
+ template <typename Q, typename Compare>
+ bool erase_( Q const& val, Compare cmp )
+ {
+ size_t nHash = hash_value( val );
+ split_list::details::search_value_type<Q const> sv( val, split_list::regular_hash<bit_reversal>( nHash ));
+ aux_node_type * pHead = get_bucket( nHash );
+ assert( pHead != nullptr );
+
+ if ( m_List.erase_at( pHead, sv, cmp )) {
+ --m_ItemCounter;
+ m_Stat.onEraseSuccess();
+ return true;
+ }
+ m_Stat.onEraseFailed();
+ return false;
+ }
+
+ template <typename Q, typename Compare>
+ guarded_ptr extract_( Q const& val, Compare cmp )
+ {
+ size_t nHash = hash_value( val );
+ split_list::details::search_value_type<Q const> sv( val, split_list::regular_hash<bit_reversal>( nHash ));
+ aux_node_type * pHead = get_bucket( nHash );
+ assert( pHead != nullptr );
+
+ guarded_ptr gp = m_List.extract_at( pHead, sv, cmp );
+ if ( gp ) {
+ --m_ItemCounter;
+ m_Stat.onExtractSuccess();
+ }
+ else
+ m_Stat.onExtractFailed();
+ return gp;
+ }
+
+ template <typename Q>
+ guarded_ptr extract_( Q const& key )
+ {
+ return extract_( key, key_comparator());
+ }
+
+ template <typename Q, typename Less>
+ guarded_ptr extract_with_( Q const& key, Less )
+ {
+ return extract_( key, typename ordered_list_adapter::template make_compare_from_less<Less>());
+ }
+ //@endcond
+
+ protected:
+ //@cond
+ static unsigned const c_padding = cds::opt::actual_padding< traits::padding >::value;
+
+ typedef typename cds::details::type_padding< bucket_table, c_padding >::type padded_bucket_table;
+ padded_bucket_table m_Buckets; ///< bucket table
+
+ typedef typename cds::details::type_padding< ordered_list_wrapper, c_padding >::type padded_ordered_list;
+ padded_ordered_list m_List; ///< Ordered list containing split-list items
+
+ atomics::atomic<size_t> m_nBucketCountLog2; ///< log2( current bucket count )
+ atomics::atomic<size_t> m_nMaxItemCount; ///< number of items container can hold, before we have to resize
+ hash m_HashFunctor; ///< Hash functor
+ item_counter m_ItemCounter; ///< Item counter
+ stat m_Stat; ///< Internal statistics
+ //@endcond