2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H
32 #define CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H
34 #include <cds/container/split_list_set_nogc.h>
35 #include <cds/details/binary_functor_wrapper.h>
37 namespace cds { namespace container {
39 /// Split-ordered list map (template specialization for gc::nogc)
40 /** @ingroup cds_nonintrusive_map
41 \anchor cds_nonintrusive_SplitListMap_nogc
43 This specialization is so-called append-only.
44 The map does not support the removal of list item.
46 See \ref cds_nonintrusive_SplitListMap_hp "SplitListMap" for description of template parameters.
48 @warning Many member functions return an iterator pointing to an item.
49 The iterator can be used to set up field of the item,
50 but you should provide an exclusive access to it,
51 see \ref cds_intrusive_item_creating "insert item troubleshooting".
56 #ifdef CDS_DOXYGEN_INVOKED
57 class Traits = split_list::traits
62 class SplitListMap<cds::gc::nogc, Key, Value, Traits>:
63 protected container::SplitListSet<
65 std::pair<Key const, Value>,
66 split_list::details::wrap_map_traits<Key, Value, Traits>
70 typedef container::SplitListSet<
72 std::pair<Key const, Value>,
73 split_list::details::wrap_map_traits<Key, Value, Traits>
77 typedef cds::gc::nogc gc; ///< Garbage collector
78 typedef Key key_type; ///< key type
79 typedef Value mapped_type; ///< type of value stored in the map
81 typedef std::pair<key_type const, mapped_type> value_type ; ///< Pair type
82 typedef typename base_class::ordered_list ordered_list; ///< Underlying ordered list class
83 typedef typename base_class::key_comparator key_comparator; ///< key comparison functor
85 typedef typename base_class::hash hash; ///< Hash functor for \ref key_type
86 typedef typename base_class::item_counter item_counter; ///< Item counter type
87 typedef typename base_class::stat stat; ///< Internal statistics
91 typedef typename base_class::traits::key_accessor key_accessor;
95 ///@name Forward iterators
99 The forward iterator for split-list is based on \p OrderedList forward iterator and has some features:
100 - it has no post-increment operator
101 - it iterates items in unordered fashion
103 The iterator interface:
107 // Default constructor
111 iterator( iterator const& src );
113 // Dereference operator
114 value_type * operator ->() const;
116 // Dereference operator
117 value_type& operator *() const;
119 // Preincrement operator
120 iterator& operator ++();
122 // Assignment operator
123 iterator& operator = (iterator const& src);
125 // Equality operators
126 bool operator ==(iterator const& i ) const;
127 bool operator !=(iterator const& i ) const;
131 typedef typename base_class::iterator iterator;
133 /// Const forward iterator
134 typedef typename base_class::const_iterator const_iterator;
136 /// Returns a forward iterator addressing the first element in a map
138 For empty set \code begin() == end() \endcode
142 return base_class::begin();
145 /// Returns an iterator that addresses the location succeeding the last element in a map
147 Do not use the value returned by <tt>end</tt> function to access any item.
148 The returned value can be used only to control reaching the end of the set.
149 For empty set \code begin() == end() \endcode
153 return base_class::end();
156 /// Returns a forward const iterator addressing the first element in a map
157 const_iterator begin() const
159 return base_class::begin();
162 /// Returns a forward const iterator addressing the first element in a map
163 const_iterator cbegin() const
165 return base_class::cbegin();
168 /// Returns an const iterator that addresses the location succeeding the last element in a map
169 const_iterator end() const
171 return base_class::end();
174 /// Returns an const iterator that addresses the location succeeding the last element in a map
175 const_iterator cend() const
177 return base_class::cend();
182 /// Initialize split-ordered map of default capacity
184 The default capacity is defined in bucket table constructor.
185 See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_ducket_table
186 which selects by \p intrusive::split_list::traits::dynamic_bucket_table.
192 /// Initialize split-ordered map
194 size_t nItemCount ///< estimated average item count
195 , size_t nLoadFactor = 1 ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
197 : base_class( nItemCount, nLoadFactor )
201 /// Inserts new node with key and default value
203 The function creates a node with \p key and default value, and then inserts the node created into the map.
206 - The \p key_type should be constructible from value of type \p K.
207 In trivial case, \p K is equal to \ref key_type.
208 - The \p mapped_type should be default-constructible.
210 Returns an iterator pointed to inserted value, or \p end() if inserting is failed
212 template <typename K>
213 iterator insert( K const& key )
215 //TODO: pass arguments by reference (make_pair makes copy)
216 return base_class::emplace( key_type( key ), mapped_type() );
221 The function creates a node with copy of \p val value
222 and then inserts the node created into the map.
225 - The \p key_type should be constructible from \p key of type \p K.
226 - The \p mapped_type should be constructible from \p val of type \p V.
228 Returns an iterator pointed to inserted value, or \p end() if inserting is failed
230 template <typename K, typename V>
231 iterator insert( K const& key, V const& val )
233 return base_class::emplace( key_type( key ), mapped_type( val ));
236 /// Inserts new node and initialize it by a functor
238 This function inserts new node with key \p key and if inserting is successful then it calls
239 \p func functor with signature
242 void operator()( value_type& item );
246 The argument \p item of user-defined functor \p func is the reference
247 to the map's item inserted. \p item.second is a reference to item's value that may be changed.
248 User-defined functor \p func should guarantee that during changing item's value no any other changes
249 could be made on this map's item by concurrent threads.
250 The user-defined functor is called only if the inserting is successful.
252 The \p key_type should be constructible from value of type \p K.
254 The function allows to split creating of new item into two part:
255 - create item from \p key;
256 - insert new item into the map;
257 - if inserting is successful, initialize the value of item by calling \p f functor
259 This can be useful if complete initialization of object of \p mapped_type is heavyweight and
260 it is preferable that the initialization should be completed only if inserting is successful.
262 Returns an iterator pointed to inserted value, or \p end() if inserting is failed
264 template <typename K, typename Func>
265 iterator insert_with( const K& key, Func func )
267 iterator it = insert( key );
273 /// For key \p key inserts data of type \p mapped_type created in-place from \p args
275 \p key_type should be constructible from type \p K
277 Returns \p true if inserting successful, \p false otherwise.
279 template <typename K, typename... Args>
280 iterator emplace( K&& key, Args&&... args )
282 return base_class::emplace( key_type( std::forward<K>( key )), mapped_type( std::forward<Args>( args )...));
287 If \p key is not in the map and \p bAllowInsert is \p true, the function inserts a new item.
288 Otherwise, the function returns an iterator pointing to the item found.
290 Returns <tt> std::pair<iterator, bool> </tt> where \p first is an iterator pointing to
291 item found or inserted (if inserting is not allowed and \p key is not found, the iterator will be \p end()),
293 \p second is true if new item has been added or \p false if the item
294 already is in the map.
296 template <typename K>
297 std::pair<iterator, bool> update( K const& key, bool bAllowInsert = true )
299 //TODO: pass arguments by reference (make_pair makes copy)
300 return base_class::update( std::make_pair( key_type( key ), mapped_type() ), bAllowInsert );
303 template <typename K>
304 CDS_DEPRECATED("ensure() is deprecated, use update()")
305 std::pair<iterator, bool> ensure( K const& key )
307 return update( key, true );
311 /// Checks whether the map contains \p key
313 The function searches the item with key equal to \p key
314 and returns an iterator pointed to item found and \ref end() otherwise
316 template <typename K>
317 iterator contains( K const& key )
319 return base_class::contains( key );
322 template <typename K>
323 CDS_DEPRECATED("deprecated, use contains()")
324 iterator find( K const& key )
326 return contains( key );
330 /// Checks whether the map contains \p key using \p pred predicate for searching
332 The function is an analog of <tt>contains( key )</tt> but \p pred is used for key comparing.
333 \p Less functor has the interface like \p std::less.
334 \p pred must imply the same element order as the comparator used for building the map.
336 template <typename K, typename Less>
337 iterator contains( K const& key, Less pred )
340 return base_class::contains( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>() );
343 template <typename K, typename Less>
344 CDS_DEPRECATED("deprecated, use contains()")
345 iterator find_with( K const& key, Less pred )
347 return contains( key, pred );
352 /// Clears the set (not atomic, for debugging purposes only)
358 /// Checks if the map is empty
360 Emptiness is checked by item counting: if item count is zero then the map is empty.
361 Thus, the correct item counting feature is an important part of Michael's map implementation.
365 return base_class::empty();
368 /// Returns item count in the map
371 return base_class::size();
374 /// Returns internal statistics
375 stat const& statistics() const
377 return base_class::statistics();
380 }} // namespace cds::container
383 #endif // #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H