1*e4b17023SJohn Marino // -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino // 5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the terms 7*e4b17023SJohn Marino // of the GNU General Public License as published by the Free Software 8*e4b17023SJohn Marino // Foundation; either version 3, or (at your option) any later 9*e4b17023SJohn Marino // version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, but 12*e4b17023SJohn Marino // WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*e4b17023SJohn Marino // General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 26*e4b17023SJohn Marino 27*e4b17023SJohn Marino // Permission to use, copy, modify, sell, and distribute this software 28*e4b17023SJohn Marino // is hereby granted without fee, provided that the above copyright 29*e4b17023SJohn Marino // notice appears in all copies, and that both that copyright notice 30*e4b17023SJohn Marino // and this permission notice appear in supporting documentation. None 31*e4b17023SJohn Marino // of the above authors, nor IBM Haifa Research Laboratories, make any 32*e4b17023SJohn Marino // representation about the suitability of this software for any 33*e4b17023SJohn Marino // purpose. It is provided "as is" without express or implied 34*e4b17023SJohn Marino // warranty. 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino /** 37*e4b17023SJohn Marino * @file hash_policy.hpp 38*e4b17023SJohn Marino * Contains hash-related policies. 39*e4b17023SJohn Marino */ 40*e4b17023SJohn Marino 41*e4b17023SJohn Marino #ifndef PB_DS_HASH_POLICY_HPP 42*e4b17023SJohn Marino #define PB_DS_HASH_POLICY_HPP 43*e4b17023SJohn Marino 44*e4b17023SJohn Marino #include <bits/c++config.h> 45*e4b17023SJohn Marino #include <algorithm> 46*e4b17023SJohn Marino #include <vector> 47*e4b17023SJohn Marino #include <cmath> 48*e4b17023SJohn Marino #include <ext/pb_ds/exception.hpp> 49*e4b17023SJohn Marino #include <ext/pb_ds/detail/type_utils.hpp> 50*e4b17023SJohn Marino #include <ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp> 51*e4b17023SJohn Marino #include <ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp> 52*e4b17023SJohn Marino #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp> 53*e4b17023SJohn Marino 54*e4b17023SJohn Marino namespace __gnu_pbds 55*e4b17023SJohn Marino { 56*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<typename Size_Type> 57*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC linear_probe_fn<Size_Type> 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino /// A probe sequence policy using fixed increments. 60*e4b17023SJohn Marino template<typename Size_Type = std::size_t> 61*e4b17023SJohn Marino class linear_probe_fn 62*e4b17023SJohn Marino { 63*e4b17023SJohn Marino public: 64*e4b17023SJohn Marino typedef Size_Type size_type; 65*e4b17023SJohn Marino 66*e4b17023SJohn Marino void 67*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 68*e4b17023SJohn Marino 69*e4b17023SJohn Marino protected: 70*e4b17023SJohn Marino /// Returns the i-th offset from the hash value. 71*e4b17023SJohn Marino inline size_type 72*e4b17023SJohn Marino operator()(size_type i) const; 73*e4b17023SJohn Marino }; 74*e4b17023SJohn Marino 75*e4b17023SJohn Marino #include <ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp> 76*e4b17023SJohn Marino 77*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 78*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<typename Size_Type> 81*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC quadratic_probe_fn<Size_Type> 82*e4b17023SJohn Marino 83*e4b17023SJohn Marino /// A probe sequence policy using square increments. 84*e4b17023SJohn Marino template<typename Size_Type = std::size_t> 85*e4b17023SJohn Marino class quadratic_probe_fn 86*e4b17023SJohn Marino { 87*e4b17023SJohn Marino public: 88*e4b17023SJohn Marino typedef Size_Type size_type; 89*e4b17023SJohn Marino 90*e4b17023SJohn Marino void 91*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 92*e4b17023SJohn Marino 93*e4b17023SJohn Marino protected: 94*e4b17023SJohn Marino /// Returns the i-th offset from the hash value. 95*e4b17023SJohn Marino inline size_type 96*e4b17023SJohn Marino operator()(size_type i) const; 97*e4b17023SJohn Marino }; 98*e4b17023SJohn Marino 99*e4b17023SJohn Marino #include <ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp> 100*e4b17023SJohn Marino 101*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 102*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 103*e4b17023SJohn Marino 104*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<typename Size_Type> 105*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC direct_mask_range_hashing<Size_Type> 106*e4b17023SJohn Marino 107*e4b17023SJohn Marino /// A mask range-hashing class (uses a bitmask). 108*e4b17023SJohn Marino template<typename Size_Type = std::size_t> 109*e4b17023SJohn Marino class direct_mask_range_hashing 110*e4b17023SJohn Marino : public detail::mask_based_range_hashing<Size_Type> 111*e4b17023SJohn Marino { 112*e4b17023SJohn Marino private: 113*e4b17023SJohn Marino typedef detail::mask_based_range_hashing<Size_Type> mask_based_base; 114*e4b17023SJohn Marino 115*e4b17023SJohn Marino public: 116*e4b17023SJohn Marino typedef Size_Type size_type; 117*e4b17023SJohn Marino 118*e4b17023SJohn Marino void 119*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 120*e4b17023SJohn Marino 121*e4b17023SJohn Marino protected: 122*e4b17023SJohn Marino void 123*e4b17023SJohn Marino notify_resized(size_type size); 124*e4b17023SJohn Marino 125*e4b17023SJohn Marino /// Transforms the __hash value hash into a ranged-hash value 126*e4b17023SJohn Marino /// (using a bit-mask). 127*e4b17023SJohn Marino inline size_type 128*e4b17023SJohn Marino operator()(size_type hash) const; 129*e4b17023SJohn Marino }; 130*e4b17023SJohn Marino 131*e4b17023SJohn Marino #include <ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp> 132*e4b17023SJohn Marino 133*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 134*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<typename Size_Type> 137*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC direct_mod_range_hashing<Size_Type> 138*e4b17023SJohn Marino 139*e4b17023SJohn Marino /// A mod range-hashing class (uses the modulo function). 140*e4b17023SJohn Marino template<typename Size_Type = std::size_t> 141*e4b17023SJohn Marino class direct_mod_range_hashing 142*e4b17023SJohn Marino : public detail::mod_based_range_hashing<Size_Type> 143*e4b17023SJohn Marino { 144*e4b17023SJohn Marino public: 145*e4b17023SJohn Marino typedef Size_Type size_type; 146*e4b17023SJohn Marino 147*e4b17023SJohn Marino void 148*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 149*e4b17023SJohn Marino 150*e4b17023SJohn Marino protected: 151*e4b17023SJohn Marino void 152*e4b17023SJohn Marino notify_resized(size_type size); 153*e4b17023SJohn Marino 154*e4b17023SJohn Marino /// Transforms the __hash value hash into a ranged-hash value 155*e4b17023SJohn Marino /// (using a modulo operation). 156*e4b17023SJohn Marino inline size_type 157*e4b17023SJohn Marino operator()(size_type hash) const; 158*e4b17023SJohn Marino 159*e4b17023SJohn Marino private: 160*e4b17023SJohn Marino typedef detail::mod_based_range_hashing<size_type> mod_based_base; 161*e4b17023SJohn Marino }; 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino #include <ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp> 164*e4b17023SJohn Marino 165*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 166*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> 169*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger<External_Load_Access, Size_Type> 170*e4b17023SJohn Marino #define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base<Size_Type, External_Load_Access> 171*e4b17023SJohn Marino 172*e4b17023SJohn Marino /// A resize trigger policy based on a load check. It keeps the 173*e4b17023SJohn Marino /// load factor between some load factors load_min and load_max. 174*e4b17023SJohn Marino template<bool External_Load_Access = false, typename Size_Type = std::size_t> 175*e4b17023SJohn Marino class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC 176*e4b17023SJohn Marino { 177*e4b17023SJohn Marino public: 178*e4b17023SJohn Marino typedef Size_Type size_type; 179*e4b17023SJohn Marino 180*e4b17023SJohn Marino enum 181*e4b17023SJohn Marino { 182*e4b17023SJohn Marino /// Specifies whether the load factor can be accessed 183*e4b17023SJohn Marino /// externally. The two options have different trade-offs in 184*e4b17023SJohn Marino /// terms of flexibility, genericity, and encapsulation. 185*e4b17023SJohn Marino external_load_access = External_Load_Access 186*e4b17023SJohn Marino }; 187*e4b17023SJohn Marino 188*e4b17023SJohn Marino /// Default constructor, or constructor taking load_min and 189*e4b17023SJohn Marino /// load_max load factors between which this policy will keep the 190*e4b17023SJohn Marino /// actual load. 191*e4b17023SJohn Marino hash_load_check_resize_trigger(float load_min = 0.125, 192*e4b17023SJohn Marino float load_max = 0.5); 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino void 195*e4b17023SJohn Marino swap(hash_load_check_resize_trigger& other); 196*e4b17023SJohn Marino 197*e4b17023SJohn Marino virtual 198*e4b17023SJohn Marino ~hash_load_check_resize_trigger(); 199*e4b17023SJohn Marino 200*e4b17023SJohn Marino /// Returns a pair of the minimal and maximal loads, respectively. 201*e4b17023SJohn Marino inline std::pair<float, float> 202*e4b17023SJohn Marino get_loads() const; 203*e4b17023SJohn Marino 204*e4b17023SJohn Marino /// Sets the loads through a pair of the minimal and maximal 205*e4b17023SJohn Marino /// loads, respectively. 206*e4b17023SJohn Marino void 207*e4b17023SJohn Marino set_loads(std::pair<float, float> load_pair); 208*e4b17023SJohn Marino 209*e4b17023SJohn Marino protected: 210*e4b17023SJohn Marino inline void 211*e4b17023SJohn Marino notify_insert_search_start(); 212*e4b17023SJohn Marino 213*e4b17023SJohn Marino inline void 214*e4b17023SJohn Marino notify_insert_search_collision(); 215*e4b17023SJohn Marino 216*e4b17023SJohn Marino inline void 217*e4b17023SJohn Marino notify_insert_search_end(); 218*e4b17023SJohn Marino 219*e4b17023SJohn Marino inline void 220*e4b17023SJohn Marino notify_find_search_start(); 221*e4b17023SJohn Marino 222*e4b17023SJohn Marino inline void 223*e4b17023SJohn Marino notify_find_search_collision(); 224*e4b17023SJohn Marino 225*e4b17023SJohn Marino inline void 226*e4b17023SJohn Marino notify_find_search_end(); 227*e4b17023SJohn Marino 228*e4b17023SJohn Marino inline void 229*e4b17023SJohn Marino notify_erase_search_start(); 230*e4b17023SJohn Marino 231*e4b17023SJohn Marino inline void 232*e4b17023SJohn Marino notify_erase_search_collision(); 233*e4b17023SJohn Marino 234*e4b17023SJohn Marino inline void 235*e4b17023SJohn Marino notify_erase_search_end(); 236*e4b17023SJohn Marino 237*e4b17023SJohn Marino /// Notifies an element was inserted. The total number of entries 238*e4b17023SJohn Marino /// in the table is num_entries. 239*e4b17023SJohn Marino inline void 240*e4b17023SJohn Marino notify_inserted(size_type num_entries); 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino inline void 243*e4b17023SJohn Marino notify_erased(size_type num_entries); 244*e4b17023SJohn Marino 245*e4b17023SJohn Marino /// Notifies the table was cleared. 246*e4b17023SJohn Marino void 247*e4b17023SJohn Marino notify_cleared(); 248*e4b17023SJohn Marino 249*e4b17023SJohn Marino /// Notifies the table was resized as a result of this object's 250*e4b17023SJohn Marino /// signifying that a resize is needed. 251*e4b17023SJohn Marino void 252*e4b17023SJohn Marino notify_resized(size_type new_size); 253*e4b17023SJohn Marino 254*e4b17023SJohn Marino void 255*e4b17023SJohn Marino notify_externally_resized(size_type new_size); 256*e4b17023SJohn Marino 257*e4b17023SJohn Marino inline bool 258*e4b17023SJohn Marino is_resize_needed() const; 259*e4b17023SJohn Marino 260*e4b17023SJohn Marino inline bool 261*e4b17023SJohn Marino is_grow_needed(size_type size, size_type num_entries) const; 262*e4b17023SJohn Marino 263*e4b17023SJohn Marino private: 264*e4b17023SJohn Marino virtual void 265*e4b17023SJohn Marino do_resize(size_type new_size); 266*e4b17023SJohn Marino 267*e4b17023SJohn Marino typedef PB_DS_SIZE_BASE_C_DEC size_base; 268*e4b17023SJohn Marino 269*e4b17023SJohn Marino #ifdef _GLIBCXX_DEBUG 270*e4b17023SJohn Marino void 271*e4b17023SJohn Marino assert_valid(const char* file, int line) const; 272*e4b17023SJohn Marino #endif 273*e4b17023SJohn Marino 274*e4b17023SJohn Marino float m_load_min; 275*e4b17023SJohn Marino float m_load_max; 276*e4b17023SJohn Marino size_type m_next_shrink_size; 277*e4b17023SJohn Marino size_type m_next_grow_size; 278*e4b17023SJohn Marino bool m_resize_needed; 279*e4b17023SJohn Marino }; 280*e4b17023SJohn Marino 281*e4b17023SJohn Marino #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp> 282*e4b17023SJohn Marino 283*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 284*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 285*e4b17023SJohn Marino #undef PB_DS_SIZE_BASE_C_DEC 286*e4b17023SJohn Marino 287*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> 288*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger<External_Load_Access, Size_Type> 289*e4b17023SJohn Marino 290*e4b17023SJohn Marino /// A resize trigger policy based on collision checks. It keeps the 291*e4b17023SJohn Marino /// simulated load factor lower than some given load factor. 292*e4b17023SJohn Marino template<bool External_Load_Access = false, typename Size_Type = std::size_t> 293*e4b17023SJohn Marino class cc_hash_max_collision_check_resize_trigger 294*e4b17023SJohn Marino { 295*e4b17023SJohn Marino public: 296*e4b17023SJohn Marino typedef Size_Type size_type; 297*e4b17023SJohn Marino 298*e4b17023SJohn Marino enum 299*e4b17023SJohn Marino { 300*e4b17023SJohn Marino /// Specifies whether the load factor can be accessed 301*e4b17023SJohn Marino /// externally. The two options have different trade-offs in 302*e4b17023SJohn Marino /// terms of flexibility, genericity, and encapsulation. 303*e4b17023SJohn Marino external_load_access = External_Load_Access 304*e4b17023SJohn Marino }; 305*e4b17023SJohn Marino 306*e4b17023SJohn Marino /// Default constructor, or constructor taking load, a __load 307*e4b17023SJohn Marino /// factor which it will attempt to maintain. 308*e4b17023SJohn Marino cc_hash_max_collision_check_resize_trigger(float load = 0.5); 309*e4b17023SJohn Marino 310*e4b17023SJohn Marino void 311*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 312*e4b17023SJohn Marino 313*e4b17023SJohn Marino /// Returns the current load. 314*e4b17023SJohn Marino inline float 315*e4b17023SJohn Marino get_load() const; 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino /// Sets the load; does not resize the container. 318*e4b17023SJohn Marino void 319*e4b17023SJohn Marino set_load(float load); 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino protected: 322*e4b17023SJohn Marino /// Notifies an insert search started. 323*e4b17023SJohn Marino inline void 324*e4b17023SJohn Marino notify_insert_search_start(); 325*e4b17023SJohn Marino 326*e4b17023SJohn Marino /// Notifies a search encountered a collision. 327*e4b17023SJohn Marino inline void 328*e4b17023SJohn Marino notify_insert_search_collision(); 329*e4b17023SJohn Marino 330*e4b17023SJohn Marino /// Notifies a search ended. 331*e4b17023SJohn Marino inline void 332*e4b17023SJohn Marino notify_insert_search_end(); 333*e4b17023SJohn Marino 334*e4b17023SJohn Marino /// Notifies a find search started. 335*e4b17023SJohn Marino inline void 336*e4b17023SJohn Marino notify_find_search_start(); 337*e4b17023SJohn Marino 338*e4b17023SJohn Marino /// Notifies a search encountered a collision. 339*e4b17023SJohn Marino inline void 340*e4b17023SJohn Marino notify_find_search_collision(); 341*e4b17023SJohn Marino 342*e4b17023SJohn Marino /// Notifies a search ended. 343*e4b17023SJohn Marino inline void 344*e4b17023SJohn Marino notify_find_search_end(); 345*e4b17023SJohn Marino 346*e4b17023SJohn Marino /// Notifies an erase search started. 347*e4b17023SJohn Marino inline void 348*e4b17023SJohn Marino notify_erase_search_start(); 349*e4b17023SJohn Marino 350*e4b17023SJohn Marino /// Notifies a search encountered a collision. 351*e4b17023SJohn Marino inline void 352*e4b17023SJohn Marino notify_erase_search_collision(); 353*e4b17023SJohn Marino 354*e4b17023SJohn Marino /// Notifies a search ended. 355*e4b17023SJohn Marino inline void 356*e4b17023SJohn Marino notify_erase_search_end(); 357*e4b17023SJohn Marino 358*e4b17023SJohn Marino /// Notifies an element was inserted. 359*e4b17023SJohn Marino inline void 360*e4b17023SJohn Marino notify_inserted(size_type num_entries); 361*e4b17023SJohn Marino 362*e4b17023SJohn Marino /// Notifies an element was erased. 363*e4b17023SJohn Marino inline void 364*e4b17023SJohn Marino notify_erased(size_type num_entries); 365*e4b17023SJohn Marino 366*e4b17023SJohn Marino /// Notifies the table was cleared. 367*e4b17023SJohn Marino void 368*e4b17023SJohn Marino notify_cleared(); 369*e4b17023SJohn Marino 370*e4b17023SJohn Marino /// Notifies the table was resized as a result of this object's 371*e4b17023SJohn Marino /// signifying that a resize is needed. 372*e4b17023SJohn Marino void 373*e4b17023SJohn Marino notify_resized(size_type new_size); 374*e4b17023SJohn Marino 375*e4b17023SJohn Marino /// Notifies the table was resized externally. 376*e4b17023SJohn Marino void 377*e4b17023SJohn Marino notify_externally_resized(size_type new_size); 378*e4b17023SJohn Marino 379*e4b17023SJohn Marino /// Queries whether a resize is needed. 380*e4b17023SJohn Marino inline bool 381*e4b17023SJohn Marino is_resize_needed() const; 382*e4b17023SJohn Marino 383*e4b17023SJohn Marino /// Queries whether a grow is needed. This method is called only 384*e4b17023SJohn Marino /// if this object indicated is needed. 385*e4b17023SJohn Marino inline bool 386*e4b17023SJohn Marino is_grow_needed(size_type size, size_type num_entries) const; 387*e4b17023SJohn Marino 388*e4b17023SJohn Marino private: 389*e4b17023SJohn Marino void 390*e4b17023SJohn Marino calc_max_num_coll(); 391*e4b17023SJohn Marino 392*e4b17023SJohn Marino inline void 393*e4b17023SJohn Marino calc_resize_needed(); 394*e4b17023SJohn Marino 395*e4b17023SJohn Marino float m_load; 396*e4b17023SJohn Marino size_type m_size; 397*e4b17023SJohn Marino size_type m_num_col; 398*e4b17023SJohn Marino size_type m_max_col; 399*e4b17023SJohn Marino bool m_resize_needed; 400*e4b17023SJohn Marino }; 401*e4b17023SJohn Marino 402*e4b17023SJohn Marino #include <ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp> 403*e4b17023SJohn Marino 404*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 405*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 406*e4b17023SJohn Marino 407*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<typename Size_Type> 408*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC hash_exponential_size_policy<Size_Type> 409*e4b17023SJohn Marino 410*e4b17023SJohn Marino /// A size policy whose sequence of sizes form an exponential 411*e4b17023SJohn Marino /// sequence (typically powers of 2. 412*e4b17023SJohn Marino template<typename Size_Type = std::size_t> 413*e4b17023SJohn Marino class hash_exponential_size_policy 414*e4b17023SJohn Marino { 415*e4b17023SJohn Marino public: 416*e4b17023SJohn Marino typedef Size_Type size_type; 417*e4b17023SJohn Marino 418*e4b17023SJohn Marino /// Default constructor, or onstructor taking a start_size, or 419*e4b17023SJohn Marino /// constructor taking a start size and grow_factor. The policy 420*e4b17023SJohn Marino /// will use the sequence of sizes start_size, start_size* 421*e4b17023SJohn Marino /// grow_factor, start_size* grow_factor^2, ... 422*e4b17023SJohn Marino hash_exponential_size_policy(size_type start_size = 8, 423*e4b17023SJohn Marino size_type grow_factor = 2); 424*e4b17023SJohn Marino 425*e4b17023SJohn Marino void 426*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 427*e4b17023SJohn Marino 428*e4b17023SJohn Marino protected: 429*e4b17023SJohn Marino size_type 430*e4b17023SJohn Marino get_nearest_larger_size(size_type size) const; 431*e4b17023SJohn Marino 432*e4b17023SJohn Marino size_type 433*e4b17023SJohn Marino get_nearest_smaller_size(size_type size) const; 434*e4b17023SJohn Marino 435*e4b17023SJohn Marino private: 436*e4b17023SJohn Marino size_type m_start_size; 437*e4b17023SJohn Marino size_type m_grow_factor; 438*e4b17023SJohn Marino }; 439*e4b17023SJohn Marino 440*e4b17023SJohn Marino #include <ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp> 441*e4b17023SJohn Marino 442*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 443*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 444*e4b17023SJohn Marino 445*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC 446*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC hash_prime_size_policy 447*e4b17023SJohn Marino 448*e4b17023SJohn Marino /// A size policy whose sequence of sizes form a nearly-exponential 449*e4b17023SJohn Marino /// sequence of primes. 450*e4b17023SJohn Marino class hash_prime_size_policy 451*e4b17023SJohn Marino { 452*e4b17023SJohn Marino public: 453*e4b17023SJohn Marino /// Size type. 454*e4b17023SJohn Marino typedef std::size_t size_type; 455*e4b17023SJohn Marino 456*e4b17023SJohn Marino /// Default constructor, or onstructor taking a start_size The 457*e4b17023SJohn Marino /// policy will use the sequence of sizes approximately 458*e4b17023SJohn Marino /// start_size, start_size* 2, start_size* 2^2, ... 459*e4b17023SJohn Marino hash_prime_size_policy(size_type start_size = 8); 460*e4b17023SJohn Marino 461*e4b17023SJohn Marino inline void 462*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 463*e4b17023SJohn Marino 464*e4b17023SJohn Marino protected: 465*e4b17023SJohn Marino size_type 466*e4b17023SJohn Marino get_nearest_larger_size(size_type size) const; 467*e4b17023SJohn Marino 468*e4b17023SJohn Marino size_type 469*e4b17023SJohn Marino get_nearest_smaller_size(size_type size) const; 470*e4b17023SJohn Marino 471*e4b17023SJohn Marino private: 472*e4b17023SJohn Marino size_type m_start_size; 473*e4b17023SJohn Marino }; 474*e4b17023SJohn Marino 475*e4b17023SJohn Marino #include <ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp> 476*e4b17023SJohn Marino 477*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 478*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 479*e4b17023SJohn Marino 480*e4b17023SJohn Marino #define PB_DS_CLASS_T_DEC template<typename Size_Policy, typename Trigger_Policy, bool External_Size_Access, typename Size_Type> 481*e4b17023SJohn Marino 482*e4b17023SJohn Marino #define PB_DS_CLASS_C_DEC hash_standard_resize_policy<Size_Policy, Trigger_Policy, External_Size_Access, Size_Type> 483*e4b17023SJohn Marino 484*e4b17023SJohn Marino /// A resize policy which delegates operations to size and trigger policies. 485*e4b17023SJohn Marino template<typename Size_Policy = hash_exponential_size_policy<>, 486*e4b17023SJohn Marino typename Trigger_Policy = hash_load_check_resize_trigger<>, 487*e4b17023SJohn Marino bool External_Size_Access = false, 488*e4b17023SJohn Marino typename Size_Type = std::size_t> 489*e4b17023SJohn Marino class hash_standard_resize_policy 490*e4b17023SJohn Marino : public Size_Policy, public Trigger_Policy 491*e4b17023SJohn Marino { 492*e4b17023SJohn Marino public: 493*e4b17023SJohn Marino typedef Size_Type size_type; 494*e4b17023SJohn Marino typedef Trigger_Policy trigger_policy; 495*e4b17023SJohn Marino typedef Size_Policy size_policy; 496*e4b17023SJohn Marino 497*e4b17023SJohn Marino enum 498*e4b17023SJohn Marino { 499*e4b17023SJohn Marino external_size_access = External_Size_Access 500*e4b17023SJohn Marino }; 501*e4b17023SJohn Marino 502*e4b17023SJohn Marino /// Default constructor. 503*e4b17023SJohn Marino hash_standard_resize_policy(); 504*e4b17023SJohn Marino 505*e4b17023SJohn Marino /// constructor taking some policies r_size_policy will be copied 506*e4b17023SJohn Marino /// by the Size_Policy object of this object. 507*e4b17023SJohn Marino hash_standard_resize_policy(const Size_Policy& r_size_policy); 508*e4b17023SJohn Marino 509*e4b17023SJohn Marino /// constructor taking some policies. r_size_policy will be 510*e4b17023SJohn Marino /// copied by the Size_Policy object of this 511*e4b17023SJohn Marino /// object. r_trigger_policy will be copied by the Trigger_Policy 512*e4b17023SJohn Marino /// object of this object. 513*e4b17023SJohn Marino hash_standard_resize_policy(const Size_Policy& r_size_policy, 514*e4b17023SJohn Marino const Trigger_Policy& r_trigger_policy); 515*e4b17023SJohn Marino 516*e4b17023SJohn Marino virtual 517*e4b17023SJohn Marino ~hash_standard_resize_policy(); 518*e4b17023SJohn Marino 519*e4b17023SJohn Marino inline void 520*e4b17023SJohn Marino swap(PB_DS_CLASS_C_DEC& other); 521*e4b17023SJohn Marino 522*e4b17023SJohn Marino /// Access to the Size_Policy object used. 523*e4b17023SJohn Marino Size_Policy& 524*e4b17023SJohn Marino get_size_policy(); 525*e4b17023SJohn Marino 526*e4b17023SJohn Marino /// Const access to the Size_Policy object used. 527*e4b17023SJohn Marino const Size_Policy& 528*e4b17023SJohn Marino get_size_policy() const; 529*e4b17023SJohn Marino 530*e4b17023SJohn Marino /// Access to the Trigger_Policy object used. 531*e4b17023SJohn Marino Trigger_Policy& 532*e4b17023SJohn Marino get_trigger_policy(); 533*e4b17023SJohn Marino 534*e4b17023SJohn Marino /// Access to the Trigger_Policy object used. 535*e4b17023SJohn Marino const Trigger_Policy& 536*e4b17023SJohn Marino get_trigger_policy() const; 537*e4b17023SJohn Marino 538*e4b17023SJohn Marino /// Returns the actual size of the container. 539*e4b17023SJohn Marino inline size_type 540*e4b17023SJohn Marino get_actual_size() const; 541*e4b17023SJohn Marino 542*e4b17023SJohn Marino /// Resizes the container to suggested_new_size, a suggested size 543*e4b17023SJohn Marino /// (the actual size will be determined by the Size_Policy 544*e4b17023SJohn Marino /// object). 545*e4b17023SJohn Marino void 546*e4b17023SJohn Marino resize(size_type suggested_new_size); 547*e4b17023SJohn Marino 548*e4b17023SJohn Marino protected: 549*e4b17023SJohn Marino inline void 550*e4b17023SJohn Marino notify_insert_search_start(); 551*e4b17023SJohn Marino 552*e4b17023SJohn Marino inline void 553*e4b17023SJohn Marino notify_insert_search_collision(); 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino inline void 556*e4b17023SJohn Marino notify_insert_search_end(); 557*e4b17023SJohn Marino 558*e4b17023SJohn Marino inline void 559*e4b17023SJohn Marino notify_find_search_start(); 560*e4b17023SJohn Marino 561*e4b17023SJohn Marino inline void 562*e4b17023SJohn Marino notify_find_search_collision(); 563*e4b17023SJohn Marino 564*e4b17023SJohn Marino inline void 565*e4b17023SJohn Marino notify_find_search_end(); 566*e4b17023SJohn Marino 567*e4b17023SJohn Marino inline void 568*e4b17023SJohn Marino notify_erase_search_start(); 569*e4b17023SJohn Marino 570*e4b17023SJohn Marino inline void 571*e4b17023SJohn Marino notify_erase_search_collision(); 572*e4b17023SJohn Marino 573*e4b17023SJohn Marino inline void 574*e4b17023SJohn Marino notify_erase_search_end(); 575*e4b17023SJohn Marino 576*e4b17023SJohn Marino inline void 577*e4b17023SJohn Marino notify_inserted(size_type num_e); 578*e4b17023SJohn Marino 579*e4b17023SJohn Marino inline void 580*e4b17023SJohn Marino notify_erased(size_type num_e); 581*e4b17023SJohn Marino 582*e4b17023SJohn Marino void 583*e4b17023SJohn Marino notify_cleared(); 584*e4b17023SJohn Marino 585*e4b17023SJohn Marino void 586*e4b17023SJohn Marino notify_resized(size_type new_size); 587*e4b17023SJohn Marino 588*e4b17023SJohn Marino inline bool 589*e4b17023SJohn Marino is_resize_needed() const; 590*e4b17023SJohn Marino 591*e4b17023SJohn Marino /// Queries what the new size should be, when the container is 592*e4b17023SJohn Marino /// resized naturally. The current __size of the container is 593*e4b17023SJohn Marino /// size, and the number of used entries within the container is 594*e4b17023SJohn Marino /// num_used_e. 595*e4b17023SJohn Marino size_type 596*e4b17023SJohn Marino get_new_size(size_type size, size_type num_used_e) const; 597*e4b17023SJohn Marino 598*e4b17023SJohn Marino private: 599*e4b17023SJohn Marino /// Resizes to new_size. 600*e4b17023SJohn Marino virtual void 601*e4b17023SJohn Marino do_resize(size_type new_size); 602*e4b17023SJohn Marino 603*e4b17023SJohn Marino typedef Trigger_Policy trigger_policy_base; 604*e4b17023SJohn Marino 605*e4b17023SJohn Marino typedef Size_Policy size_policy_base; 606*e4b17023SJohn Marino 607*e4b17023SJohn Marino size_type m_size; 608*e4b17023SJohn Marino }; 609*e4b17023SJohn Marino 610*e4b17023SJohn Marino #include <ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp> 611*e4b17023SJohn Marino 612*e4b17023SJohn Marino #undef PB_DS_CLASS_T_DEC 613*e4b17023SJohn Marino #undef PB_DS_CLASS_C_DEC 614*e4b17023SJohn Marino 615*e4b17023SJohn Marino } // namespace __gnu_pbds 616*e4b17023SJohn Marino 617*e4b17023SJohn Marino #endif 618