Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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