# endif
};
+
+ //@cond
+ template <typename Stat>
+ struct select_stat_wrapper
+ {
+ typedef Stat stat;
+ typedef iterable_list::wrapped_stat<Stat> wrapped_stat;
+ enum {
+ empty = false
+ };
+ };
+
+ template <>
+ struct select_stat_wrapper< empty_stat >
+ {
+ typedef empty_stat stat;
+ typedef empty_stat wrapped_stat;
+ enum {
+ empty = true
+ };
+ };
+
+ template <typename Stat>
+ struct select_stat_wrapper< iterable_list::wrapped_stat<Stat>>: public select_stat_wrapper<Stat>
+ {};
+ //@endcond
+
} // namespace iterable_list
//@cond
# endif
};
+ //@cond
+ template <typename Stat>
+ struct select_stat_wrapper
+ {
+ typedef Stat stat;
+ typedef lazy_list::wrapped_stat<Stat> wrapped_stat;
+ enum {
+ empty = false
+ };
+ };
+
+ template <>
+ struct select_stat_wrapper< empty_stat >
+ {
+ typedef empty_stat stat;
+ typedef empty_stat wrapped_stat;
+ enum {
+ empty = true
+ };
+ };
+
+ template <typename Stat>
+ struct select_stat_wrapper< lazy_list::wrapped_stat<Stat>>: public select_stat_wrapper< Stat >
+ {};
+ //@endcond
+
} // namespace lazy_list
//@cond
# endif
};
+
+ //@cond
+ template <typename Stat>
+ struct select_stat_wrapper
+ {
+ typedef Stat stat;
+ typedef michael_list::wrapped_stat<Stat> wrapped_stat;
+ enum {
+ empty = false
+ };
+ };
+
+ template <>
+ struct select_stat_wrapper< empty_stat >
+ {
+ typedef empty_stat stat;
+ typedef empty_stat wrapped_stat;
+ enum {
+ empty = true
+ };
+ };
+
+ template <typename Stat>
+ struct select_stat_wrapper< michael_list::wrapped_stat<Stat>>: public select_stat_wrapper< Stat >
+ {};
+
+ //@endcond
+
} // namespace michael_list
//@cond
template <typename OrderedList, bool IsConst>
class iterator
{
- friend class iterator < OrderedList, !IsConst >;
+ friend class iterator< OrderedList, !IsConst >;
+
protected:
typedef OrderedList bucket_type;
typedef typename list_iterator_selector< bucket_type, IsConst>::bucket_ptr bucket_ptr;
, typename cds::opt::make_options< traits, Options...>::type
> type;
};
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = iterable_list::select_stat_wrapper< Stat >;
//@endcond
protected:
, typename cds::opt::make_options< traits, Options...>::type
> type;
};
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = lazy_list::select_stat_wrapper< Stat >;
//@endcond
protected:
, typename cds::opt::make_options< traits, Options...>::type
> type;
};
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = michael_list::select_stat_wrapper< Stat >;
//@endcond
protected:
, typename cds::opt::make_options< traits, Options...>::type
> type;
};
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = lazy_list::select_stat_wrapper< Stat >;
//@endcond
protected:
, typename cds::opt::make_options< traits, Options...>::type
> type;
};
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = lazy_list::select_stat_wrapper< Stat >;
//@endcond
protected:
, typename cds::opt::make_options< traits, Options...>::type
> type;
};
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = michael_list::select_stat_wrapper< Stat >;
//@endcond
protected:
, typename cds::opt::make_options< traits, Options...>::type
> type;
};
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = michael_list::select_stat_wrapper< Stat >;
//@endcond
protected:
#define CDSLIB_INTRUSIVE_MICHAEL_SET_H
#include <cds/intrusive/details/michael_set_base.h>
-#include <cds/details/allocator.h>
#include <cds/intrusive/details/iterable_list_base.h>
namespace cds { namespace intrusive {
Template parameters are:
- \p GC - Garbage collector used. Note the \p GC must be the same as the GC used for \p OrderedList
- - \p OrderedList - ordered list implementation used as bucket for hash set, for example, \p MichaelList, \p LazyList.
+ - \p OrderedList - ordered list implementation used as bucket for hash set, for example, \p MichaelList, \p LazyList, \p IterableList.
The intrusive ordered list implementation specifies the type \p T stored in the hash-set, the reclamation
schema \p GC used by hash-set, the comparison functor for the type \p T and other features specific for
the ordered list.
\code
// Our node type
struct Foo {
- std::string key_; // key field
+ std::string key_; // key field
// ... other fields
};
public:
typedef GC gc; ///< Garbage collector
typedef OrderedList ordered_list; ///< type of ordered list used as a bucket implementation
- typedef ordered_list bucket_type; ///< bucket type
- typedef Traits traits; ///< Set traits
+ typedef Traits traits; ///< Set traits
- typedef typename ordered_list::value_type value_type ; ///< type of value to be stored in the set
- typedef typename ordered_list::key_comparator key_comparator ; ///< key comparing functor
- typedef typename ordered_list::disposer disposer ; ///< Node disposer functor
+ typedef typename ordered_list::value_type value_type ; ///< type of value to be stored in the set
+ typedef typename ordered_list::key_comparator key_comparator ; ///< key comparing functor
+ typedef typename ordered_list::disposer disposer ; ///< Node disposer functor
+ typedef typename ordered_list::stat stat ; ///< Internal statistics
/// Hash functor for \p value_type and all its derivatives that you use
typedef typename cds::opt::v::hash_selector< typename traits::hash >::type hash;
typedef typename traits::item_counter item_counter; ///< Item counter type
+ typedef typename traits::allocator allocator; ///< Bucket table allocator
typedef typename ordered_list::guarded_ptr guarded_ptr; ///< Guarded pointer
- /// Bucket table allocator
- typedef cds::details::Allocator< bucket_type, typename traits::allocator > bucket_table_allocator;
-
/// Count of hazard pointer required for the algorithm
static CDS_CONSTEXPR const size_t c_nHazardPtrCount = ordered_list::c_nHazardPtrCount;
- protected:
- item_counter m_ItemCounter; ///< Item counter
- hash m_HashFunctor; ///< Hash functor
- bucket_type * m_Buckets; ///< bucket table
+ // GC and OrderedList::gc must be the same
+ static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
- private:
- //@cond
- const size_t m_nHashBitmask;
- //@endcond
+ // atomicity::empty_item_counter is not allowed as a item counter
+ static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
+ "cds::atomicity::empty_item_counter is not allowed as a item counter");
protected:
//@cond
- /// Calculates hash value of \p key
- template <typename Q>
- size_t hash_value( const Q& key ) const
- {
- return m_HashFunctor( key ) & m_nHashBitmask;
- }
+ typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
- /// Returns the bucket (ordered list) for \p key
- template <typename Q>
- bucket_type& bucket( const Q& key )
- {
- return m_Buckets[ hash_value( key ) ];
- }
+ typedef typename ordered_list::template rebind_traits<
+ cds::opt::item_counter< cds::atomicity::empty_item_counter >
+ , cds::opt::stat< typename bucket_stat::wrapped_stat >
+ >::type internal_bucket_type;
+
+ typedef typename allocator::template rebind< internal_bucket_type >::other bucket_table_allocator;
+
+ hash m_HashFunctor; ///< Hash functor
+ size_t const m_nHashBitmask;
+ internal_bucket_type* m_Buckets; ///< bucket table
+ item_counter m_ItemCounter; ///< Item counter
+ typename bucket_stat::stat m_Stat; ///< Internal statistics
//@endcond
public:
- for \p IterableList: iterator is thread-safe. You may use it freely in concurrent environment.
*/
- typedef michael_set::details::iterator< bucket_type, false > iterator;
+ typedef michael_set::details::iterator< internal_bucket_type, false > iterator;
/// Const forward iterator
/**
For iterator's features and requirements see \ref iterator
*/
- typedef michael_set::details::iterator< bucket_type, true > const_iterator;
+ typedef michael_set::details::iterator< internal_bucket_type, true > const_iterator;
/// Returns a forward iterator addressing the first element in a set
/**
*/
iterator end()
{
- return iterator( m_Buckets[bucket_count() - 1].end(), bucket_end() + 1, bucket_end() );
+ return iterator( bucket_end()[-1].end(), bucket_end() - 1, bucket_end() );
}
/// Returns a forward const iterator addressing the first element in a set
}
//@}
- private:
- //@cond
- bucket_type * bucket_begin() const
- {
- return m_Buckets;
- }
-
- bucket_type * bucket_end() const
- {
- return m_Buckets + bucket_count();
- }
-
- const_iterator get_const_begin() const
- {
- return const_iterator( m_Buckets[0].cbegin(), bucket_begin(), bucket_end() );
- }
- const_iterator get_const_end() const
- {
- return const_iterator( m_Buckets[bucket_count() - 1].cend(), bucket_end() - 1, bucket_end() );
- }
- //@endcond
-
public:
/// Initializes hash set
/** @anchor cds_intrusive_MichaelHashSet_hp_ctor
size_t nMaxItemCount, ///< estimation of max item count in the hash set
size_t nLoadFactor ///< load factor: estimation of max number of items in the bucket. Small integer up to 10.
) : m_nHashBitmask( michael_set::details::init_hash_bitmask( nMaxItemCount, nLoadFactor ))
+ , m_Buckets( bucket_table_allocator().allocate( bucket_count()))
{
- // GC and OrderedList::gc must be the same
- static_assert( std::is_same<gc, typename bucket_type::gc>::value, "GC and OrderedList::gc must be the same");
-
- // atomicity::empty_item_counter is not allowed as a item counter
- static_assert( !std::is_same<item_counter, atomicity::empty_item_counter>::value,
- "cds::atomicity::empty_item_counter is not allowed as a item counter");
-
- m_Buckets = bucket_table_allocator().NewArray( bucket_count() );
+ for ( auto it = m_Buckets, itEnd = m_Buckets + bucket_count(); it != itEnd; ++it )
+ construct_bucket<bucket_stat>( it );
}
/// Clears hash set object and destroys it
~MichaelHashSet()
{
clear();
- bucket_table_allocator().Delete( m_Buckets, bucket_count() );
+
+ for ( auto it = m_Buckets, itEnd = m_Buckets + bucket_count(); it != itEnd; ++it )
+ it->~internal_bucket_type();
+ bucket_table_allocator().deallocate( m_Buckets, bucket_count() );
}
/// Inserts new node
#endif
find( Q& key )
{
- bucket_type& b = bucket( key );
- typename ordered_list::iterator it = b.find( key );
+ internal_bucket_type& b = bucket( key );
+ typename internal_bucket_type::iterator it = b.find( key );
if ( it == b.end() )
return end();
return iterator( it, &b, bucket_end());
typename std::enable_if< std::is_same<Q, Q>::value && is_iterable_list< ordered_list >::value, iterator >::type
find( Q const& key )
{
- bucket_type& b = bucket( key );
- typename ordered_list::iterator it = b.find( key );
+ internal_bucket_type& b = bucket( key );
+ typename internal_bucket_type::iterator it = b.find( key );
if ( it == b.end() )
return end();
return iterator( it, &b, bucket_end() );
#endif
find_with( Q& key, Less pred )
{
- bucket_type& b = bucket( key );
- typename ordered_list::iterator it = b.find_with( key, pred );
+ internal_bucket_type& b = bucket( key );
+ typename internal_bucket_type::iterator it = b.find_with( key, pred );
if ( it == b.end() )
return end();
return iterator( it, &b, bucket_end() );
typename std::enable_if< std::is_same<Q, Q>::value && is_iterable_list< ordered_list >::value, iterator >::type
find_with( Q const& key, Less pred )
{
- bucket_type& b = bucket( key );
- typename ordered_list::iterator it = b.find_with( key, pred );
+ internal_bucket_type& b = bucket( key );
+ typename internal_bucket_type::iterator it = b.find_with( key, pred );
if ( it == b.end() )
return end();
return iterator( it, &b, bucket_end() );
return m_ItemCounter;
}
+ /// Returns const reference to internal statistics
+ stat const& statistics() const
+ {
+ return m_Stat;
+ }
+
/// Returns the size of hash table
/**
Since \p %MichaelHashSet cannot dynamically extend the hash table size,
{
return m_nHashBitmask + 1;
}
+
+ private:
+ //@cond
+ internal_bucket_type * bucket_begin() const
+ {
+ return m_Buckets;
+ }
+
+ internal_bucket_type * bucket_end() const
+ {
+ return m_Buckets + bucket_count();
+ }
+
+ const_iterator get_const_begin() const
+ {
+ return const_iterator( m_Buckets[0].cbegin(), bucket_begin(), bucket_end() );
+ }
+ const_iterator get_const_end() const
+ {
+ return const_iterator( bucket_end()[-1].cend(), bucket_end() - 1, bucket_end() );
+ }
+
+ template <typename Stat>
+ typename std::enable_if< Stat::empty >::type construct_bucket( internal_bucket_type * bucket )
+ {
+ new (bucket) internal_bucket_type;
+ }
+
+ template <typename Stat>
+ typename std::enable_if< !Stat::empty >::type construct_bucket( internal_bucket_type * bucket )
+ {
+ new (bucket) internal_bucket_type( m_Stat );
+ }
+
+ /// Calculates hash value of \p key
+ template <typename Q>
+ size_t hash_value( const Q& key ) const
+ {
+ return m_HashFunctor( key ) & m_nHashBitmask;
+ }
+
+ /// Returns the bucket (ordered list) for \p key
+ template <typename Q>
+ internal_bucket_type& bucket( const Q& key )
+ {
+ return m_Buckets[hash_value( key )];
+ }
+ //@endcond
};
}} // namespace cds::intrusive
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.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CDSLIB_INTRUSIVE_MICHAEL_SET_NOGC_H
#include <cds/intrusive/details/michael_set_base.h>
#include <cds/gc/nogc.h>
-#include <cds/details/allocator.h>
namespace cds { namespace intrusive {
class MichaelHashSet< cds::gc::nogc, OrderedList, Traits >
{
public:
- typedef cds::gc::nogc gc; ///< Garbage collector
- typedef OrderedList bucket_type; ///< Type of ordered list to be used as buckets
- typedef Traits traits; ///< Set traits
+ typedef cds::gc::nogc gc; ///< Garbage collector
+ typedef OrderedList ordered_list; ///< type of ordered list used as a bucket implementation
+ typedef Traits traits; ///< Set traits
- typedef typename bucket_type::value_type value_type; ///< type of value to be stored in the set
- typedef typename bucket_type::key_comparator key_comparator; ///< key comparing functor
- typedef typename bucket_type::disposer disposer; ///< Node disposer functor
+ typedef typename ordered_list::value_type value_type; ///< type of value to be stored in the set
+ typedef typename ordered_list::key_comparator key_comparator; ///< key comparing functor
+ typedef typename ordered_list::disposer disposer; ///< Node disposer functor
+ typedef typename ordered_list::stat stat; ///< Internal statistics
/// Hash functor for \p value_type and all its derivatives that you use
typedef typename cds::opt::v::hash_selector< typename traits::hash >::type hash;
typedef typename traits::item_counter item_counter; ///< Item counter type
+ typedef typename traits::allocator allocator; ///< Bucket table allocator
- /// Bucket table allocator
- typedef cds::details::Allocator< bucket_type, typename traits::allocator > bucket_table_allocator;
+ // GC and OrderedList::gc must be the same
+ static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
- protected:
- item_counter m_ItemCounter; ///< Item counter
- hash m_HashFunctor; ///< Hash functor
- bucket_type * m_Buckets; ///< bucket table
+ // atomicity::empty_item_counter is not allowed as a item counter
+ static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
+ "atomicity::empty_item_counter is not allowed as a item counter");
- private:
+ protected:
//@cond
- const size_t m_nHashBitmask;
+ typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
+
+ typedef typename ordered_list::template rebind_traits<
+ cds::opt::item_counter< cds::atomicity::empty_item_counter >
+ , cds::opt::stat< typename bucket_stat::wrapped_stat >
+ >::type internal_bucket_type;
+
+ typedef typename allocator::template rebind< internal_bucket_type >::other bucket_table_allocator;
+
+ hash m_HashFunctor; ///< Hash functor
+ const size_t m_nHashBitmask;
+ internal_bucket_type * m_Buckets; ///< bucket table
+ item_counter m_ItemCounter; ///< Item counter
+ typename bucket_stat::stat m_Stat; ///< Internal statistics
//@endcond
protected:
/// Returns the bucket (ordered list) for \p key
template <typename Q>
- bucket_type& bucket( Q const & key )
+ internal_bucket_type& bucket( Q const & key )
{
return m_Buckets[ hash_value( key ) ];
}
};
\endcode
*/
- typedef michael_set::details::iterator< bucket_type, false > iterator;
+ typedef michael_set::details::iterator< internal_bucket_type, false > iterator;
/// Const forward iterator
/**
For iterator's features and requirements see \ref iterator
*/
- typedef michael_set::details::iterator< bucket_type, true > const_iterator;
+ typedef michael_set::details::iterator< internal_bucket_type, true > const_iterator;
/// Returns a forward iterator addressing the first element in a set
/**
size_t nMaxItemCount, ///< estimation of max item count in the hash set
size_t nLoadFactor ///< load factor: estimation of max number of items in the bucket
) : m_nHashBitmask( michael_set::details::init_hash_bitmask( nMaxItemCount, nLoadFactor ))
+ , m_Buckets( bucket_table_allocator().allocate( bucket_count() ) )
{
- // GC and OrderedList::gc must be the same
- static_assert( std::is_same<gc, typename bucket_type::gc>::value, "GC and OrderedList::gc must be the same");
-
- // atomicity::empty_item_counter is not allowed as a item counter
- static_assert( !std::is_same<item_counter, atomicity::empty_item_counter>::value,
- "atomicity::empty_item_counter is not allowed as a item counter");
-
- m_Buckets = bucket_table_allocator().NewArray( bucket_count() );
+ for ( auto it = m_Buckets, itEnd = m_Buckets + bucket_count(); it != itEnd; ++it )
+ construct_bucket<bucket_stat>( it );
}
/// Clears hash set object and destroys it
~MichaelHashSet()
{
clear();
- bucket_table_allocator().Delete( m_Buckets, bucket_count() );
+
+ for ( auto it = m_Buckets, itEnd = m_Buckets + bucket_count(); it != itEnd; ++it )
+ it->~internal_bucket_type();
+ bucket_table_allocator().deallocate( m_Buckets, bucket_count() );
}
/// Inserts new node
return m_nHashBitmask + 1;
}
+ /// Returns const reference to internal statistics
+ stat const& statistics() const
+ {
+ return m_Stat;
+ }
+
+ private:
+ //@cond
+ template <typename Stat>
+ typename std::enable_if< Stat::empty >::type construct_bucket( internal_bucket_type * bucket )
+ {
+ new (bucket) internal_bucket_type;
+ }
+
+ template <typename Stat>
+ typename std::enable_if< !Stat::empty >::type construct_bucket( internal_bucket_type * bucket )
+ {
+ new (bucket) internal_bucket_type( m_Stat );
+ }
+ //@endcond
};
}} // namespace cds::intrusive
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.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CDSLIB_INTRUSIVE_MICHAEL_SET_RCU_H
#define CDSLIB_INTRUSIVE_MICHAEL_SET_RCU_H
#include <cds/intrusive/details/michael_set_base.h>
-#include <cds/details/allocator.h>
namespace cds { namespace intrusive {
class MichaelHashSet< cds::urcu::gc< RCU >, OrderedList, Traits >
{
public:
- typedef cds::urcu::gc< RCU > gc; ///< RCU schema
- typedef OrderedList bucket_type; ///< type of ordered list used as a bucket implementation
- typedef Traits traits; ///< Set traits
+ typedef cds::urcu::gc< RCU > gc; ///< RCU schema
+ typedef OrderedList ordered_list; ///< type of ordered list used as a bucket implementation
+ typedef Traits traits; ///< Set traits
- typedef typename bucket_type::value_type value_type ; ///< type of value stored in the list
- typedef typename bucket_type::key_comparator key_comparator ; ///< key comparing functor
- typedef typename bucket_type::disposer disposer ; ///< Node disposer functor
+ typedef typename ordered_list::value_type value_type; ///< type of value stored in the list
+ typedef typename ordered_list::key_comparator key_comparator; ///< key comparing functor
+ typedef typename ordered_list::disposer disposer; ///< Node disposer functor
+ typedef typename ordered_list::stat stat; ///< Internal statistics
/// Hash functor for \ref value_type and all its derivatives that you use
typedef typename cds::opt::v::hash_selector< typename traits::hash >::type hash;
typedef typename traits::item_counter item_counter; ///< Item counter type
+ typedef typename traits::allocator allocator; ///< Bucket table allocator
- /// Bucket table allocator
- typedef cds::details::Allocator< bucket_type, typename traits::allocator > bucket_table_allocator;
-
- typedef typename bucket_type::rcu_lock rcu_lock; ///< RCU scoped lock
- typedef typename bucket_type::exempt_ptr exempt_ptr; ///< pointer to extracted node
- typedef typename bucket_type::raw_ptr raw_ptr; ///< Return type of \p get() member function and its derivatives
+ typedef typename ordered_list::rcu_lock rcu_lock; ///< RCU scoped lock
/// Group of \p extract_xxx functions require external locking if underlying ordered list requires that
- static CDS_CONSTEXPR const bool c_bExtractLockExternal = bucket_type::c_bExtractLockExternal;
+ static CDS_CONSTEXPR const bool c_bExtractLockExternal = ordered_list::c_bExtractLockExternal;
- protected:
- item_counter m_ItemCounter; ///< Item counter
- hash m_HashFunctor; ///< Hash functor
- bucket_type * m_Buckets; ///< bucket table
+ // GC and OrderedList::gc must be the same
+ static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
- private:
- //@cond
- const size_t m_nHashBitmask;
- //@endcond
+ // atomicity::empty_item_counter is not allowed as a item counter
+ static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
+ "atomicity::empty_item_counter is not allowed as a item counter");
protected:
//@cond
- /// Calculates hash value of \p key
- template <typename Q>
- size_t hash_value( Q const& key ) const
- {
- return m_HashFunctor( key ) & m_nHashBitmask;
- }
+ typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
- /// Returns the bucket (ordered list) for \p key
- template <typename Q>
- bucket_type& bucket( Q const& key )
- {
- return m_Buckets[ hash_value( key ) ];
- }
- template <typename Q>
- bucket_type const& bucket( Q const& key ) const
- {
- return m_Buckets[ hash_value( key ) ];
- }
+ typedef typename ordered_list::template rebind_traits<
+ cds::opt::item_counter< cds::atomicity::empty_item_counter >
+ , cds::opt::stat< typename bucket_stat::wrapped_stat >
+ >::type internal_bucket_type;
+
+ typedef typename allocator::template rebind< internal_bucket_type >::other bucket_table_allocator;
+ //@endcond
+
+ public:
+ typedef typename internal_bucket_type::exempt_ptr exempt_ptr; ///< pointer to extracted node
+ typedef typename internal_bucket_type::raw_ptr raw_ptr; ///< Return type of \p get() member function and its derivatives
+
+ private:
+ //@cond
+ hash m_HashFunctor; ///< Hash functor
+ size_t const m_nHashBitmask;
+ internal_bucket_type* m_Buckets; ///< bucket table
+ item_counter m_ItemCounter; ///< Item counter
+ typename bucket_stat::stat m_Stat; ///< Internal statistics
//@endcond
public:
};
\endcode
*/
- typedef michael_set::details::iterator< bucket_type, false > iterator;
+ typedef michael_set::details::iterator< internal_bucket_type, false > iterator;
/// Const forward iterator
/**
For iterator's features and requirements see \ref iterator
*/
- typedef michael_set::details::iterator< bucket_type, true > const_iterator;
+ typedef michael_set::details::iterator< internal_bucket_type, true > const_iterator;
/// Returns a forward iterator addressing the first element in a set
/**
size_t nMaxItemCount, ///< estimation of max item count in the hash set
size_t nLoadFactor ///< load factor: average size of the bucket
) : m_nHashBitmask( michael_set::details::init_hash_bitmask( nMaxItemCount, nLoadFactor ))
+ , m_Buckets( bucket_table_allocator().allocate( bucket_count() ) )
{
- // GC and OrderedList::gc must be the same
- static_assert( std::is_same<gc, typename bucket_type::gc>::value, "GC and OrderedList::gc must be the same");
-
- // atomicity::empty_item_counter is not allowed as a item counter
- static_assert( !std::is_same<item_counter, atomicity::empty_item_counter>::value,
- "atomicity::empty_item_counter is not allowed as a item counter");
-
- m_Buckets = bucket_table_allocator().NewArray( bucket_count() );
+ for ( auto it = m_Buckets, itEnd = m_Buckets + bucket_count(); it != itEnd; ++it )
+ construct_bucket<bucket_stat>( it );
}
/// Clear hash set and destroy it
~MichaelHashSet()
{
clear();
- bucket_table_allocator().Delete( m_Buckets, bucket_count() );
+
+ for ( auto it = m_Buckets, itEnd = m_Buckets + bucket_count(); it != itEnd; ++it )
+ it->~internal_bucket_type();
+ bucket_table_allocator().deallocate( m_Buckets, bucket_count() );
}
/// Inserts new node
unlinks it from the set, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item found.
If the item with the key equal to \p key is not found the function returns an empty \p exempt_ptr.
- Depends on \p bucket_type you should or should not lock RCU before calling of this function:
+ Depends on \p ordered_list you should or should not lock RCU before calling of this function:
- for the set based on \ref cds_intrusive_MichaelList_rcu "MichaelList" RCU should not be locked
- for the set based on \ref cds_intrusive_LazyList_rcu "LazyList" RCU should be locked
/** \anchor cds_intrusive_MichaelHashSet_rcu_get
The function searches the item with key equal to \p key and returns the pointer to item found.
If \p key is not found it returns \p nullptr.
- Note the type of returned value depends on underlying \p bucket_type.
+ Note the type of returned value depends on underlying \p ordered_list.
For details, see documentation of ordered list you use.
Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type.
return m_nHashBitmask + 1;
}
+ /// Returns const reference to internal statistics
+ stat const& statistics() const
+ {
+ return m_Stat;
+ }
+
+ private:
+ //@cond
+ template <typename Stat>
+ typename std::enable_if< Stat::empty >::type construct_bucket( internal_bucket_type * bucket )
+ {
+ new (bucket) internal_bucket_type;
+ }
+
+ template <typename Stat>
+ typename std::enable_if< !Stat::empty >::type construct_bucket( internal_bucket_type * bucket )
+ {
+ new (bucket) internal_bucket_type( m_Stat );
+ }
+
+ /// Calculates hash value of \p key
+ template <typename Q>
+ size_t hash_value( Q const& key ) const
+ {
+ return m_HashFunctor( key ) & m_nHashBitmask;
+ }
+
+ /// Returns the bucket (ordered list) for \p key
+ template <typename Q>
+ internal_bucket_type& bucket( Q const& key )
+ {
+ return m_Buckets[hash_value( key )];
+ }
+ template <typename Q>
+ internal_bucket_type const& bucket( Q const& key ) const
+ {
+ return m_Buckets[hash_value( key )];
+ }
+ //@endcond
};
}} // namespace cds::intrusive
#endif // #ifndef CDSLIB_INTRUSIVE_MICHAEL_SET_NOGC_H
-
<Optimization>Disabled</Optimization>\r
<PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <DisableSpecificWarnings>4503</DisableSpecificWarnings>\r
</ClCompile>\r
<Link>\r
<SubSystem>Console</SubSystem>\r
<Optimization>Disabled</Optimization>\r
<PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <DisableSpecificWarnings>4503</DisableSpecificWarnings>\r
</ClCompile>\r
<Link>\r
<SubSystem>Console</SubSystem>\r
<Optimization>Disabled</Optimization>\r
<PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <DisableSpecificWarnings>4503</DisableSpecificWarnings>\r
</ClCompile>\r
<Link>\r
<SubSystem>Console</SubSystem>\r
<Optimization>Disabled</Optimization>\r
<PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <DisableSpecificWarnings>4503</DisableSpecificWarnings>\r
</ClCompile>\r
<Link>\r
<SubSystem>Console</SubSystem>\r
<IntrinsicFunctions>true</IntrinsicFunctions>\r
<PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <DisableSpecificWarnings>4503</DisableSpecificWarnings>\r
</ClCompile>\r
<Link>\r
<SubSystem>Console</SubSystem>\r
<IntrinsicFunctions>true</IntrinsicFunctions>\r
<PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <DisableSpecificWarnings>4503</DisableSpecificWarnings>\r
</ClCompile>\r
<Link>\r
<SubSystem>Console</SubSystem>\r
test( s );
}
+ TEST_F( IntrusiveMichaelIterableSet_DHP, stat )
+ {
+ struct list_traits: public ci::iterable_list::traits
+ {
+ typedef base_class::less<item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::iterable_list::stat<> stat;
+ };
+ typedef ci::IterableList< gc_type, item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelIterableSet_DHP, wrapped_stat )
+ {
+ struct list_traits: public ci::iterable_list::traits
+ {
+ typedef base_class::less<item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::iterable_list::wrapped_stat<> stat;
+ };
+ typedef ci::IterableList< gc_type, item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
test( s );
}
+ TEST_F( IntrusiveMichaelIterableSet_HP, stat )
+ {
+ struct list_traits: public ci::iterable_list::traits
+ {
+ typedef base_class::less<item_type> less;
+ typedef cmp<item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::iterable_list::stat<> stat;
+ };
+ typedef ci::IterableList< gc_type, item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelIterableSet_HP, wrapped_stat )
+ {
+ struct list_traits: public ci::iterable_list::traits
+ {
+ typedef base_class::less<item_type> less;
+ typedef cmp<item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::iterable_list::wrapped_stat<> stat;
+ };
+ typedef ci::IterableList< gc_type, item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
test( s );
}
+ TEST_F( IntrusiveMichaelLazySet_DHP, base_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelLazySet_DHP, base_wrapped_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
TEST_F( IntrusiveMichaelLazySet_DHP, member_cmp )
{
test( s );
}
+ TEST_F( IntrusiveMichaelLazySet_DHP, member_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelLazySet_DHP, member_wrapped_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
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.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test_intrusive_set_hp.h"
test( s );
}
+ TEST_F( IntrusiveMichaelLazySet_HP, base_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>, ci::opt::lock_type<std::mutex>> hook;
+ typedef cmp<base_mutex_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, base_mutex_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelLazySet_HP, base_wrapped_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef cmp<base_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
TEST_F( IntrusiveMichaelLazySet_HP, member_cmp )
{
test( s );
}
+ TEST_F( IntrusiveMichaelLazySet_HP, member_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<member_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelLazySet_HP, member_wrapped_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<member_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
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.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test_intrusive_set_nogc.h"
test( s );
}
+ TEST_F( IntrusiveMichaelLazySet_NoGC, base_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelLazySet_NoGC, base_wrapped_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
TEST_F( IntrusiveMichaelLazySet_NoGC, member_cmp )
{
test( s );
}
+ TEST_F( IntrusiveMichaelLazySet_NoGC, member_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelLazySet_NoGC, member_wrapped_stat )
+ {
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
test( s );
}
+ TEST_F( IntrusiveMichaelSet_DHP, base_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef cmp<base_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelSet_DHP, base_wrapped_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef cmp<base_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
TEST_F( IntrusiveMichaelSet_DHP, member_cmp )
{
test( s );
}
+ TEST_F( IntrusiveMichaelSet_DHP, member_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<member_item_type> less;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelSet_DHP, member_wrapped_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<member_item_type> less;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
}
+ TEST_F( IntrusiveMichaelSet_HP, base_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef cmp<base_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelSet_HP, base_wrapped_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
TEST_F( IntrusiveMichaelSet_HP, member_cmp )
{
typedef ci::MichaelList< gc_type
test( s );
}
+ TEST_F( IntrusiveMichaelSet_HP, member_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<member_item_type> less;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelSet_HP, member_wrapped_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<member_item_type> less;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
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.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test_intrusive_set_nogc.h"
test( s );
}
+ TEST_F( IntrusiveMichaelSet_NoGC, base_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelSet_NoGC, base_wrapped_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<gc_type>> hook;
+ typedef base_class::less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
TEST_F( IntrusiveMichaelSet_NoGC, member_cmp )
{
test( s );
}
+ TEST_F( IntrusiveMichaelSet_NoGC, member_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
+ TEST_F( IntrusiveMichaelSet_NoGC, member_wrapped_stat )
+ {
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<gc_type>> hook;
+ typedef cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< gc_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< gc_type, bucket_type, set_traits > set_type;
+
+ set_type s( kSize, 2 );
+ test( s );
+ }
+
} // namespace
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.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CDSUNIT_SET_TEST_INTRUSIVE_MICHAEL_LAZY_RCU_H
#define CDSUNIT_SET_TEST_INTRUSIVE_MICHAEL_LAZY_RCU_H
this->test( s );
}
+TYPED_TEST_P( IntrusiveMichaelLazySet, base_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::base_item_type base_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< rcu_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
+
+TYPED_TEST_P( IntrusiveMichaelLazySet, base_wrapped_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::base_item_type base_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::base_hook< ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template less<base_item_type> less;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< rcu_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
TYPED_TEST_P( IntrusiveMichaelLazySet, member_cmp )
{
this->test( s );
}
+TYPED_TEST_P( IntrusiveMichaelLazySet, member_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::member_item_type member_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::stat<> stat;
+ };
+ typedef ci::LazyList< rcu_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
+
+TYPED_TEST_P( IntrusiveMichaelLazySet, member_wrapped_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::member_item_type member_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::lazy_list::traits
+ {
+ typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::lazy_list::wrapped_stat<> stat;
+ };
+ typedef ci::LazyList< rcu_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
// GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as
// "No test named <test_name> can be found in this test case"
REGISTER_TYPED_TEST_CASE_P( IntrusiveMichaelLazySet,
- base_cmp, base_less, base_cmpmix, base_mutex, member_cmp, member_less, member_cmpmix, member_mutex
+ base_cmp, base_less, base_cmpmix, base_mutex, base_stat, base_wrapped_stat, member_cmp, member_less, member_cmpmix, member_mutex, member_stat, member_wrapped_stat
);
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.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CDSUNIT_SET_TEST_INTRUSIVE_MICHAEL_MICHAEL_RCU_H
#define CDSUNIT_SET_TEST_INTRUSIVE_MICHAEL_MICHAEL_RCU_H
this->test( s );
}
+TYPED_TEST_P( IntrusiveMichaelSet, base_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::base_item_type base_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template less<base_item_type> less;
+ typedef typename TestFixture::template cmp<base_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< rcu_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
+
+TYPED_TEST_P( IntrusiveMichaelSet, base_wrapped_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::base_item_type base_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::base_hook< ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template less<base_item_type> less;
+ typedef typename TestFixture::template cmp<base_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< rcu_type, base_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
TYPED_TEST_P( IntrusiveMichaelSet, member_cmp )
{
this->test( s );
}
+TYPED_TEST_P( IntrusiveMichaelSet, member_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::member_item_type member_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::stat<> stat;
+ };
+ typedef ci::MichaelList< rcu_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
+TYPED_TEST_P( IntrusiveMichaelSet, member_wrapped_stat )
+{
+ typedef typename TestFixture::rcu_type rcu_type;
+ typedef typename TestFixture::member_item_type member_item_type;
+ typedef typename TestFixture::mock_disposer mock_disposer;
+ typedef typename TestFixture::hash_int hash_int;
+
+ struct list_traits: public ci::michael_list::traits
+ {
+ typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
+ typedef typename TestFixture::template cmp<member_item_type> compare;
+ typedef mock_disposer disposer;
+ typedef ci::michael_list::wrapped_stat<> stat;
+ };
+ typedef ci::MichaelList< rcu_type, member_item_type, list_traits > bucket_type;
+
+ struct set_traits: public ci::michael_set::traits
+ {
+ typedef hash_int hash;
+ typedef typename TestFixture::simple_item_counter item_counter;
+ };
+ typedef ci::MichaelHashSet< rcu_type, bucket_type, set_traits > set_type;
+
+ set_type s( TestFixture::kSize, 2 );
+ this->test( s );
+}
// GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as
// "No test named <test_name> can be found in this test case"
REGISTER_TYPED_TEST_CASE_P( IntrusiveMichaelSet,
- base_cmp, base_less, base_cmpmix, member_cmp, member_less, member_cmpmix
+ base_cmp, base_less, base_cmpmix, base_stat, base_wrapped_stat, member_cmp, member_less, member_cmpmix, member_stat, member_wrapped_stat
);