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