1 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 /** @file profile/unordered_map
31 * This file is a GNU profile extension to the Standard C++ Library.
34 #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
35 #define _GLIBCXX_PROFILE_UNORDERED_MAP 1
37 #ifndef __GXX_EXPERIMENTAL_CXX0X__
38 # include <bits/c++0x_warning.h>
40 # include <unordered_map>
42 #include <profile/base.h>
44 #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
45 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
51 /// Class std::unordered_map wrapper with performance instrumentation.
52 template<typename _Key, typename _Tp,
53 typename _Hash = std::hash<_Key>,
54 typename _Pred = std::equal_to<_Key>,
55 typename _Alloc = std::allocator<_Key> >
57 : public _GLIBCXX_STD_BASE
59 typedef typename _GLIBCXX_STD_BASE _Base;
62 typedef typename _Base::size_type size_type;
63 typedef typename _Base::hasher hasher;
64 typedef typename _Base::key_equal key_equal;
65 typedef typename _Base::allocator_type allocator_type;
66 typedef typename _Base::key_type key_type;
67 typedef typename _Base::value_type value_type;
68 typedef typename _Base::difference_type difference_type;
69 typedef typename _Base::reference reference;
70 typedef typename _Base::const_reference const_reference;
71 typedef typename _Base::mapped_type mapped_type;
73 typedef typename _Base::iterator iterator;
74 typedef typename _Base::const_iterator const_iterator;
77 unordered_map(size_type __n = 10,
78 const hasher& __hf = hasher(),
79 const key_equal& __eql = key_equal(),
80 const allocator_type& __a = allocator_type())
81 : _Base(__n, __hf, __eql, __a)
83 __profcxx_hashtable_construct(this, _Base::bucket_count());
84 __profcxx_hashtable_construct2(this);
87 template<typename _InputIterator>
88 unordered_map(_InputIterator __f, _InputIterator __l,
90 const hasher& __hf = hasher(),
91 const key_equal& __eql = key_equal(),
92 const allocator_type& __a = allocator_type())
93 : _Base(__f, __l, __n, __hf, __eql, __a)
95 __profcxx_hashtable_construct(this, _Base::bucket_count());
96 __profcxx_hashtable_construct2(this);
99 unordered_map(const _Base& __x)
102 __profcxx_hashtable_construct(this, _Base::bucket_count());
103 __profcxx_hashtable_construct2(this);
106 unordered_map(unordered_map&& __x)
107 : _Base(std::move(__x))
109 __profcxx_hashtable_construct(this, _Base::bucket_count());
110 __profcxx_hashtable_construct2(this);
113 unordered_map(initializer_list<value_type> __l,
115 const hasher& __hf = hasher(),
116 const key_equal& __eql = key_equal(),
117 const allocator_type& __a = allocator_type())
118 : _Base(__l, __n, __hf, __eql, __a) { }
121 operator=(const unordered_map& __x)
123 *static_cast<_Base*>(this) = __x;
128 operator=(unordered_map&& __x)
138 operator=(initializer_list<value_type> __l)
147 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
149 _M_profile_destruct();
153 _M_base() { return *this; }
156 _M_base() const { return *this; }
162 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
164 _M_profile_destruct();
169 insert(std::initializer_list<value_type> __l)
171 size_type __old_size = _Base::bucket_count();
173 _M_profile_resize(__old_size, _Base::bucket_count());
176 std::pair<iterator, bool>
177 insert(const value_type& __obj)
179 size_type __old_size = _Base::bucket_count();
180 std::pair<iterator, bool> __res = _Base::insert(__obj);
181 _M_profile_resize(__old_size, _Base::bucket_count());
186 insert(const_iterator __iter, const value_type& __v)
188 size_type __old_size = _Base::bucket_count();
189 iterator __res = _Base::insert(__iter, __v);
190 _M_profile_resize(__old_size, _Base::bucket_count());
194 template<typename _InputIter>
196 insert(_InputIter __first, _InputIter __last)
198 size_type __old_size = _Base::bucket_count();
199 _Base::insert(__first, __last);
200 _M_profile_resize(__old_size, _Base::bucket_count());
204 insert(const value_type* __first, const value_type* __last)
206 size_type __old_size = _Base::bucket_count();
207 _Base::insert(__first, __last);
208 _M_profile_resize(__old_size, _Base::bucket_count());
213 operator[](const _Key& _k)
215 size_type __old_size = _Base::bucket_count();
216 mapped_type& __res = _M_base()[_k];
217 size_type __new_size = _Base::bucket_count();
218 _M_profile_resize(__old_size, _Base::bucket_count());
223 swap(unordered_map& __x)
224 { _Base::swap(__x); }
226 void rehash(size_type __n)
228 size_type __old_size = _Base::bucket_count();
230 _M_profile_resize(__old_size, _Base::bucket_count());
235 _M_profile_resize(size_type __old_size, size_type __new_size)
237 if (__old_size != __new_size)
238 __profcxx_hashtable_resize(this, __old_size, __new_size);
242 _M_profile_destruct()
244 size_type __hops = 0, __lc = 0, __chain = 0;
245 for (iterator __it = _M_base().begin(); __it != _M_base().end();
248 while (__it._M_cur_node->_M_next)
256 __lc = __lc > __chain ? __lc : __chain;
257 __hops += __chain * (__chain - 1) / 2;
261 __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
265 template<typename _Key, typename _Tp, typename _Hash,
266 typename _Pred, typename _Alloc>
268 swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
269 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
272 template<typename _Key, typename _Tp, typename _Hash,
273 typename _Pred, typename _Alloc>
275 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
276 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
277 { return __x._M_equal(__y); }
279 template<typename _Key, typename _Tp, typename _Hash,
280 typename _Pred, typename _Alloc>
282 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
283 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
284 { return !(__x == __y); }
287 #undef _GLIBCXX_STD_BASE
288 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
289 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
291 /// Class std::unordered_multimap wrapper with performance instrumentation.
292 template<typename _Key, typename _Tp,
293 typename _Hash = std::hash<_Key>,
294 typename _Pred = std::equal_to<_Key>,
295 typename _Alloc = std::allocator<_Key> >
296 class unordered_multimap
297 : public _GLIBCXX_STD_BASE
299 typedef typename _GLIBCXX_STD_BASE _Base;
302 typedef typename _Base::size_type size_type;
303 typedef typename _Base::hasher hasher;
304 typedef typename _Base::key_equal key_equal;
305 typedef typename _Base::allocator_type allocator_type;
306 typedef typename _Base::key_type key_type;
307 typedef typename _Base::value_type value_type;
308 typedef typename _Base::difference_type difference_type;
309 typedef typename _Base::reference reference;
310 typedef typename _Base::const_reference const_reference;
312 typedef typename _Base::iterator iterator;
313 typedef typename _Base::const_iterator const_iterator;
316 unordered_multimap(size_type __n = 10,
317 const hasher& __hf = hasher(),
318 const key_equal& __eql = key_equal(),
319 const allocator_type& __a = allocator_type())
320 : _Base(__n, __hf, __eql, __a)
322 __profcxx_hashtable_construct(this, _Base::bucket_count());
324 template<typename _InputIterator>
325 unordered_multimap(_InputIterator __f, _InputIterator __l,
327 const hasher& __hf = hasher(),
328 const key_equal& __eql = key_equal(),
329 const allocator_type& __a = allocator_type())
330 : _Base(__f, __l, __n, __hf, __eql, __a)
332 __profcxx_hashtable_construct(this, _Base::bucket_count());
335 unordered_multimap(const _Base& __x)
338 __profcxx_hashtable_construct(this, _Base::bucket_count());
341 unordered_multimap(unordered_multimap&& __x)
342 : _Base(std::move(__x))
344 __profcxx_hashtable_construct(this, _Base::bucket_count());
347 unordered_multimap(initializer_list<value_type> __l,
349 const hasher& __hf = hasher(),
350 const key_equal& __eql = key_equal(),
351 const allocator_type& __a = allocator_type())
352 : _Base(__l, __n, __hf, __eql, __a) { }
355 operator=(const unordered_multimap& __x)
357 *static_cast<_Base*>(this) = __x;
362 operator=(unordered_multimap&& __x)
372 operator=(initializer_list<value_type> __l)
379 ~unordered_multimap()
381 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
383 _M_profile_destruct();
387 _M_base() { return *this; }
390 _M_base() const { return *this; }
396 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
398 _M_profile_destruct();
403 insert(std::initializer_list<value_type> __l)
405 size_type __old_size = _Base::bucket_count();
407 _M_profile_resize(__old_size, _Base::bucket_count());
411 insert(const value_type& __obj)
413 size_type __old_size = _Base::bucket_count();
414 iterator __res = _Base::insert(__obj);
415 _M_profile_resize(__old_size, _Base::bucket_count());
420 insert(const_iterator __iter, const value_type& __v)
422 size_type __old_size = _Base::bucket_count();
423 iterator __res =_Base::insert(__iter, __v);
424 _M_profile_resize(__old_size, _Base::bucket_count());
428 template<typename _InputIter>
430 insert(_InputIter __first, _InputIter __last)
432 size_type __old_size = _Base::bucket_count();
433 _Base::insert(__first, __last);
434 _M_profile_resize(__old_size, _Base::bucket_count());
438 insert(const value_type* __first, const value_type* __last)
440 size_type __old_size = _Base::bucket_count();
441 _Base::insert(__first, __last);
442 _M_profile_resize(__old_size, _Base::bucket_count());
446 swap(unordered_multimap& __x)
447 { _Base::swap(__x); }
449 void rehash(size_type __n)
451 size_type __old_size = _Base::bucket_count();
453 _M_profile_resize(__old_size, _Base::bucket_count());
458 _M_profile_resize(size_type __old_size, size_type __new_size)
460 if (__old_size != __new_size)
461 __profcxx_hashtable_resize(this, __old_size, __new_size);
465 _M_profile_destruct()
467 size_type __hops = 0, __lc = 0, __chain = 0;
468 for (iterator __it = _M_base().begin(); __it != _M_base().end();
471 while (__it._M_cur_node->_M_next)
479 __lc = __lc > __chain ? __lc : __chain;
480 __hops += __chain * (__chain - 1) / 2;
484 __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
489 template<typename _Key, typename _Tp, typename _Hash,
490 typename _Pred, typename _Alloc>
492 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
493 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
496 template<typename _Key, typename _Tp, typename _Hash,
497 typename _Pred, typename _Alloc>
499 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
500 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
501 { return __x._M_equal(__y); }
503 template<typename _Key, typename _Tp, typename _Hash,
504 typename _Pred, typename _Alloc>
506 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
507 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
508 { return !(__x == __y); }
510 } // namespace __profile
514 #undef _GLIBCXX_STD_BASE
516 #endif // __GXX_EXPERIMENTAL_CXX0X__