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 <bits/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(const_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       template<typename _InputIter>
00198         void
00199         insert(_InputIter __first, _InputIter __last)
00200         {
00201       size_type __old_size = _Base::bucket_count(); 
00202       _Base::insert(__first.base(), __last.base());
00203       _M_profile_resize(__old_size, _Base::bucket_count()); 
00204     }
00205 
00206       void
00207       insert(const value_type* __first, const value_type* __last)
00208       {
00209         size_type __old_size = _Base::bucket_count(); 
00210         _Base::insert(__first, __last);
00211         _M_profile_resize(__old_size, _Base::bucket_count()); 
00212       }
00213      
00214       // operator []
00215       mapped_type&
00216       operator[](const _Key& _k)
00217       {
00218         size_type __old_size =  _Base::bucket_count();
00219         mapped_type& __res = _M_base()[_k];
00220         size_type __new_size =  _Base::bucket_count();
00221         _M_profile_resize(__old_size, _Base::bucket_count()); 
00222         return __res;
00223       }   
00224 
00225       void
00226       swap(unordered_map& __x)
00227       { _Base::swap(__x); }
00228 
00229       void rehash(size_type __n)
00230       {
00231         size_type __old_size =  _Base::bucket_count();
00232         _Base::rehash(__n);
00233         _M_profile_resize(__old_size, _Base::bucket_count()); 
00234       }
00235 
00236     private:
00237       void
00238       _M_profile_resize(size_type __old_size, size_type __new_size)
00239       {
00240         if (__old_size != __new_size)
00241       __profcxx_hashtable_resize(this, __old_size, __new_size);
00242       }
00243 
00244       void
00245       _M_profile_destruct()
00246       {
00247         size_type __hops = 0, __lc = 0, __chain = 0;
00248         for (iterator __it = _M_base().begin(); __it != _M_base().end();
00249          ++__it)
00250       {
00251         while (__it._M_cur_node->_M_next)
00252           {
00253         ++__chain;
00254         ++__it;
00255           }
00256         if (__chain)
00257           {
00258         ++__chain;
00259         __lc = __lc > __chain ? __lc : __chain;  
00260         __hops += __chain * (__chain - 1) / 2;
00261         __chain = 0;
00262           }
00263       }
00264         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops); 
00265       }
00266    };
00267 
00268   template<typename _Key, typename _Tp, typename _Hash,
00269        typename _Pred, typename _Alloc>
00270     inline void
00271     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00272      unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00273     { __x.swap(__y); }
00274 
00275 #undef _GLIBCXX_BASE
00276 #undef _GLIBCXX_STD_BASE
00277 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
00278 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00279 
00280   /// Class std::unordered_multimap wrapper with performance instrumentation.
00281   template<typename _Key, typename _Tp,
00282        typename _Hash  = std::hash<_Key>,
00283        typename _Pred = std::equal_to<_Key>,
00284        typename _Alloc =  std::allocator<_Key> >
00285     class unordered_multimap
00286     : public _GLIBCXX_STD_BASE
00287     {      
00288       typedef typename _GLIBCXX_STD_BASE _Base;
00289 
00290     public:
00291       typedef typename _Base::size_type       size_type;
00292       typedef typename _Base::hasher          hasher;
00293       typedef typename _Base::key_equal       key_equal;
00294       typedef typename _Base::allocator_type  allocator_type;
00295       typedef typename _Base::key_type        key_type;
00296       typedef typename _Base::value_type      value_type;
00297       typedef typename _Base::difference_type difference_type;
00298       typedef typename _Base::reference       reference;
00299       typedef typename _Base::const_reference const_reference;
00300 
00301       typedef typename _Base::iterator iterator;
00302       typedef typename _Base::const_iterator const_iterator;
00303 
00304       explicit
00305       unordered_multimap(size_type __n = 10,
00306             const hasher& __hf = hasher(),
00307             const key_equal& __eql = key_equal(),
00308             const allocator_type& __a = allocator_type())
00309       : _Base(__n, __hf, __eql, __a)
00310       {
00311         __profcxx_hashtable_construct(this, _Base::bucket_count());
00312       }
00313       template<typename _InputIterator>
00314         unordered_multimap(_InputIterator __f, _InputIterator __l,
00315               size_type __n = 10,
00316               const hasher& __hf = hasher(),
00317               const key_equal& __eql = key_equal(),
00318               const allocator_type& __a = allocator_type())
00319       : _Base(__f, __l, __n, __hf, __eql, __a)
00320       {
00321         __profcxx_hashtable_construct(this, _Base::bucket_count());
00322       }
00323 
00324       unordered_multimap(const _Base& __x)
00325       : _Base(__x)
00326       {
00327         __profcxx_hashtable_construct(this, _Base::bucket_count());
00328       }
00329 
00330       unordered_multimap(unordered_multimap&& __x)
00331       : _Base(std::forward<_Base>(__x))
00332       {
00333         __profcxx_hashtable_construct(this, _Base::bucket_count());
00334       }
00335 
00336       unordered_multimap(initializer_list<value_type> __l,
00337              size_type __n = 10,
00338              const hasher& __hf = hasher(),
00339              const key_equal& __eql = key_equal(),
00340              const allocator_type& __a = allocator_type())
00341       : _Base(__l, __n, __hf, __eql, __a) { }
00342 
00343       unordered_multimap&
00344       operator=(const unordered_multimap& __x)
00345       {
00346     *static_cast<_Base*>(this) = __x;
00347     return *this;
00348       }
00349 
00350       unordered_multimap&
00351       operator=(unordered_multimap&& __x)
00352       {
00353     // NB: DR 1204.
00354     // NB: DR 675.
00355     this->clear();
00356     this->swap(__x);
00357     return *this;
00358       }
00359 
00360       unordered_multimap&
00361       operator=(initializer_list<value_type> __l)
00362       {
00363     this->clear();
00364     this->insert(__l);
00365     return *this;
00366       }
00367 
00368       ~unordered_multimap()
00369       {
00370         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00371                      _Base::size());
00372         _M_profile_destruct();
00373       }
00374 
00375       _Base&
00376       _M_base()       { return *this; }
00377 
00378       const _Base&
00379       _M_base() const { return *this; }
00380 
00381 
00382       void
00383       clear()
00384       {
00385         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00386                      _Base::size());
00387         _M_profile_destruct();
00388         _Base::clear();
00389       }
00390 
00391       void
00392       insert(std::initializer_list<value_type> __l)
00393       { 
00394         size_type __old_size =  _Base::bucket_count();
00395         _Base::insert(__l);
00396         _M_profile_resize(__old_size, _Base::bucket_count());
00397       }
00398 
00399       iterator
00400       insert(const value_type& __obj)
00401       {
00402         size_type __old_size =  _Base::bucket_count();
00403         iterator __res = _Base::insert(__obj);
00404         _M_profile_resize(__old_size, _Base::bucket_count()); 
00405         return __res;
00406       }
00407 
00408       iterator
00409       insert(const_iterator __iter, const value_type& __v)
00410       { 
00411         size_type __old_size = _Base::bucket_count(); 
00412         iterator __res =_Base::insert(__iter, __v);
00413         _M_profile_resize(__old_size, _Base::bucket_count()); 
00414         return __res;
00415       }
00416 
00417       template<typename _InputIter>
00418         void
00419         insert(_InputIter __first, _InputIter __last)
00420         {
00421       size_type __old_size = _Base::bucket_count(); 
00422       _Base::insert(__first.base(), __last.base());
00423       _M_profile_resize(__old_size, _Base::bucket_count()); 
00424     }
00425 
00426       void
00427       insert(const value_type* __first, const value_type* __last)
00428       {
00429         size_type __old_size = _Base::bucket_count(); 
00430         _Base::insert(__first, __last);
00431         _M_profile_resize(__old_size, _Base::bucket_count()); 
00432       }
00433 
00434       void
00435       swap(unordered_multimap& __x)
00436       { _Base::swap(__x); }
00437 
00438       void rehash(size_type __n)
00439       {
00440         size_type __old_size =  _Base::bucket_count();
00441         _Base::rehash(__n);
00442         _M_profile_resize(__old_size, _Base::bucket_count()); 
00443       }
00444 
00445     private:
00446       void
00447       _M_profile_resize(size_type __old_size, size_type __new_size)
00448       {
00449         if (__old_size != __new_size)
00450           __profcxx_hashtable_resize(this, __old_size, __new_size);
00451       }
00452 
00453       void
00454       _M_profile_destruct()
00455       {
00456         size_type __hops = 0, __lc = 0, __chain = 0;
00457         for (iterator __it = _M_base().begin(); __it != _M_base().end();
00458          ++__it)
00459       {
00460         while (__it._M_cur_node->_M_next)
00461           {
00462         ++__chain;
00463         ++__it;
00464           }
00465         if (__chain)
00466           {
00467         ++__chain;
00468         __lc = __lc > __chain ? __lc : __chain;
00469         __hops += __chain * (__chain - 1) / 2;
00470         __chain = 0;
00471           }
00472       }
00473         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
00474       }
00475 
00476     };
00477 
00478   template<typename _Key, typename _Tp, typename _Hash,
00479        typename _Pred, typename _Alloc>
00480     inline void
00481     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00482      unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00483     { __x.swap(__y); }
00484 
00485 } // namespace __profile
00486 } // namespace std
00487 
00488 #undef _GLIBCXX_BASE
00489 #undef _GLIBCXX_STD_BASE
00490 
00491 #endif

Generated on 12 Mar 2010 for libstdc++ by  doxygen 1.6.1