// -*- C++ -*-
//
// Copyright (C) 2009-2019 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

/** @file profile/impl/profiler_map_to_unordered_map.h
 *  @brief Diagnostics for map to unordered_map.
 */

// Written by Silvius Rus.

#ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H
#define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1

#include "profile/impl/profiler.h"
#include "profile/impl/profiler_node.h"
#include "profile/impl/profiler_trace.h"

namespace __gnu_profile
{
  inline int
  __log2(std::size_t __size)
  {
    for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0;
	 -- __bit_count)
      if ((2 << __bit_count) & __size)
	return __bit_count;
    return 0;
  }

  inline float
  __map_insert_cost(std::size_t __size)
  { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
	    * static_cast<float>(__log2(__size))); }

  inline float
  __map_erase_cost(std::size_t __size)
  { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
	    * static_cast<float>(__log2(__size))); }

  inline float
  __map_find_cost(std::size_t __size)
  { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
	    * static_cast<float>(__log2(__size))); }

  /** @brief A map-to-unordered_map instrumentation line in the
      object table.  */
  class __map2umap_info
  : public __object_info_base
  {
  public:
    __map2umap_info(__stack_t __stack)
    : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
      _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0)
    { }

    void
    __merge(const __map2umap_info& __o)
    {
      __object_info_base::__merge(__o);
      _M_insert		+= __o._M_insert;
      _M_erase		+= __o._M_erase;
      _M_find		+= __o._M_find;
      _M_iterate	+= __o._M_iterate;
      _M_umap_cost	+= __o._M_umap_cost;
      _M_map_cost	+= __o._M_map_cost;
    }

    void
    __write(FILE* __f) const
    {
      std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f\n",
		   _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
		   _M_umap_cost);
    }

    float
    __magnitude() const
    { return _M_map_cost - _M_umap_cost; }

    std::string
    __advice() const
    { return "prefer an unordered container"; }

    void
    __record_insert(std::size_t __size, std::size_t __count)
    {
      ++_M_insert;
      if (__count)
	{
	  _M_map_cost += __count * __map_insert_cost(__size);
	  _M_umap_cost
	    += (__count
		* _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
	}
    }

    void
    __record_erase(std::size_t __size, std::size_t __count)
    {
      ++_M_erase;
      if (__count)
	{
	  _M_map_cost += __count * __map_erase_cost(__size);
	  _M_umap_cost
	    += (__count
		* _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
	}
    }

    void
    __record_find(std::size_t __size)
    {
      ++_M_find;
      _M_map_cost += __map_find_cost(__size);
      _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
    }

    void
    __record_iterate(int __count)
    { __gnu_cxx::__atomic_add(&_M_iterate, __count); }

    void
    __set_iterate_costs()
    {
      _M_umap_cost
	+= (_M_iterate
	    * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
      _M_map_cost
	+= (_M_iterate
	    * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
    }

  private:
    std::size_t _M_insert;
    std::size_t _M_erase;
    std::size_t _M_find;
    mutable _Atomic_word _M_iterate;
    float _M_umap_cost;
    float _M_map_cost;
  };


  /** @brief A map-to-unordered_map instrumentation line in the
      stack table.  */
  class __map2umap_stack_info
  : public __map2umap_info
  {
  public:
    __map2umap_stack_info(const __map2umap_info& __o)
    : __map2umap_info(__o) { }
  };

  /** @brief Map-to-unordered_map instrumentation producer.  */
  class __trace_map2umap
  : public __trace_base<__map2umap_info, __map2umap_stack_info>
  {
  public:
    __trace_map2umap()
    : __trace_base<__map2umap_info, __map2umap_stack_info>()
    { __id = "ordered-to-unordered"; }

    // Call at destruction/clean to set container final size.
    void
    __destruct(__map2umap_info* __obj_info)
    {
      __obj_info->__set_iterate_costs();
      __retire_object(__obj_info);
    }
  };

  inline void
  __trace_map_to_unordered_map_init()
  { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }

  inline void
  __trace_map_to_unordered_map_free()
  { delete _GLIBCXX_PROFILE_DATA(_S_map2umap); }

  inline void
  __trace_map_to_unordered_map_report(FILE* __f,
				      __warning_vector_t& __warnings)
  { __trace_report(_GLIBCXX_PROFILE_DATA(_S_map2umap), __f, __warnings); }

  inline __map2umap_info*
  __trace_map_to_unordered_map_construct()
  {
    if (!__profcxx_init())
      return 0;

    if (!__reentrance_guard::__get_in())
      return 0;

    __reentrance_guard __get_out;
    return _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(__get_stack());
  }

  inline void
  __trace_map_to_unordered_map_insert(__map2umap_info* __info,
				      std::size_t __size, std::size_t __count)
  {
    if (!__info)
      return;

    __info->__record_insert(__size, __count);
  }

  inline void
  __trace_map_to_unordered_map_erase(__map2umap_info* __info,
				     std::size_t __size, std::size_t __count)
  {
    if (!__info)
      return;

    __info->__record_erase(__size, __count);
  }

  inline void
  __trace_map_to_unordered_map_find(__map2umap_info* __info,
				    std::size_t __size)
  {
    if (!__info)
      return;

    __info->__record_find(__size);
  }

  inline void
  __trace_map_to_unordered_map_iterate(__map2umap_info* __info,
				       int)
  {
    if (!__info)
      return;

    // We only collect if an iteration took place no matter in what side.
    __info->__record_iterate(1);
  }

  inline void
  __trace_map_to_unordered_map_invalidate(__map2umap_info* __info)
  {
    if (!__info)
      return;

    __info->__set_invalid();
  }

  inline void
  __trace_map_to_unordered_map_destruct(__map2umap_info* __info)
  {
    if (!__info)
      return;

    _GLIBCXX_PROFILE_DATA(_S_map2umap)->__destruct(__info);
  }
} // namespace __gnu_profile
#endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
