Added copyright and license
[libcds.git] / cds / container / split_list_map_nogc.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
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.
18
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.     
29 */
30
31 #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H
32 #define CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H
33
34 #include <cds/container/split_list_set_nogc.h>
35 #include <cds/details/binary_functor_wrapper.h>
36
37 namespace cds { namespace container {
38
39     /// Split-ordered list map (template specialization for gc::nogc)
40     /** @ingroup cds_nonintrusive_map
41         \anchor cds_nonintrusive_SplitListMap_nogc
42
43         This specialization is so-called append-only.
44         The map does not support the removal of list item.
45
46         See \ref cds_nonintrusive_SplitListMap_hp "SplitListMap" for description of template parameters.
47
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".
52     */
53     template <
54         typename Key,
55         typename Value,
56 #ifdef CDS_DOXYGEN_INVOKED
57         class Traits = split_list::traits
58 #else
59         class Traits
60 #endif
61     >
62     class SplitListMap<cds::gc::nogc, Key, Value, Traits>:
63         protected container::SplitListSet<
64             cds::gc::nogc,
65             std::pair<Key const, Value>,
66             split_list::details::wrap_map_traits<Key, Value, Traits>
67         >
68     {
69         //@cond
70         typedef container::SplitListSet<
71             cds::gc::nogc,
72             std::pair<Key const, Value>,
73             split_list::details::wrap_map_traits<Key, Value, Traits>
74         > base_class;
75         //@endcond
76     public:
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
80
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
84
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
88
89     protected:
90         //@cond
91         typedef typename base_class::traits::key_accessor key_accessor;
92         //@endcond
93
94     public:
95         /// Forward iterator (see \p SplitListSet::iterator)
96         /**
97             Remember, the iterator <tt>operator -> </tt> and <tt>operator *</tt> returns \ref value_type pointer and reference.
98             To access item key and value use <tt>it->first</tt> and <tt>it->second</tt> respectively.
99         */
100         typedef typename base_class::iterator iterator;
101
102         /// Const forward iterator (see SplitListSet::const_iterator)
103         typedef typename base_class::const_iterator const_iterator;
104
105         /// Returns a forward iterator addressing the first element in a map
106         /**
107             For empty set \code begin() == end() \endcode
108         */
109         iterator begin()
110         {
111             return base_class::begin();
112         }
113
114         /// Returns an iterator that addresses the location succeeding the last element in a map
115         /**
116             Do not use the value returned by <tt>end</tt> function to access any item.
117             The returned value can be used only to control reaching the end of the set.
118             For empty set \code begin() == end() \endcode
119         */
120         iterator end()
121         {
122             return base_class::end();
123         }
124
125         /// Returns a forward const iterator addressing the first element in a map
126         //@{
127         const_iterator begin() const
128         {
129             return base_class::begin();
130         }
131         const_iterator cbegin() const
132         {
133             return base_class::cbegin();
134         }
135         //@}
136
137         /// Returns an const iterator that addresses the location succeeding the last element in a map
138         //@{
139         const_iterator end() const
140         {
141             return base_class::end();
142         }
143         const_iterator cend() const
144         {
145             return base_class::cend();
146         }
147         //@}
148
149     public:
150         /// Initialize split-ordered map of default capacity
151         /**
152             The default capacity is defined in bucket table constructor.
153             See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_ducket_table
154             which selects by \p intrusive::split_list::traits::dynamic_bucket_table.
155         */
156         SplitListMap()
157             : base_class()
158         {}
159
160         /// Initialize split-ordered map
161         SplitListMap(
162             size_t nItemCount           ///< estimated average item count
163             , size_t nLoadFactor = 1    ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
164             )
165             : base_class( nItemCount, nLoadFactor )
166         {}
167
168     public:
169         /// Inserts new node with key and default value
170         /**
171             The function creates a node with \p key and default value, and then inserts the node created into the map.
172
173             Preconditions:
174             - The \p key_type should be constructible from value of type \p K.
175                 In trivial case, \p K is equal to \ref key_type.
176             - The \p mapped_type should be default-constructible.
177
178             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
179         */
180         template <typename K>
181         iterator insert( K const& key )
182         {
183             //TODO: pass arguments by reference (make_pair makes copy)
184             return base_class::insert( std::make_pair( key, mapped_type() ) );
185         }
186
187         /// Inserts new node
188         /**
189             The function creates a node with copy of \p val value
190             and then inserts the node created into the map.
191
192             Preconditions:
193             - The \p key_type should be constructible from \p key of type \p K.
194             - The \p mapped_type should be constructible from \p val of type \p V.
195
196             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
197         */
198         template <typename K, typename V>
199         iterator insert( K const& key, V const& val )
200         {
201             //TODO: pass arguments by reference (make_pair makes copy)
202             return base_class::insert( std::make_pair( key, val ) );
203         }
204
205         /// Inserts new node and initialize it by a functor
206         /**
207             This function inserts new node with key \p key and if inserting is successful then it calls
208             \p func functor with signature
209             \code
210             struct functor {
211                 void operator()( value_type& item );
212             };
213             \endcode
214
215             The argument \p item of user-defined functor \p func is the reference
216             to the map's item inserted. \p item.second is a reference to item's value that may be changed.
217             User-defined functor \p func should guarantee that during changing item's value no any other changes
218             could be made on this map's item by concurrent threads.
219             The user-defined functor is called only if the inserting is successful.
220
221             The \p key_type should be constructible from value of type \p K.
222
223             The function allows to split creating of new item into two part:
224             - create item from \p key;
225             - insert new item into the map;
226             - if inserting is successful, initialize the value of item by calling \p f functor
227
228             This can be useful if complete initialization of object of \p mapped_type is heavyweight and
229             it is preferable that the initialization should be completed only if inserting is successful.
230
231             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
232         */
233         template <typename K, typename Func>
234         iterator insert_with( const K& key, Func func )
235         {
236             iterator it = insert( key );
237             if ( it != end() )
238                 func( (*it) );
239             return it;
240         }
241
242         /// For key \p key inserts data of type \p mapped_type created in-place from \p args
243         /**
244             \p key_type should be constructible from type \p K
245
246             Returns \p true if inserting successful, \p false otherwise.
247         */
248         template <typename K, typename... Args>
249         iterator emplace( K&& key, Args&&... args )
250         {
251             return base_class::emplace( std::forward<K>(key), std::move(mapped_type(std::forward<Args>(args)...)));
252         }
253
254         /// Updates the item
255         /**
256             If \p key is not in the map and \p bAllowInsert is \p true, the function inserts a new item.
257             Otherwise, the function returns an iterator pointing to the item found.
258
259             Returns <tt> std::pair<iterator, bool> </tt> where \p first is an iterator pointing to
260             item found or inserted (if inserting is not allowed and \p key is not found, the iterator will be \p end()),
261
262             \p second is true if new item has been added or \p false if the item
263             already is in the map.
264         */
265         template <typename K>
266         std::pair<iterator, bool> update( K const& key, bool bAllowInsert = true )
267         {
268             //TODO: pass arguments by reference (make_pair makes copy)
269             return base_class::update( std::make_pair( key, mapped_type() ), bAllowInsert );
270         }
271         //@cond
272         template <typename K>
273         CDS_DEPRECATED("ensure() is deprecated, use update()")
274         std::pair<iterator, bool> ensure( K const& key )
275         {
276             return update( key, true );
277         }
278         //@endcond
279
280         /// Checks whether the map contains \p key
281         /**
282             The function searches the item with key equal to \p key
283             and returns an iterator pointed to item found and \ref end() otherwise
284         */
285         template <typename K>
286         iterator contains( K const& key )
287         {
288             return base_class::contains( key );
289         }
290         //@cond
291         template <typename K>
292         CDS_DEPRECATED("deprecated, use contains()")
293         iterator find( K const& key )
294         {
295             return contains( key );
296         }
297         //@endcond
298
299         /// Checks whether the map contains \p key using \p pred predicate for searching
300         /**
301             The function is an analog of <tt>contains( key )</tt> but \p pred is used for key comparing.
302             \p Less functor has the interface like \p std::less.
303             \p pred must imply the same element order as the comparator used for building the map.
304         */
305         template <typename K, typename Less>
306         iterator contains( K const& key, Less pred )
307         {
308             CDS_UNUSED( pred );
309             return base_class::contains( key, cds::details::predicate_wrapper<value_type, Less, key_accessor>() );
310         }
311         //@cond
312         template <typename K, typename Less>
313         CDS_DEPRECATED("deprecated, use contains()")
314         iterator find_with( K const& key, Less pred )
315         {
316             return contains( key, pred );
317         }
318         //@endcond
319
320         /// Checks if the map is empty
321         /**
322             Emptiness is checked by item counting: if item count is zero then the map is empty.
323             Thus, the correct item counting feature is an important part of Michael's map implementation.
324         */
325         bool empty() const
326         {
327             return base_class::empty();
328         }
329
330         /// Returns item count in the map
331         size_t size() const
332         {
333             return base_class::size();
334         }
335
336         /// Returns internal statistics
337         stat const& statistics() const
338         {
339             return base_class::statistics();
340         }
341     };
342 }}  // namespace cds::container
343
344
345 #endif // #ifndef CDSLIB_CONTAINER_SPLIT_LIST_MAP_NOGC_H