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