# 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 */