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:
Usually, ordered single-linked list is used as a building block for the hash table implementation.
Iterable list is suitable for almost append-only hash table because the list doesn't delete
its internal node when erasing a key but it is marked them as empty to be reused in the future.
- However, plenty of empty nodes degrades performance.
-
+ However, plenty of empty nodes degrades performance.
+
The complexity of searching is <tt>O(N)</tt>.
Template arguments:
typedef typename maker::mapped_type mapped_type;
typedef typename maker::value_type value_type;
#endif
-
+ typedef Traits traits; ///< List traits
typedef typename base_class::gc gc; ///< Garbage collector used
typedef typename base_class::back_off back_off; ///< Back-off strategy used
typedef typename maker::data_allocator_type allocator_type; ///< Allocator type used for allocate/deallocate data
/// Guarded pointer
typedef typename base_class::guarded_ptr guarded_ptr;
+ //@cond
+ // Rebind traits (split-list support)
+ template <typename... Options>
+ struct rebind_traits {
+ typedef IterableKVList<
+ gc
+ , key_type, mapped_type
+ , typename cds::opt::make_options< traits, Options...>::type
+ > type;
+ };
+
+ // Stat selector
+ template <typename Stat>
+ using select_stat_wrapper = typename base_class::template select_stat_wrapper< Stat >;
+ //@endcond
+
protected:
//@cond
typedef typename base_class::head_type head_type;
this code
\code
if ( it1 == it2 )
- assert( &(*it1) == &(*it2) );
+ assert( &(*it1) == &(*it2));
\endcode
can throw assertion. The point is that the iterator stores the value of element which can be modified later by other thread.
The guard inside the iterator prevents recycling that value so the iterator's value remains valid even after such changing.
The functor may change non-key fields of \p val; however, \p func must guarantee
that during changing no any other modifications could be made on this item by concurrent threads.
- Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successful,
+ @return <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successful,
\p second is true if new item has been added or \p false if the item with such \p key
already exists.
If the item \p key is not found in the list, then \p key is inserted
iff \p bInsert is \p true.
- Otherwise, the current element is changed to <tt> value_type( key, val )</tt>,
+ Otherwise, the current element is changed to <tt> value_type( key, val )</tt>,
the old element will be retired later.
Returns std::pair<bool, bool> where \p first is \p true if operation is successful,
bool erase_with( K const& key, Less pred )
{
CDS_UNUSED( pred );
- return base_class::erase_with( key, less_wrapper<Less>() );
+ return base_class::erase_with( key, less_wrapper<Less>());
}
/// Deletes \p key from the list
guarded_ptr extract_with( K const& key, Less pred )
{
CDS_UNUSED( pred );
- return base_class::extract_with( key, less_wrapper<Less>() );
+ return base_class::extract_with( key, less_wrapper<Less>());
}
/// Checks whether the list contains \p key
bool contains( Q const& key, Less pred ) const
{
CDS_UNUSED( pred );
- return base_class::contains( key, less_wrapper<Less>() );
+ return base_class::contains( key, less_wrapper<Less>());
}
/// Finds the key \p key and performs an action with it
guarded_ptr get_with( K const& key, Less pred ) const
{
CDS_UNUSED( pred );
- return base_class::get_with( key, less_wrapper<Less>() );
+ return base_class::get_with( key, less_wrapper<Less>());
}
/// Checks if the list is empty
// Split-list support
template <typename K>
- bool insert_at( head_type& refHead, K const& key )
+ bool insert_at( head_type& refHead, K&& key )
{
- return base_class::insert_at( refHead, value_type( key_type( key ), mapped_type() ));
+ return base_class::insert_at( refHead, value_type( key_type( std::forward<K>( key )), mapped_type()));
}
template <typename K, typename V>
- bool insert_at( head_type& refHead, const K& key, V const& val )
+ bool insert_at( head_type& refHead, K&& key, V&& val )
{
- return base_class::insert_at( refHead, value_type( key_type( key ), val ));
+ return base_class::insert_at( refHead, value_type( key_type( std::forward<K>( key )), std::forward<V>( val )));
}
template <typename K, typename Func>
- bool insert_with_at( head_type& refHead, K const& key, Func f )
+ bool insert_with_at( head_type& refHead, K&& key, Func f )
{
- return base_class::insert_at( refHead, value_type( key_type( key ), mapped_type()), f );
+ return base_class::insert_at( refHead, value_type( key_type( std::forward<K>( key )), mapped_type()), f );
}
template <typename K, typename... Args>
}
template <typename K, typename Func>
- std::pair<bool, bool> update_at( head_type& refHead, const K& key, Func f, bool bAllowInsert )
+ std::pair<bool, bool> update_at( head_type& refHead, K&& key, Func f, bool bAllowInsert )
{
- return base_class::update_at( refHead, value_type( key_type( key ), mapped_type()), f, bAllowInsert );
+ return base_class::update_at( refHead, value_type( key_type( std::forward<K>( key )), mapped_type()), f, bAllowInsert );
}
template <typename K, typename Compare>