profile/unordered_map

Go to the documentation of this file.
00001 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /** @file profile/unordered_map
00031  *  This file is a GNU profile extension to the Standard C++ Library.
00032  */
00033 
00034 #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
00035 #define _GLIBCXX_PROFILE_UNORDERED_MAP 1
00036 
00037 #include <profile/base.h>
00038 
00039 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00040 # include <unordered_map>
00041 #else
00042 # include <c++0x_warning.h>
00043 #endif
00044 
00045 #include <initializer_list>
00046 
00047 #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
00048 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00049 
00050 namespace std
00051 {
00052 namespace __profile
00053 {
00054   /// Class std::unordered_map wrapper with performance instrumentation.
00055   template<typename _Key, typename _Tp,
00056        typename _Hash  = std::hash<_Key>,
00057        typename _Pred = std::equal_to<_Key>,
00058        typename _Alloc =  std::allocator<_Key> >
00059     class unordered_map
00060     : public _GLIBCXX_STD_BASE
00061     {
00062       typedef typename _GLIBCXX_STD_BASE _Base;
00063 
00064     public:
00065       typedef typename _Base::size_type       size_type;
00066       typedef typename _Base::hasher          hasher;
00067       typedef typename _Base::key_equal       key_equal;
00068       typedef typename _Base::allocator_type  allocator_type;
00069       typedef typename _Base::key_type        key_type;
00070       typedef typename _Base::value_type      value_type;
00071       typedef typename _Base::difference_type difference_type;
00072       typedef typename _Base::reference       reference;
00073       typedef typename _Base::const_reference const_reference;
00074       typedef typename _Base::mapped_type      mapped_type;
00075 
00076       typedef typename _Base::iterator iterator;
00077       typedef typename _Base::const_iterator const_iterator;
00078 
00079       explicit
00080       unordered_map(size_type __n = 10,
00081             const hasher& __hf = hasher(),
00082             const key_equal& __eql = key_equal(),
00083             const allocator_type& __a = allocator_type())
00084       : _Base(__n, __hf, __eql, __a)
00085       {
00086         __profcxx_hashtable_construct(this, _Base::bucket_count());
00087         __profcxx_hashtable_construct2(this);
00088       }
00089 
00090       template<typename _InputIterator>
00091         unordered_map(_InputIterator __f, _InputIterator __l,
00092               size_type __n = 10,
00093               const hasher& __hf = hasher(),
00094               const key_equal& __eql = key_equal(),
00095               const allocator_type& __a = allocator_type())
00096       : _Base(__f, __l, __n, __hf, __eql, __a)
00097       {
00098         __profcxx_hashtable_construct(this, _Base::bucket_count());
00099         __profcxx_hashtable_construct2(this);
00100       }
00101 
00102       unordered_map(const _Base& __x)
00103       : _Base(__x) 
00104       { 
00105         __profcxx_hashtable_construct(this, _Base::bucket_count());
00106         __profcxx_hashtable_construct2(this);
00107       }
00108 
00109       unordered_map(unordered_map&& __x)
00110       : _Base(std::forward<_Base>(__x)) 
00111       {
00112         __profcxx_hashtable_construct(this, _Base::bucket_count());
00113         __profcxx_hashtable_construct2(this);
00114       }
00115 
00116       unordered_map(initializer_list<value_type> __l,
00117             size_type __n = 10,
00118             const hasher& __hf = hasher(),
00119             const key_equal& __eql = key_equal(),
00120             const allocator_type& __a = allocator_type())
00121       : _Base(__l, __n, __hf, __eql, __a) { }
00122 
00123       unordered_map&
00124       operator=(const unordered_map& __x)
00125       {
00126     *static_cast<_Base*>(this) = __x;
00127     return *this;
00128       }
00129 
00130       unordered_map&
00131       operator=(unordered_map&& __x)
00132       {
00133     // NB: DR 1204.
00134     // NB: DR 675.
00135     this->clear();
00136     this->swap(__x);
00137     return *this;
00138       }
00139 
00140       unordered_map&
00141       operator=(initializer_list<value_type> __l)
00142       {
00143     this->clear();
00144     this->insert(__l);
00145     return *this;
00146       }
00147 
00148       ~unordered_map()
00149       {
00150         __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00151                      _Base::size());
00152         _M_profile_destruct();
00153       }
00154 
00155       _Base&
00156       _M_base()       { return *this; }
00157 
00158       const _Base&
00159       _M_base() const { return *this; }
00160 
00161 
00162       void
00163       clear()
00164       {
00165         __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00166                      _Base::size());
00167         _M_profile_destruct();
00168         _Base::clear();
00169       }
00170 
00171       void
00172       insert(std::initializer_list<value_type> __l)
00173       { 
00174         size_type __old_size = _Base::bucket_count(); 
00175         _Base::insert(__l);
00176         _M_profile_resize(__old_size, _Base::bucket_count()); 
00177       }
00178 
00179       std::pair<iterator, bool>
00180       insert(const value_type& __obj)
00181       {
00182         size_type __old_size =  _Base::bucket_count();
00183         std::pair<iterator, bool> __res = _Base::insert(__obj);
00184         _M_profile_resize(__old_size, _Base::bucket_count()); 
00185         return __res;
00186       }
00187 
00188       iterator
00189       insert(iterator __iter, const value_type& __v)
00190       { 
00191         size_type __old_size = _Base::bucket_count(); 
00192         iterator res = _Base::insert(__iter, __v);
00193         _M_profile_resize(__old_size, _Base::bucket_count()); 
00194         return res;
00195       }
00196 
00197       const_iterator
00198       insert(const_iterator __iter, const value_type& __v)
00199       { 
00200         size_type __old_size = _Base::bucket_count(); 
00201         const_iterator res =_Base::insert(__iter, __v);
00202         _M_profile_resize(__old_size, _Base::bucket_count()); 
00203         return res;
00204       }
00205 
00206       template<typename _InputIter>
00207       void
00208       insert(_InputIter __first, _InputIter __last)
00209       {
00210         size_type __old_size = _Base::bucket_count(); 
00211         _Base::insert(__first.base(), __last.base());
00212         _M_profile_resize(__old_size, _Base::bucket_count()); 
00213       }
00214 
00215       void
00216       insert(const value_type* __first, const value_type* __last)
00217       {
00218         size_type __old_size = _Base::bucket_count(); 
00219         _Base::insert(__first, __last);
00220         _M_profile_resize(__old_size, _Base::bucket_count()); 
00221       }
00222      
00223       // operator []
00224       mapped_type&
00225       operator[](const _Key& _k)
00226       {
00227         size_type __old_size =  _Base::bucket_count();
00228         mapped_type& __res = _M_base()[_k];
00229         size_type __new_size =  _Base::bucket_count();
00230         _M_profile_resize(__old_size, _Base::bucket_count()); 
00231         return __res;
00232       }   
00233 
00234       void
00235       swap(unordered_map& __x)
00236       {
00237         _Base::swap(__x);
00238       }
00239       
00240       void rehash(size_type __n)
00241       {
00242         size_type __old_size =  _Base::bucket_count();
00243         _Base::rehash(__n);
00244         _M_profile_resize(__old_size, _Base::bucket_count()); 
00245       }
00246     private:
00247       void _M_profile_resize(size_type __old_size, size_type __new_size)
00248       {
00249         if (__old_size != __new_size)
00250         {
00251           __profcxx_hashtable_resize(this, __old_size, __new_size);
00252         }
00253       }
00254       void _M_profile_destruct()
00255       {
00256         size_type __hops = 0, __lc = 0, __chain = 0;
00257         for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
00258         {
00259           while (it._M_cur_node->_M_next) {
00260              __chain++;
00261              it++;
00262           }
00263           if (__chain) {
00264             __chain++;
00265             __lc = __lc > __chain ? __lc : __chain;  
00266             __hops += __chain * (__chain - 1) / 2;
00267             __chain = 0;
00268           }
00269         }
00270         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops); 
00271       }
00272    };
00273   template<typename _Key, typename _Tp, typename _Hash,
00274        typename _Pred, typename _Alloc>
00275     inline void
00276     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00277      unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00278     { __x.swap(__y); }
00279 
00280 
00281 #undef _GLIBCXX_BASE
00282 #undef _GLIBCXX_STD_BASE
00283 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
00284 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00285 
00286   /// Class std::unordered_multimap wrapper with performance instrumentation.
00287   template<typename _Key, typename _Tp,
00288        typename _Hash  = std::hash<_Key>,
00289        typename _Pred = std::equal_to<_Key>,
00290        typename _Alloc =  std::allocator<_Key> >
00291     class unordered_multimap
00292     : public _GLIBCXX_STD_BASE
00293     {      
00294       typedef typename _GLIBCXX_STD_BASE _Base;
00295 
00296     public:
00297       typedef typename _Base::size_type       size_type;
00298       typedef typename _Base::hasher          hasher;
00299       typedef typename _Base::key_equal       key_equal;
00300       typedef typename _Base::allocator_type  allocator_type;
00301       typedef typename _Base::key_type        key_type;
00302       typedef typename _Base::value_type      value_type;
00303       typedef typename _Base::difference_type difference_type;
00304       typedef typename _Base::reference       reference;
00305       typedef typename _Base::const_reference const_reference;
00306 
00307       typedef typename _Base::iterator iterator;
00308       typedef typename _Base::const_iterator const_iterator;
00309 
00310       explicit
00311       unordered_multimap(size_type __n = 10,
00312             const hasher& __hf = hasher(),
00313             const key_equal& __eql = key_equal(),
00314             const allocator_type& __a = allocator_type())
00315       : _Base(__n, __hf, __eql, __a)
00316       {
00317         __profcxx_hashtable_construct(this, _Base::bucket_count());
00318       }
00319       template<typename _InputIterator>
00320         unordered_multimap(_InputIterator __f, _InputIterator __l,
00321               size_type __n = 10,
00322               const hasher& __hf = hasher(),
00323               const key_equal& __eql = key_equal(),
00324               const allocator_type& __a = allocator_type())
00325       : _Base(__f, __l, __n, __hf, __eql, __a)
00326       {
00327         __profcxx_hashtable_construct(this, _Base::bucket_count());
00328       }
00329 
00330       unordered_multimap(const _Base& __x)
00331       : _Base(__x)
00332       {
00333         __profcxx_hashtable_construct(this, _Base::bucket_count());
00334       }
00335 
00336       unordered_multimap(unordered_multimap&& __x)
00337       : _Base(std::forward<_Base>(__x))
00338       {
00339         __profcxx_hashtable_construct(this, _Base::bucket_count());
00340       }
00341 
00342       unordered_multimap(initializer_list<value_type> __l,
00343              size_type __n = 10,
00344              const hasher& __hf = hasher(),
00345              const key_equal& __eql = key_equal(),
00346              const allocator_type& __a = allocator_type())
00347       : _Base(__l, __n, __hf, __eql, __a) { }
00348 
00349       unordered_multimap&
00350       operator=(const unordered_multimap& __x)
00351       {
00352     *static_cast<_Base*>(this) = __x;
00353     return *this;
00354       }
00355 
00356       unordered_multimap&
00357       operator=(unordered_multimap&& __x)
00358       {
00359     // NB: DR 1204.
00360     // NB: DR 675.
00361     this->clear();
00362     this->swap(__x);
00363     return *this;
00364       }
00365 
00366       unordered_multimap&
00367       operator=(initializer_list<value_type> __l)
00368       {
00369     this->clear();
00370     this->insert(__l);
00371     return *this;
00372       }
00373 
00374       ~unordered_multimap()
00375       {
00376         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00377                      _Base::size());
00378         _M_profile_destruct();
00379       }
00380 
00381       _Base&
00382       _M_base()       { return *this; }
00383 
00384       const _Base&
00385       _M_base() const { return *this; }
00386 
00387 
00388       void
00389       clear()
00390       {
00391         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00392                      _Base::size());
00393         _M_profile_destruct();
00394         _Base::clear();
00395       }
00396 
00397       void
00398       insert(std::initializer_list<value_type> __l)
00399       { 
00400         size_type __old_size =  _Base::bucket_count();
00401         _Base::insert(__l);
00402         _M_profile_resize(__old_size, _Base::bucket_count());
00403       }
00404 
00405       iterator
00406       insert(const value_type& __obj)
00407       {
00408         size_type __old_size =  _Base::bucket_count();
00409         iterator __res = _Base::insert(__obj);
00410         _M_profile_resize(__old_size, _Base::bucket_count()); 
00411         return __res;
00412       }
00413 
00414       iterator
00415       insert(iterator __iter, const value_type& __v)
00416       { 
00417         size_type __old_size = _Base::bucket_count(); 
00418         iterator res = _Base::insert(__iter, __v);
00419         _M_profile_resize(__old_size, _Base::bucket_count()); 
00420         return res;
00421       }
00422 
00423       const_iterator
00424       insert(const_iterator __iter, const value_type& __v)
00425       { 
00426         size_type __old_size = _Base::bucket_count(); 
00427         const_iterator res =_Base::insert(__iter, __v);
00428         _M_profile_resize(__old_size, _Base::bucket_count()); 
00429         return res;
00430       }
00431 
00432       template<typename _InputIter>
00433       void
00434       insert(_InputIter __first, _InputIter __last)
00435       {
00436         size_type __old_size = _Base::bucket_count(); 
00437         _Base::insert(__first.base(), __last.base());
00438         _M_profile_resize(__old_size, _Base::bucket_count()); 
00439       }
00440 
00441       void
00442       insert(const value_type* __first, const value_type* __last)
00443       {
00444         size_type __old_size = _Base::bucket_count(); 
00445         _Base::insert(__first, __last);
00446         _M_profile_resize(__old_size, _Base::bucket_count()); 
00447       }
00448 
00449       void
00450       swap(unordered_multimap& __x)
00451       {
00452         _Base::swap(__x);
00453       }
00454 
00455       void rehash(size_type __n)
00456       {
00457         size_type __old_size =  _Base::bucket_count();
00458         _Base::rehash(__n);
00459         _M_profile_resize(__old_size, _Base::bucket_count()); 
00460       }
00461     private:
00462       void _M_profile_resize(size_type __old_size, size_type __new_size)
00463       {
00464         if (__old_size != __new_size)
00465         {
00466           __profcxx_hashtable_resize(this, __old_size, __new_size);
00467         }
00468       }
00469 
00470       void _M_profile_destruct()
00471       {
00472         size_type __hops = 0, __lc = 0, __chain = 0;
00473         for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
00474         {
00475           while (it._M_cur_node->_M_next) {
00476              __chain++;
00477              it++;
00478           }
00479           if (__chain) {
00480             __chain++;
00481             __lc = __lc > __chain ? __lc : __chain;
00482             __hops += __chain * (__chain - 1) / 2;
00483             __chain = 0;
00484           }
00485         }
00486         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
00487       }
00488 
00489     };
00490   template<typename _Key, typename _Tp, typename _Hash,
00491        typename _Pred, typename _Alloc>
00492     inline void
00493     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00494      unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00495     { __x.swap(__y); }
00496 
00497 } // namespace __profile
00498 } // namespace std
00499 
00500 #undef _GLIBCXX_BASE
00501 #undef _GLIBCXX_STD_BASE
00502 
00503 #endif

Generated on 11 Jan 2010 for libstdc++ by  doxygen 1.6.1