Merge branch 'vendor/GCC44' into gcc441
[dragonfly.git] / contrib / gcc-4.4 / libstdc++-v3 / include / ext / pb_ds / hash_policy.hpp
1 // -*- C++ -*-
2
3 // Copyright (C) 2005, 2006, 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_policy.hpp
38  * Contains hash-related policies.
39  */
40
41 #ifndef PB_DS_HASH_POLICY_HPP
42 #define PB_DS_HASH_POLICY_HPP
43
44 #include <algorithm>
45 #include <vector>
46 #include <cmath>
47 #include <ext/pb_ds/exception.hpp>
48 #include <ext/pb_ds/detail/type_utils.hpp>
49 #include <ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp>
50 #include <ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp>
51 #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp>
52
53 namespace __gnu_pbds
54 {
55   // A null hash function, indicating that the combining hash function
56   // is actually a ranged hash function.
57   struct null_hash_fn
58   { };
59
60   // A null probe function, indicating that the combining probe
61   // function is actually a ranged probe function.
62   struct null_probe_fn
63   { };
64
65 #define PB_DS_CLASS_T_DEC template<typename Size_Type>
66 #define PB_DS_CLASS_C_DEC linear_probe_fn<Size_Type>
67
68   // A probe sequence policy using fixed increments.
69   template<typename Size_Type = size_t>
70   class linear_probe_fn
71   {
72   public:
73     typedef Size_Type size_type;
74
75     void
76     swap(PB_DS_CLASS_C_DEC& other);
77
78   protected:
79     // Returns the i-th offset from the hash value.
80     inline size_type
81     operator()(size_type i) const;
82   };
83
84 #include <ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp>
85
86 #undef PB_DS_CLASS_T_DEC
87 #undef PB_DS_CLASS_C_DEC
88
89 #define PB_DS_CLASS_T_DEC template<typename Size_Type>
90 #define PB_DS_CLASS_C_DEC quadratic_probe_fn<Size_Type>
91
92   // A probe sequence policy using square increments.
93   template<typename Size_Type = size_t>
94   class quadratic_probe_fn
95   {
96   public:
97     typedef Size_Type size_type;
98
99     void
100     swap(PB_DS_CLASS_C_DEC& other);
101
102   protected:
103     // Returns the i-th offset from the hash value.
104     inline size_type
105     operator()(size_type i) const;
106   };
107
108 #include <ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp>
109
110 #undef PB_DS_CLASS_T_DEC
111 #undef PB_DS_CLASS_C_DEC
112
113 #define PB_DS_CLASS_T_DEC template<typename Size_Type>
114 #define PB_DS_CLASS_C_DEC direct_mask_range_hashing<Size_Type>
115
116   // A mask range-hashing class (uses a bit-mask).
117   template<typename Size_Type = size_t>
118   class direct_mask_range_hashing 
119   : public detail::mask_based_range_hashing<Size_Type>
120   {
121   private:
122     typedef detail::mask_based_range_hashing<Size_Type> mask_based_base;
123
124   public:
125     typedef Size_Type size_type;
126
127     void
128     swap(PB_DS_CLASS_C_DEC& other);
129
130   protected:
131     void
132     notify_resized(size_type size);
133
134     // Transforms the __hash value hash into a ranged-hash value
135     // (using a bit-mask).
136     inline size_type
137     operator()(size_type hash) const;
138   };
139
140 #include <ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp>
141
142 #undef PB_DS_CLASS_T_DEC
143 #undef PB_DS_CLASS_C_DEC
144
145 #define PB_DS_CLASS_T_DEC template<typename Size_Type>
146 #define PB_DS_CLASS_C_DEC direct_mod_range_hashing<Size_Type>
147
148   // A mod range-hashing class (uses the modulo function).
149   template<typename Size_Type = size_t>
150   class direct_mod_range_hashing 
151   : public detail::mod_based_range_hashing<Size_Type>
152   {
153   public:
154     typedef Size_Type size_type;
155       
156     void
157     swap(PB_DS_CLASS_C_DEC& other);
158
159   protected:
160     void
161     notify_resized(size_type size);
162       
163     // Transforms the __hash value hash into a ranged-hash value
164     // (using a modulo operation).
165     inline size_type
166     operator()(size_type hash) const;
167       
168   private:
169     typedef detail::mod_based_range_hashing<size_type> mod_based_base;
170   };
171
172 #include <ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp>
173
174 #undef PB_DS_CLASS_T_DEC
175 #undef PB_DS_CLASS_C_DEC
176
177 #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type>
178 #define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger<External_Load_Access, Size_Type>
179 #define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base<Size_Type, External_Load_Access>
180
181   // A resize trigger policy based on a load check. It keeps the
182   // load factor between some load factors load_min and load_max.
183   template<bool External_Load_Access = false, typename Size_Type = size_t>
184   class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC
185   {
186   public:
187     typedef Size_Type size_type;
188
189     enum
190       {
191         external_load_access = External_Load_Access
192       };
193
194     // Default constructor, or constructor taking load_min and
195     // load_max load factors between which this policy will keep the
196     // actual load.
197     hash_load_check_resize_trigger(float load_min = 0.125,
198                                    float load_max = 0.5);
199
200     void
201     swap(hash_load_check_resize_trigger& other);
202
203     virtual
204     ~hash_load_check_resize_trigger();
205
206     // Returns a pair of the minimal and maximal loads, respectively.
207     inline std::pair<float, float>
208     get_loads() const;
209
210     // Sets the loads through a pair of the minimal and maximal
211     // loads, respectively.
212     void
213     set_loads(std::pair<float, float> load_pair);
214
215   protected:
216     inline void
217     notify_insert_search_start();
218
219     inline void
220     notify_insert_search_collision();
221
222     inline void
223     notify_insert_search_end();
224
225     inline void
226     notify_find_search_start();
227
228     inline void
229     notify_find_search_collision();
230
231     inline void
232     notify_find_search_end();
233
234     inline void
235     notify_erase_search_start();
236
237     inline void
238     notify_erase_search_collision();
239
240     inline void
241     notify_erase_search_end();
242
243     // Notifies an element was inserted. The total number of entries
244     // in the table is num_entries.
245     inline void
246     notify_inserted(size_type num_entries);
247
248     inline void
249     notify_erased(size_type num_entries);
250
251     // Notifies the table was cleared.
252     void
253     notify_cleared();
254
255     // Notifies the table was resized as a result of this object's
256     // signifying that a resize is needed.
257     void
258     notify_resized(size_type new_size);
259
260     void
261     notify_externally_resized(size_type new_size);
262
263     inline bool
264     is_resize_needed() const;
265
266     inline bool
267     is_grow_needed(size_type size, size_type num_entries) const;
268
269   private:
270     virtual void
271     do_resize(size_type new_size);
272
273     typedef PB_DS_SIZE_BASE_C_DEC size_base;
274
275 #ifdef _GLIBCXX_DEBUG
276     void
277     assert_valid() const;
278 #endif 
279
280     float       m_load_min;
281     float       m_load_max;
282     size_type   m_next_shrink_size;
283     size_type   m_next_grow_size;
284     bool        m_resize_needed;
285   };
286
287 #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp>
288
289 #undef PB_DS_CLASS_T_DEC
290 #undef PB_DS_CLASS_C_DEC
291 #undef PB_DS_SIZE_BASE_C_DEC
292
293 #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type>
294 #define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger<External_Load_Access, Size_Type>
295
296   // A resize trigger policy based on collision checks. It keeps the
297   // simulated load factor lower than some given load factor.
298   template<bool External_Load_Access = false, typename Size_Type = size_t>
299   class cc_hash_max_collision_check_resize_trigger
300   {
301   public:
302     typedef Size_Type size_type;
303
304     enum
305       {
306         external_load_access = External_Load_Access
307       };
308
309     // Default constructor, or constructor taking load, a __load
310     // factor which it will attempt to maintain.
311     cc_hash_max_collision_check_resize_trigger(float load = 0.5);
312
313     void
314     swap(PB_DS_CLASS_C_DEC& other);
315
316     // Returns the current load.
317     inline float
318     get_load() const;
319
320     // Sets the load; does not resize the container.
321     void
322     set_load(float load);
323
324   protected:
325     inline void
326     notify_insert_search_start();
327
328     inline void
329     notify_insert_search_collision();
330
331     inline void
332     notify_insert_search_end();
333
334     inline void
335     notify_find_search_start();
336
337     inline void
338     notify_find_search_collision();
339
340     inline void
341     notify_find_search_end();
342
343     inline void
344     notify_erase_search_start();
345
346     inline void
347     notify_erase_search_collision();
348
349     inline void
350     notify_erase_search_end();
351
352     inline void
353     notify_inserted(size_type num_entries);
354
355     inline void
356     notify_erased(size_type num_entries);
357
358     void
359     notify_cleared();
360
361     // Notifies the table was resized as a result of this object's
362     // signifying that a resize is needed.
363     void
364     notify_resized(size_type new_size);
365
366     void
367     notify_externally_resized(size_type new_size);
368
369     inline bool
370     is_resize_needed() const;
371
372     inline bool
373     is_grow_needed(size_type size, size_type num_entries) const;
374
375   private:
376     void
377     calc_max_num_coll();
378
379     inline void
380     calc_resize_needed();
381
382     float       m_load;
383     size_type   m_size;
384     size_type   m_num_col;
385     size_type   m_max_col;
386     bool        m_resize_needed;
387   };
388
389 #include <ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp>
390
391 #undef PB_DS_CLASS_T_DEC
392 #undef PB_DS_CLASS_C_DEC
393
394 #define PB_DS_CLASS_T_DEC template<typename Size_Type>
395 #define PB_DS_CLASS_C_DEC hash_exponential_size_policy<Size_Type>
396
397   // A size policy whose sequence of sizes form an exponential
398   // sequence (typically powers of 2.
399   template<typename Size_Type = size_t>
400   class hash_exponential_size_policy
401   {
402   public:
403     typedef Size_Type size_type;
404
405     // Default constructor, or onstructor taking a start_size, or
406     // constructor taking a start size and grow_factor. The policy
407     // will use the sequence of sizes start_size, start_size*
408     // grow_factor, start_size* grow_factor^2, ...
409     hash_exponential_size_policy(size_type start_size = 8,
410                                  size_type grow_factor = 2);
411
412     void
413     swap(PB_DS_CLASS_C_DEC& other);
414
415   protected:
416     size_type
417     get_nearest_larger_size(size_type size) const;
418
419     size_type
420     get_nearest_smaller_size(size_type size) const;
421
422   private:
423     size_type m_start_size;
424     size_type m_grow_factor;
425   };
426
427 #include <ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp>
428
429 #undef PB_DS_CLASS_T_DEC
430 #undef PB_DS_CLASS_C_DEC
431
432 #define PB_DS_CLASS_T_DEC
433 #define PB_DS_CLASS_C_DEC hash_prime_size_policy
434
435   // A size policy whose sequence of sizes form a nearly-exponential
436   // sequence of primes.
437   class hash_prime_size_policy
438   {
439   public:
440     // Size type.
441     typedef size_t size_type;
442
443     // Default constructor, or onstructor taking a start_size The
444     // policy will use the sequence of sizes approximately
445     // start_size, start_size* 2, start_size* 2^2, ...
446     hash_prime_size_policy(size_type start_size = 8);
447
448     inline void
449     swap(PB_DS_CLASS_C_DEC& other);
450
451   protected:
452     size_type
453     get_nearest_larger_size(size_type size) const;
454
455     size_type
456     get_nearest_smaller_size(size_type size) const;
457
458   private:
459     size_type m_start_size;
460   };
461
462 #include <ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp>
463
464 #undef PB_DS_CLASS_T_DEC
465 #undef PB_DS_CLASS_C_DEC
466
467 #define PB_DS_CLASS_T_DEC template<typename Size_Policy, typename Trigger_Policy, bool External_Size_Access, typename Size_Type>
468
469 #define PB_DS_CLASS_C_DEC hash_standard_resize_policy<Size_Policy, Trigger_Policy, External_Size_Access, Size_Type>
470
471   // A resize policy which delegates operations to size and trigger policies.
472   template<typename Size_Policy = hash_exponential_size_policy<>,
473            typename Trigger_Policy = hash_load_check_resize_trigger<>,
474            bool External_Size_Access = false,
475            typename Size_Type = size_t>
476   class hash_standard_resize_policy 
477   : public Size_Policy, public Trigger_Policy
478   {
479   public:
480     typedef Size_Type           size_type;
481     typedef Trigger_Policy      trigger_policy;
482     typedef Size_Policy         size_policy;
483
484     enum
485       {
486         external_size_access = External_Size_Access
487       };
488
489     // Default constructor.
490     hash_standard_resize_policy();
491
492     // constructor taking some policies r_size_policy will be copied
493     // by the Size_Policy object of this object.
494     hash_standard_resize_policy(const Size_Policy& r_size_policy);
495
496     // constructor taking some policies. r_size_policy will be
497     // copied by the Size_Policy object of this
498     // object. r_trigger_policy will be copied by the Trigger_Policy
499     // object of this object.
500     hash_standard_resize_policy(const Size_Policy& r_size_policy, 
501                                 const Trigger_Policy& r_trigger_policy);
502
503     virtual
504     ~hash_standard_resize_policy();
505
506     inline void
507     swap(PB_DS_CLASS_C_DEC& other);
508
509     // Access to the Size_Policy object used.
510     Size_Policy& 
511     get_size_policy();
512
513     // Const access to the Size_Policy object used.
514     const Size_Policy& 
515     get_size_policy() const;
516
517     // Access to the Trigger_Policy object used.
518     Trigger_Policy& 
519     get_trigger_policy();
520
521     // Access to the Trigger_Policy object used.
522     const Trigger_Policy& 
523     get_trigger_policy() const;
524
525     // Returns the actual size of the container.
526     inline size_type
527     get_actual_size() const;
528
529     // Resizes the container to suggested_new_size, a suggested size
530     // (the actual size will be determined by the Size_Policy
531     // object).
532     void
533     resize(size_type suggested_new_size);
534
535   protected:
536     inline void
537     notify_insert_search_start();
538
539     inline void
540     notify_insert_search_collision();
541
542     inline void
543     notify_insert_search_end();
544
545     inline void
546     notify_find_search_start();
547
548     inline void
549     notify_find_search_collision();
550
551     inline void
552     notify_find_search_end();
553
554     inline void
555     notify_erase_search_start();
556
557     inline void
558     notify_erase_search_collision();
559
560     inline void
561     notify_erase_search_end();
562
563     inline void
564     notify_inserted(size_type num_e);
565
566     inline void
567     notify_erased(size_type num_e);
568
569     void
570     notify_cleared();
571
572     void
573     notify_resized(size_type new_size);
574
575     inline bool
576     is_resize_needed() const;
577
578     // Queries what the new size should be, when the container is
579     // resized naturally. The current __size of the container is
580     // size, and the number of used entries within the container is
581     // num_used_e.
582     size_type
583     get_new_size(size_type size, size_type num_used_e) const;
584
585   private:
586     // Resizes to new_size.
587     virtual void
588     do_resize(size_type new_size);
589
590     typedef Trigger_Policy trigger_policy_base;
591
592     typedef Size_Policy size_policy_base;
593
594     size_type m_size;
595   };
596
597 #include <ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp>
598
599 #undef PB_DS_CLASS_T_DEC
600 #undef PB_DS_CLASS_C_DEC
601
602 } // namespace __gnu_pbds
603
604 #endif