profiler_hash_func.h

00001 // -*- 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 terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 2, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this library; see the file COPYING.  If not, write to
00018 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00019 // MA 02111-1307, USA.
00020 
00021 // As a special exception, you may use this file as part of a free
00022 // software library without restriction.  Specifically, if other files
00023 // instantiate templates or use macros or inline functions from this
00024 // file, or you compile this file and link it with other files to
00025 // produce an executable, this file does not by itself cause the
00026 // resulting executable to be covered by the GNU General Public
00027 // License.  This exception does not however invalidate any other
00028 // reasons why the executable file might be covered by the GNU General
00029 // Public License.
00030 
00031 /** @file profile/impl/profiler_trace.h
00032  *  @brief Data structures to represent profiling traces.
00033  */
00034 
00035 // Written by Lixia Liu and Silvius Rus.
00036 
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H
00038 #define _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H 1
00039 
00040 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00041 #include <cstdlib>
00042 #include <cstdio>
00043 #include <cstring>
00044 #else
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <string.h>
00048 #endif
00049 #include "profile/impl/profiler.h"
00050 #include "profile/impl/profiler_node.h"
00051 #include "profile/impl/profiler_trace.h"
00052 
00053 namespace __gnu_profile
00054 {
00055 
00056 /** @brief A hash performance instrumentation line in the object table.  */
00057 class __hashfunc_info: public __object_info_base
00058 {
00059  public:
00060   __hashfunc_info()
00061       :_M_longest_chain(0), _M_accesses(0), _M_hops(0) {}
00062   __hashfunc_info(const __hashfunc_info& o);
00063   __hashfunc_info(__stack_t __stack)
00064       : __object_info_base(__stack),
00065         _M_longest_chain(0), _M_accesses(0), _M_hops(0){} 
00066   virtual ~__hashfunc_info() {}
00067 
00068   void __merge(const __hashfunc_info& __o);
00069   void __destruct(size_t __chain, size_t __accesses, size_t __hops);
00070   void __write(FILE* __f) const;
00071   float __magnitude() const { return static_cast<float>(_M_hops); }
00072   const char* __advice() const { return strdup("change hash function"); }
00073 
00074 private:
00075   size_t _M_longest_chain;
00076   size_t _M_accesses;
00077   size_t _M_hops;
00078 };
00079 
00080 inline __hashfunc_info::__hashfunc_info(const __hashfunc_info& __o)
00081     : __object_info_base(__o)
00082 {
00083   _M_longest_chain = __o._M_longest_chain;
00084   _M_accesses      = __o._M_accesses;
00085   _M_hops          = __o._M_hops;
00086 }
00087 
00088 inline void __hashfunc_info::__merge(const __hashfunc_info& __o)
00089 {
00090   _M_longest_chain  = std::max(_M_longest_chain, __o._M_longest_chain);
00091   _M_accesses      += __o._M_accesses;
00092   _M_hops          += __o._M_hops;
00093 }
00094 
00095 inline void __hashfunc_info::__destruct(size_t __chain, size_t __accesses, 
00096                                         size_t __hops)
00097 { 
00098   _M_longest_chain  = std::max(_M_longest_chain, __chain);
00099   _M_accesses      += __accesses;
00100   _M_hops          += __hops;
00101 }
00102 
00103 /** @brief A hash performance instrumentation line in the stack table.  */
00104 class __hashfunc_stack_info: public __hashfunc_info {
00105  public:
00106   __hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) {}
00107 };
00108 
00109 /** @brief Hash performance instrumentation producer.  */
00110 class __trace_hash_func
00111     : public __trace_base<__hashfunc_info, __hashfunc_stack_info> 
00112 {
00113  public:
00114   __trace_hash_func();
00115   ~__trace_hash_func() {}
00116 
00117   // Insert a new node at construct with object, callstack and initial size. 
00118   void __insert(__object_t __obj, __stack_t __stack);
00119   // Call at destruction/clean to set container final size.
00120   void __destruct(const void* __obj, size_t __chain,
00121                   size_t __accesses, size_t __hops);
00122 };
00123 
00124 inline __trace_hash_func::__trace_hash_func()
00125     : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
00126 {
00127   __id = "hash-distr";
00128 }
00129 
00130 inline void __trace_hash_func::__insert(__object_t __obj, __stack_t __stack)
00131 {
00132   __add_object(__obj, __hashfunc_info(__stack));
00133 }
00134 
00135 inline void __hashfunc_info::__write(FILE* __f) const
00136 {
00137   fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain);
00138 }
00139 
00140 inline void __trace_hash_func::__destruct(const void* __obj, size_t __chain,
00141                                           size_t __accesses, size_t __hops)
00142 {
00143   if (!__is_on()) return;
00144 
00145   // First find the item from the live objects and update the informations.
00146   __hashfunc_info* __objs = __get_object_info(__obj);
00147   if (!__objs)
00148     return;
00149 
00150   __objs->__destruct(__chain, __accesses, __hops);
00151   __retire_object(__obj);
00152 }
00153 
00154 inline void __trace_hash_func_init()
00155 {
00156   _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func();
00157 }
00158 
00159 inline void __trace_hash_func_report(FILE* __f,
00160                                      __warning_vector_t& __warnings)
00161 {
00162   if (_GLIBCXX_PROFILE_DATA(_S_hash_func)) {
00163     _GLIBCXX_PROFILE_DATA(_S_hash_func)->__collect_warnings(__warnings);
00164     _GLIBCXX_PROFILE_DATA(_S_hash_func)->__write(__f);
00165   }
00166 }
00167 
00168 inline void __trace_hash_func_construct(const void* __obj)
00169 {
00170   if (!__profcxx_init()) return;
00171 
00172   _GLIBCXX_PROFILE_DATA(_S_hash_func)->__insert(__obj, __get_stack());
00173 }
00174 
00175 inline void __trace_hash_func_destruct(const void* __obj, size_t __chain,
00176                                        size_t __accesses, size_t __hops)
00177 {
00178   if (!__profcxx_init()) return;
00179 
00180   _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain, __accesses, 
00181                                                   __hops);
00182 }
00183 
00184 } // namespace __gnu_profile
00185 #endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */