Home | History | Annotate | Download | only in resize_policy
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the terms
      7 // of the GNU General Public License as published by the Free Software
      8 // Foundation; either version 3, or (at your option) any later
      9 // version.
     10 
     11 // This library is distributed in the hope that it will be useful, but
     12 // WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 // General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
     26 
     27 // Permission to use, copy, modify, sell, and distribute this software
     28 // is hereby granted without fee, provided that the above copyright
     29 // notice appears in all copies, and that both that copyright notice
     30 // and this permission notice appear in supporting documentation. None
     31 // of the above authors, nor IBM Haifa Research Laboratories, make any
     32 // representation about the suitability of this software for any
     33 // purpose. It is provided "as is" without express or implied
     34 // warranty.
     35 
     36 /**
     37  * @file hash_load_check_resize_trigger_imp.hpp
     38  * Contains a resize trigger implementation.
     39  */
     40 
     41 PB_DS_CLASS_T_DEC
     42 PB_DS_CLASS_C_DEC::
     43 hash_load_check_resize_trigger(float load_min, float load_max)
     44 : m_load_min(load_min), m_load_max(load_max), m_next_shrink_size(0),
     45   m_next_grow_size(0), m_resize_needed(false)
     46 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     47 
     48 PB_DS_CLASS_T_DEC
     49 inline void
     50 PB_DS_CLASS_C_DEC::
     51 notify_find_search_start()
     52 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     53 
     54 PB_DS_CLASS_T_DEC
     55 inline void
     56 PB_DS_CLASS_C_DEC::
     57 notify_find_search_collision()
     58 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     59 
     60 PB_DS_CLASS_T_DEC
     61 inline void
     62 PB_DS_CLASS_C_DEC::
     63 notify_find_search_end()
     64 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     65 
     66 PB_DS_CLASS_T_DEC
     67 inline void
     68 PB_DS_CLASS_C_DEC::
     69 notify_insert_search_start()
     70 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     71 
     72 PB_DS_CLASS_T_DEC
     73 inline void
     74 PB_DS_CLASS_C_DEC::
     75 notify_insert_search_collision()
     76 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     77 
     78 PB_DS_CLASS_T_DEC
     79 inline void
     80 PB_DS_CLASS_C_DEC::
     81 notify_insert_search_end()
     82 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     83 
     84 PB_DS_CLASS_T_DEC
     85 inline void
     86 PB_DS_CLASS_C_DEC::
     87 notify_erase_search_start()
     88 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     89 
     90 PB_DS_CLASS_T_DEC
     91 inline void
     92 PB_DS_CLASS_C_DEC::
     93 notify_erase_search_collision()
     94 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
     95 
     96 PB_DS_CLASS_T_DEC
     97 inline void
     98 PB_DS_CLASS_C_DEC::
     99 notify_erase_search_end()
    100 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
    101 
    102 PB_DS_CLASS_T_DEC
    103 inline void
    104 PB_DS_CLASS_C_DEC::
    105 notify_inserted(size_type num_entries)
    106 {
    107   m_resize_needed = (num_entries >= m_next_grow_size);
    108   size_base::set_size(num_entries);
    109   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    110 }
    111 
    112 PB_DS_CLASS_T_DEC
    113 inline void
    114 PB_DS_CLASS_C_DEC::
    115 notify_erased(size_type num_entries)
    116 {
    117   size_base::set_size(num_entries);
    118   m_resize_needed = num_entries <= m_next_shrink_size;
    119   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    120 }
    121 
    122 PB_DS_CLASS_T_DEC
    123 inline bool
    124 PB_DS_CLASS_C_DEC::
    125 is_resize_needed() const
    126 {
    127   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    128   return m_resize_needed;
    129 }
    130 
    131 PB_DS_CLASS_T_DEC
    132 inline bool
    133 PB_DS_CLASS_C_DEC::
    134 is_grow_needed(size_type /*size*/, size_type num_entries) const
    135 {
    136   _GLIBCXX_DEBUG_ASSERT(m_resize_needed);
    137   return num_entries >= m_next_grow_size;
    138 }
    139 
    140 PB_DS_CLASS_T_DEC
    141 PB_DS_CLASS_C_DEC::
    142 ~hash_load_check_resize_trigger() { }
    143 
    144 PB_DS_CLASS_T_DEC
    145 void
    146 PB_DS_CLASS_C_DEC::
    147 notify_resized(size_type new_size)
    148 {
    149   m_resize_needed = false;
    150   m_next_grow_size = size_type(m_load_max * new_size - 1);
    151   m_next_shrink_size = size_type(m_load_min * new_size);
    152 
    153 #ifdef PB_DS_HT_MAP_RESIZE_TRACE_
    154   std::cerr << "hlcrt::notify_resized " <<
    155     static_cast<unsigned long>(new_size) << "    " <<
    156     static_cast<unsigned long>(m_load_min) << "    " <<
    157     static_cast<unsigned long>(m_load_max) << "    " <<
    158     static_cast<unsigned long>(m_next_shrink_size) << " " <<
    159     static_cast<unsigned long>(m_next_grow_size) << "    " << std::endl;
    160 #endif
    161 
    162   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    163 }
    164 
    165 PB_DS_CLASS_T_DEC
    166 void
    167 PB_DS_CLASS_C_DEC::
    168 notify_externally_resized(size_type new_size)
    169 {
    170   m_resize_needed = false;
    171   size_type new_grow_size = size_type(m_load_max * new_size - 1);
    172   size_type new_shrink_size = size_type(m_load_min * new_size);
    173   if (new_grow_size >= m_next_grow_size)
    174     {
    175       _GLIBCXX_DEBUG_ASSERT(new_shrink_size > m_next_shrink_size);
    176       m_next_grow_size = new_grow_size;
    177       _GLIBCXX_DEBUG_ONLY(assert_valid();)
    178 
    179 #ifdef PB_DS_HT_MAP_RESIZE_TRACE_
    180 	std::cerr << "hlcrt::notify_externally_resized1 " <<
    181         static_cast<unsigned long>(new_size) << "    " <<
    182         static_cast<unsigned long>(m_load_min) << "    " <<
    183         static_cast<unsigned long>(m_load_max) << "    " <<
    184         static_cast<unsigned long>(m_next_shrink_size) << " " <<
    185         static_cast<unsigned long>(m_next_grow_size) << "    " << std::endl;
    186 #endif
    187       return;
    188     }
    189 
    190   _GLIBCXX_DEBUG_ASSERT(new_shrink_size <= m_next_shrink_size);
    191   m_next_shrink_size = new_shrink_size;
    192 
    193 #ifdef PB_DS_HT_MAP_RESIZE_TRACE_
    194   std::cerr << "hlcrt::notify_externally_resized2 " <<
    195     static_cast<unsigned long>(new_size) << "    " <<
    196     static_cast<unsigned long>(m_load_min) << "    " <<
    197     static_cast<unsigned long>(m_load_max) << "    " <<
    198     static_cast<unsigned long>(m_next_shrink_size) << " " <<
    199     static_cast<unsigned long>(m_next_grow_size) << "    " << std::endl;
    200 #endif
    201 
    202   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    203 }
    204 
    205 PB_DS_CLASS_T_DEC
    206 void
    207 PB_DS_CLASS_C_DEC::
    208 notify_cleared()
    209 {
    210   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    211   size_base::set_size(0);
    212   m_resize_needed = (0 < m_next_shrink_size);
    213   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    214 }
    215 
    216 PB_DS_CLASS_T_DEC
    217 void
    218 PB_DS_CLASS_C_DEC::
    219 swap(PB_DS_CLASS_C_DEC& other)
    220 {
    221   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    222   _GLIBCXX_DEBUG_ONLY(other.assert_valid();)
    223 
    224   size_base::swap(other);
    225   std::swap(m_load_min, other.m_load_min);
    226   std::swap(m_load_max, other.m_load_max);
    227   std::swap(m_resize_needed, other.m_resize_needed);
    228   std::swap(m_next_grow_size, other.m_next_grow_size);
    229   std::swap(m_next_shrink_size, other.m_next_shrink_size);
    230 
    231   _GLIBCXX_DEBUG_ONLY(assert_valid();)
    232   _GLIBCXX_DEBUG_ONLY(other.assert_valid();)
    233 }
    234 
    235 PB_DS_CLASS_T_DEC
    236 inline std::pair<float, float>
    237 PB_DS_CLASS_C_DEC::
    238 get_loads() const
    239 {
    240   PB_DS_STATIC_ASSERT(access, external_load_access);
    241   return std::make_pair(m_load_min, m_load_max);
    242 }
    243 
    244 PB_DS_CLASS_T_DEC
    245 void
    246 PB_DS_CLASS_C_DEC::
    247 set_loads(std::pair<float, float> load_pair)
    248 {
    249   PB_DS_STATIC_ASSERT(access, external_load_access);
    250   const float old_load_min = m_load_min;
    251   const float old_load_max = m_load_max;
    252   const size_type old_next_shrink_size = m_next_shrink_size;
    253   const size_type old_next_grow_size = m_next_grow_size;
    254   const bool old_resize_needed = m_resize_needed;
    255 
    256   __try
    257     {
    258       m_load_min = load_pair.first;
    259       m_load_max = load_pair.second;
    260       do_resize(static_cast<size_type>(size_base::get_size() / ((m_load_min + m_load_max) / 2)));
    261     }
    262   __catch(...)
    263     {
    264       m_load_min = old_load_min;
    265       m_load_max = old_load_max;
    266       m_next_shrink_size = old_next_shrink_size;
    267       m_next_grow_size = old_next_grow_size;
    268       m_resize_needed = old_resize_needed;
    269       __throw_exception_again;
    270     }
    271 }
    272 
    273 PB_DS_CLASS_T_DEC
    274 void
    275 PB_DS_CLASS_C_DEC::
    276 do_resize(size_type)
    277 { std::abort(); }
    278 
    279 #ifdef _GLIBCXX_DEBUG
    280 PB_DS_CLASS_T_DEC
    281 void
    282 PB_DS_CLASS_C_DEC::
    283 assert_valid() const
    284 {
    285   _GLIBCXX_DEBUG_ASSERT(m_load_max > m_load_min);
    286   _GLIBCXX_DEBUG_ASSERT(m_next_grow_size >= m_next_shrink_size);
    287 }
    288 #endif
    289 
    290