X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=blobdiff_plain;f=cds%2Fcontainer%2Flazy_list_rcu.h;h=60c724e01fd537aa40fe7b126a684814f674f93e;hp=0c5ed541e9704bc9b835fad921b6e645d4ca646e;hb=1132246d5685f87a5b240e077b7e88d56e38b1ff;hpb=a4d098afe1cfb4cfb6359c4bb4e22d8d9d75f0b5 diff --git a/cds/container/lazy_list_rcu.h b/cds/container/lazy_list_rcu.h index 0c5ed541..60c724e0 100644 --- a/cds/container/lazy_list_rcu.h +++ b/cds/container/lazy_list_rcu.h @@ -1,11 +1,11 @@ /* This file is a part of libcds - Concurrent Data Structures library - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 Source code repo: http://github.com/khizmax/libcds/ Download: http://sourceforge.net/projects/libcds/files/ - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -147,6 +147,22 @@ namespace cds { namespace container { typedef typename gc::scoped_lock rcu_lock ; ///< RCU scoped lock static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal; ///< Group of \p extract_xxx functions require external locking + //@cond + // Rebind traits (split-list support) + template + struct rebind_traits { + typedef LazyList< + gc + , value_type + , typename cds::opt::make_options< traits, Options...>::type + > type; + }; + + // Stat selector + template + using select_stat_wrapper = typename base_class::template select_stat_wrapper< Stat >; + //@endcond + protected: //@cond typedef typename base_class::value_type node_type; @@ -155,41 +171,6 @@ namespace cds { namespace container { typedef typename maker::intrusive_traits::compare intrusive_key_comparator; typedef typename base_class::node_type head_type; - //@endcond - - public: - using exempt_ptr = cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer >; ///< pointer to extracted node - /// Type of \p get() member function return value - typedef value_type * raw_ptr; - - protected: - //@cond - static value_type& node_to_value( node_type& n ) - { - return n.m_Value; - } - - static value_type const& node_to_value( node_type const& n ) - { - return n.m_Value; - } - - template - static node_type * alloc_node( Q const& v ) - { - return cxx_allocator().New( v ); - } - - template - static node_type * alloc_node( Args&&... args ) - { - return cxx_allocator().MoveNew( std::forward(args)... ); - } - - static void free_node( node_type * pNode ) - { - cxx_allocator().Delete( pNode ); - } struct node_disposer { void operator()( node_type * pNode ) @@ -198,30 +179,15 @@ namespace cds { namespace container { } }; typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr; - - head_type& head() - { - return base_class::m_Head; - } - - head_type& head() const - { - return const_cast( base_class::m_Head ); - } - - head_type& tail() - { - return base_class::m_Tail; - } - - head_type const& tail() const - { - return base_class::m_Tail; - } //@endcond + public: + using exempt_ptr = cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer >; ///< pointer to extracted node + /// Type of \p get() member function return value + typedef value_type * raw_ptr; + protected: - //@cond + //@cond template class iterator_type: protected base_class::template iterator_type { @@ -301,7 +267,7 @@ namespace cds { namespace container { */ iterator begin() { - iterator it( head() ); + iterator it( head()); ++it ; // skip dummy head node return it; } @@ -315,13 +281,13 @@ namespace cds { namespace container { */ iterator end() { - return iterator( tail() ); + return iterator( tail()); } /// Returns a forward const iterator addressing the first element in a list const_iterator begin() const { - const_iterator it( head() ); + const_iterator it( head()); ++it ; // skip dummy head node return it; } @@ -329,7 +295,7 @@ namespace cds { namespace container { /// Returns a forward const iterator addressing the first element in a list const_iterator cbegin() const { - const_iterator it( head() ); + const_iterator it( head()); ++it ; // skip dummy head node return it; } @@ -337,13 +303,13 @@ namespace cds { namespace container { /// Returns an const iterator that addresses the location succeeding the last element in a list const_iterator end() const { - return const_iterator( tail() ); + return const_iterator( tail()); } /// Returns an const iterator that addresses the location succeeding the last element in a list const_iterator cend() const { - return const_iterator( tail() ); + return const_iterator( tail()); } //@} @@ -379,9 +345,9 @@ namespace cds { namespace container { Returns \p true if inserting successful, \p false otherwise. */ template - bool insert( Q const& val ) + bool insert( Q&& val ) { - return insert_at( head(), val ); + return insert_at( head(), std::forward( val )); } /// Inserts new node @@ -408,9 +374,9 @@ namespace cds { namespace container { The function makes RCU lock internally. */ template - bool insert( Q const& key, Func func ) + bool insert( Q&& key, Func func ) { - return insert_at( head(), key, func ); + return insert_at( head(), std::forward( key ), func ); } /// Inserts data of type \p value_type constructed from \p args @@ -612,7 +578,7 @@ namespace cds { namespace container { template bool contains( Q const& key ) const { - return find_at( head(), key, intrusive_key_comparator() ); + return find_at( head(), key, intrusive_key_comparator()); } //@cond template @@ -633,7 +599,7 @@ namespace cds { namespace container { bool contains( Q const& key, Less pred ) const { CDS_UNUSED( pred ); - return find_at( head(), key, typename maker::template less_wrapper::type() ); + return find_at( head(), key, typename maker::template less_wrapper::type()); } //@cond template @@ -803,9 +769,9 @@ namespace cds { namespace container { } template - bool insert_at( head_type& refHead, Q const& val ) + bool insert_at( head_type& refHead, Q&& val ) { - return insert_node_at( refHead, alloc_node( val )); + return insert_node_at( refHead, alloc_node( std::forward( val ))); } template @@ -815,11 +781,11 @@ namespace cds { namespace container { } template - bool insert_at( head_type& refHead, Q const& key, Func f ) + bool insert_at( head_type& refHead, Q&& key, Func f ) { - scoped_node_ptr pNode( alloc_node( key )); + scoped_node_ptr pNode( alloc_node( std::forward( key ))); - if ( base_class::insert_at( &refHead, *pNode, [&f](node_type& node){ f( node_to_value(node) ); } )) { + if ( base_class::insert_at( &refHead, *pNode, [&f](node_type& node){ f( node_to_value(node)); } )) { pNode.release(); return true; } @@ -829,7 +795,7 @@ namespace cds { namespace container { template bool erase_at( head_type& refHead, Q const& key, Compare cmp, Func f ) { - return base_class::erase_at( &refHead, key, cmp, [&f](node_type const& node){ f( node_to_value(node) ); } ); + return base_class::erase_at( &refHead, key, cmp, [&f](node_type const& node){ f( node_to_value(node)); } ); } template @@ -855,13 +821,13 @@ namespace cds { namespace container { template bool find_at( head_type& refHead, Q const& key, Compare cmp ) const { - return base_class::find_at( &refHead, key, cmp, [](node_type&, Q const &) {} ); + return base_class::find_at( &refHead, key, cmp, [](node_type&, Q const&) {} ); } template bool find_at( head_type& refHead, Q& val, Compare cmp, Func f ) const { - return base_class::find_at( &refHead, val, cmp, [&f](node_type& node, Q& val){ f( node_to_value(node), val ); }); + return base_class::find_at( &refHead, val, cmp, [&f](node_type& node, Q& v){ f( node_to_value(node), v ); }); } template @@ -871,6 +837,52 @@ namespace cds { namespace container { return pNode ? &pNode->m_Value : nullptr; } + static value_type& node_to_value( node_type& n ) + { + return n.m_Value; + } + + static value_type const& node_to_value( node_type const& n ) + { + return n.m_Value; + } + + template + static node_type * alloc_node( Q&& v ) + { + return cxx_allocator().New( std::forward( v )); + } + + template + static node_type * alloc_node( Args&&... args ) + { + return cxx_allocator().MoveNew( std::forward( args )... ); + } + + static void free_node( node_type * pNode ) + { + cxx_allocator().Delete( pNode ); + } + + head_type& head() + { + return base_class::m_Head; + } + + head_type& head() const + { + return const_cast(base_class::m_Head); + } + + head_type& tail() + { + return base_class::m_Tail; + } + + head_type const& tail() const + { + return base_class::m_Tail; + } //@endcond };