Ruby  2.4.2p198(2017-09-14revision59899)
st.c
Go to the documentation of this file.
1 /* This is a public domain general purpose hash table package
2  originally written by Peter Moore @ UCB.
3 
4  The hash table data structures were redesigned and the package was
5  rewritten by Vladimir Makarov <vmakarov@redhat.com>. */
6 
7 /* The original package implemented classic bucket-based hash tables
8  with entries doubly linked for an access by their insertion order.
9  To decrease pointer chasing and as a consequence to improve a data
10  locality the current implementation is based on storing entries in
11  an array and using hash tables with open addressing. The current
12  entries are more compact in comparison with the original ones and
13  this also improves the data locality.
14 
15  The hash table has two arrays called *bins* and *entries*.
16 
17  bins:
18  -------
19  | | entries array:
20  |-------| --------------------------------
21  | index | | | entry: | | |
22  |-------| | | | | |
23  | ... | | ... | hash | ... | ... |
24  |-------| | | key | | |
25  | empty | | | record | | |
26  |-------| --------------------------------
27  | ... | ^ ^
28  |-------| |_ entries start |_ entries bound
29  |deleted|
30  -------
31 
32  o The entry array contains table entries in the same order as they
33  were inserted.
34 
35  When the first entry is deleted, a variable containing index of
36  the current first entry (*entries start*) is changed. In all
37  other cases of the deletion, we just mark the entry as deleted by
38  using a reserved hash value.
39 
40  Such organization of the entry storage makes operations of the
41  table shift and the entries traversal very fast.
42 
43  o The bins provide access to the entries by their keys. The
44  key hash is mapped to a bin containing *index* of the
45  corresponding entry in the entry array.
46 
47  The bin array size is always power of two, it makes mapping very
48  fast by using the corresponding lower bits of the hash.
49  Generally it is not a good idea to ignore some part of the hash.
50  But alternative approach is worse. For example, we could use a
51  modulo operation for mapping and a prime number for the size of
52  the bin array. Unfortunately, the modulo operation for big
53  64-bit numbers are extremely slow (it takes more than 100 cycles
54  on modern Intel CPUs).
55 
56  Still other bits of the hash value are used when the mapping
57  results in a collision. In this case we use a secondary hash
58  value which is a result of a function of the collision bin
59  index and the original hash value. The function choice
60  guarantees that we can traverse all bins and finally find the
61  corresponding bin as after several iterations the function
62  becomes a full cycle linear congruential generator because it
63  satisfies requirements of the Hull-Dobell theorem.
64 
65  When an entry is removed from the table besides marking the
66  hash in the corresponding entry described above, we also mark
67  the bin by a special value in order to find entries which had
68  a collision with the removed entries.
69 
70  There are two reserved values for the bins. One denotes an
71  empty bin, another one denotes a bin for a deleted entry.
72 
73  o The length of the bin array is at least two times more than the
74  entry array length. This keeps the table load factor healthy.
75  The trigger of rebuilding the table is always a case when we can
76  not insert an entry anymore at the entries bound. We could
77  change the entries bound too in case of deletion but than we need
78  a special code to count bins with corresponding deleted entries
79  and reset the bin values when there are too many bins
80  corresponding deleted entries
81 
82  Table rebuilding is done by creation of a new entry array and
83  bins of an appropriate size. We also try to reuse the arrays
84  in some cases by compacting the array and removing deleted
85  entries.
86 
87  o To save memory very small tables have no allocated arrays
88  bins. We use a linear search for an access by a key.
89 
90  o To save more memory we use 8-, 16-, 32- and 64- bit indexes in
91  bins depending on the current hash table size.
92 
93  This implementation speeds up the Ruby hash table benchmarks in
94  average by more 40% on Intel Haswell CPU.
95 
96 */
97 
98 #ifdef NOT_RUBY
99 #include "regint.h"
100 #include "st.h"
101 #else
102 #include "internal.h"
103 #endif
104 
105 #include <stdio.h>
106 #ifdef HAVE_STDLIB_H
107 #include <stdlib.h>
108 #endif
109 #include <string.h>
110 #include <assert.h>
111 
112 #ifdef __GNUC__
113 #define PREFETCH(addr, write_p) __builtin_prefetch(addr, write_p)
114 #define EXPECT(expr, val) __builtin_expect(expr, val)
115 #define ATTRIBUTE_UNUSED __attribute__((unused))
116 #else
117 #define PREFETCH(addr, write_p)
118 #define EXPECT(expr, val) (expr)
119 #define ATTRIBUTE_UNUSED
120 #endif
121 
122 #ifdef ST_DEBUG
123 #define st_assert(cond) assert(cond)
124 #else
125 #define st_assert(cond) ((void)(0 && (cond)))
126 #endif
127 
128 /* The type of hashes. */
130 
135 };
136 
137 #define type_numhash st_hashtype_num
139  st_numcmp,
140  st_numhash,
141 };
142 
143 /* extern int strcmp(const char *, const char *); */
145 static const struct st_hash_type type_strhash = {
146  strcmp,
147  strhash,
148 };
149 
151 static const struct st_hash_type type_strcasehash = {
153  strcasehash,
154 };
155 
156 /* Value used to catch uninitialized entries/bins during debugging.
157  There is a possibility for a false alarm, but its probability is
158  extremely small. */
159 #define ST_INIT_VAL 0xafafafafafafafaf
160 #define ST_INIT_VAL_BYTE 0xafa
161 
162 #ifdef RUBY
163 #undef malloc
164 #undef realloc
165 #undef calloc
166 #undef free
167 #define malloc ruby_xmalloc
168 #define calloc ruby_xcalloc
169 #define realloc ruby_xrealloc
170 #define free ruby_xfree
171 #endif
172 
173 #define EQUAL(tab,x,y) ((x) == (y) || (*(tab)->type->compare)((x),(y)) == 0)
174 #define PTR_EQUAL(tab, ptr, hash_val, key) \
175  ((ptr)->hash == (hash_val) && EQUAL((tab), (key), (ptr)->key))
176 
177 /* Features of a table. */
178 struct st_features {
179  /* Power of 2 used for number of allocated entries. */
180  unsigned char entry_power;
181  /* Power of 2 used for number of allocated bins. Depending on the
182  table size, the number of bins is 2-4 times more than the
183  number of entries. */
184  unsigned char bin_power;
185  /* Enumeration of sizes of bins (8-bit, 16-bit etc). */
186  unsigned char size_ind;
187  /* Bins are packed in words of type st_index_t. The following is
188  a size of bins counted by words. */
190 };
191 
192 /* Features of all possible size tables. */
193 #if SIZEOF_ST_INDEX_T == 8
194 #define MAX_POWER2 62
195 static const struct st_features features[] = {
196  {0, 1, 0, 0x0},
197  {1, 2, 0, 0x1},
198  {2, 3, 0, 0x1},
199  {3, 4, 0, 0x2},
200  {4, 5, 0, 0x4},
201  {5, 6, 0, 0x8},
202  {6, 7, 0, 0x10},
203  {7, 8, 0, 0x20},
204  {8, 9, 1, 0x80},
205  {9, 10, 1, 0x100},
206  {10, 11, 1, 0x200},
207  {11, 12, 1, 0x400},
208  {12, 13, 1, 0x800},
209  {13, 14, 1, 0x1000},
210  {14, 15, 1, 0x2000},
211  {15, 16, 1, 0x4000},
212  {16, 17, 2, 0x10000},
213  {17, 18, 2, 0x20000},
214  {18, 19, 2, 0x40000},
215  {19, 20, 2, 0x80000},
216  {20, 21, 2, 0x100000},
217  {21, 22, 2, 0x200000},
218  {22, 23, 2, 0x400000},
219  {23, 24, 2, 0x800000},
220  {24, 25, 2, 0x1000000},
221  {25, 26, 2, 0x2000000},
222  {26, 27, 2, 0x4000000},
223  {27, 28, 2, 0x8000000},
224  {28, 29, 2, 0x10000000},
225  {29, 30, 2, 0x20000000},
226  {30, 31, 2, 0x40000000},
227  {31, 32, 2, 0x80000000},
228  {32, 33, 3, 0x200000000},
229  {33, 34, 3, 0x400000000},
230  {34, 35, 3, 0x800000000},
231  {35, 36, 3, 0x1000000000},
232  {36, 37, 3, 0x2000000000},
233  {37, 38, 3, 0x4000000000},
234  {38, 39, 3, 0x8000000000},
235  {39, 40, 3, 0x10000000000},
236  {40, 41, 3, 0x20000000000},
237  {41, 42, 3, 0x40000000000},
238  {42, 43, 3, 0x80000000000},
239  {43, 44, 3, 0x100000000000},
240  {44, 45, 3, 0x200000000000},
241  {45, 46, 3, 0x400000000000},
242  {46, 47, 3, 0x800000000000},
243  {47, 48, 3, 0x1000000000000},
244  {48, 49, 3, 0x2000000000000},
245  {49, 50, 3, 0x4000000000000},
246  {50, 51, 3, 0x8000000000000},
247  {51, 52, 3, 0x10000000000000},
248  {52, 53, 3, 0x20000000000000},
249  {53, 54, 3, 0x40000000000000},
250  {54, 55, 3, 0x80000000000000},
251  {55, 56, 3, 0x100000000000000},
252  {56, 57, 3, 0x200000000000000},
253  {57, 58, 3, 0x400000000000000},
254  {58, 59, 3, 0x800000000000000},
255  {59, 60, 3, 0x1000000000000000},
256  {60, 61, 3, 0x2000000000000000},
257  {61, 62, 3, 0x4000000000000000},
258  {62, 63, 3, 0x8000000000000000},
259 };
260 
261 #else
262 #define MAX_POWER2 30
263 
264 static const struct st_features features[] = {
265  {0, 1, 0, 0x1},
266  {1, 2, 0, 0x1},
267  {2, 3, 0, 0x2},
268  {3, 4, 0, 0x4},
269  {4, 5, 0, 0x8},
270  {5, 6, 0, 0x10},
271  {6, 7, 0, 0x20},
272  {7, 8, 0, 0x40},
273  {8, 9, 1, 0x100},
274  {9, 10, 1, 0x200},
275  {10, 11, 1, 0x400},
276  {11, 12, 1, 0x800},
277  {12, 13, 1, 0x1000},
278  {13, 14, 1, 0x2000},
279  {14, 15, 1, 0x4000},
280  {15, 16, 1, 0x8000},
281  {16, 17, 2, 0x20000},
282  {17, 18, 2, 0x40000},
283  {18, 19, 2, 0x80000},
284  {19, 20, 2, 0x100000},
285  {20, 21, 2, 0x200000},
286  {21, 22, 2, 0x400000},
287  {22, 23, 2, 0x800000},
288  {23, 24, 2, 0x1000000},
289  {24, 25, 2, 0x2000000},
290  {25, 26, 2, 0x4000000},
291  {26, 27, 2, 0x8000000},
292  {27, 28, 2, 0x10000000},
293  {28, 29, 2, 0x20000000},
294  {29, 30, 2, 0x40000000},
295  {30, 31, 2, 0x80000000},
296 };
297 
298 #endif
299 
300 /* The reserved hash value and its substitution. */
301 #define RESERVED_HASH_VAL (~(st_hash_t) 0)
302 #define RESERVED_HASH_SUBSTITUTION_VAL ((st_hash_t) 0)
303 
304 /* Return hash value of KEY for table TAB. */
305 static inline st_hash_t
307 {
308  st_hash_t hash = (st_hash_t)(tab->type->hash)(key);
309 
310  /* RESERVED_HASH_VAL is used for a deleted entry. Map it into
311  another value. Such mapping should be extremely rare. */
313 }
314 
315 /* Power of 2 defining the minimal number of allocated entries. */
316 #define MINIMAL_POWER2 2
317 
318 #if MINIMAL_POWER2 < 2
319 #error "MINIMAL_POWER2 should be >= 2"
320 #endif
321 
322 /* If the power2 of the allocated `entries` is less than the following
323  value, don't allocate bins and use a linear search. */
324 #define MAX_POWER2_FOR_TABLES_WITHOUT_BINS 4
325 
326 /* Return smallest n >= MINIMAL_POWER2 such 2^n > SIZE. */
327 static int
329 {
330  unsigned int n;
331 
332  for (n = 0; size != 0; n++)
333  size >>= 1;
334  if (n <= MAX_POWER2)
335  return n < MINIMAL_POWER2 ? MINIMAL_POWER2 : n;
336 #ifndef NOT_RUBY
337  /* Ran out of the table entries */
338  rb_raise(rb_eRuntimeError, "st_table too big");
339 #endif
340  /* should raise exception */
341  return -1;
342 }
343 
344 /* Return value of N-th bin in array BINS of table with bins size
345  index S. */
346 static inline st_index_t
347 get_bin(st_index_t *bins, int s, st_index_t n)
348 {
349  return (s == 0 ? ((unsigned char *) bins)[n]
350  : s == 1 ? ((unsigned short *) bins)[n]
351  : s == 2 ? ((unsigned int *) bins)[n]
352  : ((st_index_t *) bins)[n]);
353 }
354 
355 /* Set up N-th bin in array BINS of table with bins size index S to
356  value V. */
357 static inline void
359 {
360  if (s == 0) ((unsigned char *) bins)[n] = (unsigned char) v;
361  else if (s == 1) ((unsigned short *) bins)[n] = (unsigned short) v;
362  else if (s == 2) ((unsigned int *) bins)[n] = (unsigned int) v;
363  else ((st_index_t *) bins)[n] = v;
364 }
365 
366 /* These macros define reserved values for empty table bin and table
367  bin which contains a deleted entry. We will never use such values
368  for an entry index in bins. */
369 #define EMPTY_BIN 0
370 #define DELETED_BIN 1
371 /* Base of a real entry index in the bins. */
372 #define ENTRY_BASE 2
373 
374 /* Mark I-th bin of table TAB as empty, in other words not
375  corresponding to any entry. */
376 #define MARK_BIN_EMPTY(tab, i) (set_bin((tab)->bins, get_size_ind(tab), i, EMPTY_BIN))
377 
378 /* Values used for not found entry and bin with given
379  characteristics. */
380 #define UNDEFINED_ENTRY_IND (~(st_index_t) 0)
381 #define UNDEFINED_BIN_IND (~(st_index_t) 0)
382 
383 /* Mark I-th bin of table TAB as corresponding to a deleted table
384  entry. Update number of entries in the table and number of bins
385  corresponding to deleted entries. */
386 #define MARK_BIN_DELETED(tab, i) \
387  do { \
388  st_assert(i != UNDEFINED_BIN_IND); \
389  st_assert(! IND_EMPTY_OR_DELETED_BIN_P(tab, i)); \
390  set_bin((tab)->bins, get_size_ind(tab), i, DELETED_BIN); \
391  } while (0)
392 
393 /* Macros to check that value B is used empty bins and bins
394  corresponding deleted entries. */
395 #define EMPTY_BIN_P(b) ((b) == EMPTY_BIN)
396 #define DELETED_BIN_P(b) ((b) == DELETED_BIN)
397 #define EMPTY_OR_DELETED_BIN_P(b) ((b) <= DELETED_BIN)
398 
399 /* Macros to check empty bins and bins corresponding to deleted
400  entries. Bins are given by their index I in table TAB. */
401 #define IND_EMPTY_BIN_P(tab, i) (EMPTY_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
402 #define IND_DELETED_BIN_P(tab, i) (DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
403 #define IND_EMPTY_OR_DELETED_BIN_P(tab, i) (EMPTY_OR_DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
404 
405 /* Macros for marking and checking deleted entries given by their
406  pointer E_PTR. */
407 #define MARK_ENTRY_DELETED(e_ptr) ((e_ptr)->hash = RESERVED_HASH_VAL)
408 #define DELETED_ENTRY_P(e_ptr) ((e_ptr)->hash == RESERVED_HASH_VAL)
409 
410 /* Return bin size index of table TAB. */
411 static inline unsigned int
413 {
414  return tab->size_ind;
415 }
416 
417 /* Return the number of allocated bins of table TAB. */
418 static inline st_index_t
420 {
421  return ((st_index_t) 1)<<tab->bin_power;
422 }
423 
424 /* Return mask for a bin index in table TAB. */
425 static inline st_index_t
426 bins_mask(const st_table *tab)
427 {
428  return get_bins_num(tab) - 1;
429 }
430 
431 /* Return the index of table TAB bin corresponding to
432  HASH_VALUE. */
433 static inline st_index_t
434 hash_bin(st_hash_t hash_value, st_table *tab)
435 {
436  return hash_value & bins_mask(tab);
437 }
438 
439 /* Return the number of allocated entries of table TAB. */
440 static inline st_index_t
442 {
443  return ((st_index_t) 1)<<tab->entry_power;
444 }
445 
446 /* Return size of the allocated bins of table TAB. */
447 static inline st_index_t
448 bins_size(const st_table *tab)
449 {
450  return features[tab->entry_power].bins_words * sizeof (st_index_t);
451 }
452 
453 /* Mark all bins of table TAB as empty. */
454 static void
456 {
457  memset(tab->bins, 0, bins_size(tab));
458 }
459 
460 /* Make table TAB empty. */
461 static void
463 {
464  tab->num_entries = 0;
465  tab->entries_start = tab->entries_bound = 0;
466  if (tab->bins != NULL)
467  initialize_bins(tab);
468 }
469 
470 #ifdef ST_DEBUG
471 /* Check the table T consistency. It can be extremely slow. So use
472  it only for debugging. */
473 static void
474 st_check(st_table *tab)
475 {
476  st_index_t d, e, i, n, p;
477 
478  for (p = get_allocated_entries(tab), i = 0; p > 1; i++, p>>=1)
479  ;
480  p = i;
481  assert(p >= MINIMAL_POWER2);
483  && tab->entries_start <= tab->entries_bound);
484  n = 0;
485  return;
486  if (tab->entries_bound != 0)
487  for (i = tab->entries_start; i < tab->entries_bound; i++) {
489  && tab->entries[i].key != ST_INIT_VAL
490  && tab->entries[i].record != ST_INIT_VAL);
491  if (! DELETED_ENTRY_P(&tab->entries[i]))
492  n++;
493  }
494  assert(n == tab->num_entries);
495  if (tab->bins == NULL)
497  else {
499  for (n = d = i = 0; i < get_bins_num(tab); i++) {
500  assert(get_bin(tab->bins, tab->size_ind, i) != ST_INIT_VAL);
501  if (IND_DELETED_BIN_P(tab, i)) {
502  d++;
503  continue;
504  }
505  else if (IND_EMPTY_BIN_P(tab, i))
506  continue;
507  n++;
508  e = get_bin(tab->bins, tab->size_ind, i) - ENTRY_BASE;
509  assert(tab->entries_start <= e && e < tab->entries_bound);
510  assert(! DELETED_ENTRY_P(&tab->entries[e]));
512  && tab->entries[e].key != ST_INIT_VAL
513  && tab->entries[e].record != ST_INIT_VAL);
514  }
515  assert(n == tab->num_entries);
516  assert(n + d < get_bins_num(tab));
517  }
518 }
519 #endif
520 
521 #ifdef HASH_LOG
522 #ifdef HAVE_UNISTD_H
523 #include <unistd.h>
524 #endif
525 static struct {
526  int all, total, num, str, strcase;
527 } collision;
528 
529 /* Flag switching off output of package statistics at the end of
530  program. */
531 static int init_st = 0;
532 
533 /* Output overall number of table searches and collisions into a
534  temporary file. */
535 static void
536 stat_col(void)
537 {
538  char fname[10+sizeof(long)*3];
539  FILE *f;
540  if (!collision.total) return;
541  f = fopen((snprintf(fname, sizeof(fname), "/tmp/col%ld", (long)getpid()), fname), "w");
542  fprintf(f, "collision: %d / %d (%6.2f)\n", collision.all, collision.total,
543  ((double)collision.all / (collision.total)) * 100);
544  fprintf(f, "num: %d, str: %d, strcase: %d\n", collision.num, collision.str, collision.strcase);
545  fclose(f);
546 }
547 #endif
548 
549 /* Create and return table with TYPE which can hold at least SIZE
550  entries. The real number of entries which the table can hold is
551  the nearest power of two for SIZE. */
552 st_table *
554 {
555  st_table *tab;
556  int n;
557 
558 #ifdef HASH_LOG
559 #if HASH_LOG+0 < 0
560  {
561  const char *e = getenv("ST_HASH_LOG");
562  if (!e || !*e) init_st = 1;
563  }
564 #endif
565  if (init_st == 0) {
566  init_st = 1;
567  atexit(stat_col);
568  }
569 #endif
570 
571  n = get_power2(size);
572  tab = (st_table *) malloc(sizeof (st_table));
573  tab->type = type;
574  tab->entry_power = n;
575  tab->bin_power = features[n].bin_power;
576  tab->size_ind = features[n].size_ind;
578  tab->bins = NULL;
579  else
580  tab->bins = (st_index_t *) malloc(bins_size(tab));
582  * sizeof(st_table_entry));
583 #ifdef ST_DEBUG
584  memset(tab->entries, ST_INIT_VAL_BYTE,
585  get_allocated_entries(tab) * sizeof(st_table_entry));
586  if (tab->bins != NULL)
587  memset(tab->bins, ST_INIT_VAL_BYTE, bins_size(tab));
588 #endif
589  make_tab_empty(tab);
590  tab->rebuilds_num = 0;
591 #ifdef ST_DEBUG
592  st_check(tab);
593 #endif
594  return tab;
595 }
596 
597 /* Create and return table with TYPE which can hold a minimal number
598  of entries (see comments for get_power2). */
599 st_table *
600 st_init_table(const struct st_hash_type *type)
601 {
602  return st_init_table_with_size(type, 0);
603 }
604 
605 /* Create and return table which can hold a minimal number of
606  numbers. */
607 st_table *
609 {
610  return st_init_table(&type_numhash);
611 }
612 
613 /* Create and return table which can hold SIZE numbers. */
614 st_table *
616 {
617  return st_init_table_with_size(&type_numhash, size);
618 }
619 
620 /* Create and return table which can hold a minimal number of
621  strings. */
622 st_table *
624 {
625  return st_init_table(&type_strhash);
626 }
627 
628 /* Create and return table which can hold SIZE strings. */
629 st_table *
631 {
632  return st_init_table_with_size(&type_strhash, size);
633 }
634 
635 /* Create and return table which can hold a minimal number of strings
636  whose character case is ignored. */
637 st_table *
639 {
640  return st_init_table(&type_strcasehash);
641 }
642 
643 /* Create and return table which can hold SIZE strings whose character
644  case is ignored. */
645 st_table *
647 {
648  return st_init_table_with_size(&type_strcasehash, size);
649 }
650 
651 /* Make table TAB empty. */
652 void
654 {
655  make_tab_empty(tab);
656  tab->rebuilds_num++;
657 #ifdef ST_DEBUG
658  st_check(tab);
659 #endif
660 }
661 
662 /* Free table TAB space. */
663 void
665 {
666  if (tab->bins != NULL)
667  free(tab->bins);
668  free(tab->entries);
669  free(tab);
670 }
671 
672 /* Return byte size of memory allocted for table TAB. */
673 size_t
674 st_memsize(const st_table *tab)
675 {
676  return(sizeof(st_table)
677  + (tab->bins == NULL ? 0 : bins_size(tab))
678  + get_allocated_entries(tab) * sizeof(st_table_entry));
679 }
680 
681 static st_index_t
683 
684 static st_index_t
686 
687 static st_index_t
689 
690 static st_index_t
692  st_data_t key, st_index_t *bin_ind);
693 
694 #ifdef HASH_LOG
695 static void
696 count_collision(const struct st_hash_type *type)
697 {
698  collision.all++;
699  if (type == &type_numhash) {
700  collision.num++;
701  }
702  else if (type == &type_strhash) {
703  collision.strcase++;
704  }
705  else if (type == &type_strcasehash) {
706  collision.str++;
707  }
708 }
709 
710 #define COLLISION (collision_check ? count_collision(tab->type) : (void)0)
711 #define FOUND_BIN (collision_check ? collision.total++ : (void)0)
712 #define collision_check 0
713 #else
714 #define COLLISION
715 #define FOUND_BIN
716 #endif
717 
718 /* If the number of entries in the table is at least REBUILD_THRESHOLD
719  times less than the entry array length, decrease the table
720  size. */
721 #define REBUILD_THRESHOLD 4
722 
723 #if REBUILD_THRESHOLD < 2
724 #error "REBUILD_THRESHOLD should be >= 2"
725 #endif
726 
727 /* Rebuild table TAB. Rebuilding removes all deleted bins and entries
728  and can change size of the table entries and bins arrays.
729  Rebuilding is implemented by creation of a new table or by
730  compaction of the existing one. */
731 static void
733 {
734  st_index_t i, ni, bound;
735  unsigned int size_ind;
736  st_table *new_tab;
737  st_table_entry *entries, *new_entries;
738  st_table_entry *curr_entry_ptr;
739  st_index_t *bins;
740  st_index_t bin_ind;
741 
742  st_assert(tab != NULL);
743  bound = tab->entries_bound;
744  entries = tab->entries;
745  if ((2 * tab->num_entries <= get_allocated_entries(tab)
747  || tab->num_entries < (1 << MINIMAL_POWER2)) {
748  /* Compaction: */
749  tab->num_entries = 0;
750  if (tab->bins != NULL)
751  initialize_bins(tab);
752  new_tab = tab;
753  new_entries = entries;
754  }
755  else {
756  new_tab = st_init_table_with_size(tab->type,
757  2 * tab->num_entries - 1);
758  new_entries = new_tab->entries;
759  }
760  ni = 0;
761  bins = new_tab->bins;
762  size_ind = get_size_ind(new_tab);
763  for (i = tab->entries_start; i < bound; i++) {
764  curr_entry_ptr = &entries[i];
765  PREFETCH(entries + i + 1, 0);
766  if (EXPECT(DELETED_ENTRY_P(curr_entry_ptr), 0))
767  continue;
768  if (&new_entries[ni] != curr_entry_ptr)
769  new_entries[ni] = *curr_entry_ptr;
770  if (EXPECT(bins != NULL, 1)) {
771  bin_ind = find_table_bin_ind_direct(new_tab, curr_entry_ptr->hash,
772  curr_entry_ptr->key);
773  st_assert(bin_ind != UNDEFINED_BIN_IND
774  && (tab == new_tab || new_tab->rebuilds_num == 0)
775  && IND_EMPTY_BIN_P(new_tab, bin_ind));
776  set_bin(bins, size_ind, bin_ind, ni + ENTRY_BASE);
777  }
778  new_tab->num_entries++;
779  ni++;
780  }
781  if (new_tab != tab) {
782  tab->entry_power = new_tab->entry_power;
783  tab->bin_power = new_tab->bin_power;
784  tab->size_ind = new_tab->size_ind;
785  st_assert (tab->num_entries == ni && new_tab->num_entries == ni);
786  if (tab->bins != NULL)
787  free(tab->bins);
788  tab->bins = new_tab->bins;
789  free(tab->entries);
790  tab->entries = new_tab->entries;
791  free(new_tab);
792  }
793  tab->entries_start = 0;
794  tab->entries_bound = tab->num_entries;
795  tab->rebuilds_num++;
796 #ifdef ST_DEBUG
797  st_check(tab);
798 #endif
799 }
800 
801 /* Return the next secondary hash index for table TAB using previous
802  index IND and PERTERB. Finally modulo of the function becomes a
803  full *cycle linear congruential generator*, in other words it
804  guarantees traversing all table bins in extreme case.
805 
806  According the Hull-Dobell theorem a generator
807  "Xnext = (a*Xprev + c) mod m" is a full cycle generator iff
808  o m and c are relatively prime
809  o a-1 is divisible by all prime factors of m
810  o a-1 is divisible by 4 if m is divisible by 4.
811 
812  For our case a is 5, c is 1, and m is a power of two. */
813 static inline st_index_t
815 {
816  *perterb >>= 11;
817  ind = (ind << 2) + ind + *perterb + 1;
818  return hash_bin(ind, tab);
819 }
820 
821 /* Find an entry with HASH_VALUE and KEY in TABLE using a linear
822  search. Return the index of the found entry in array `entries`.
823  If it is not found, return UNDEFINED_ENTRY_IND. */
824 static inline st_index_t
826 {
827  st_index_t i, bound;
828  st_table_entry *entries;
829 
830  bound = tab->entries_bound;
831  entries = tab->entries;
832  for (i = tab->entries_start; i < bound; i++) {
833  if (PTR_EQUAL(tab, &entries[i], hash_value, key))
834  return i;
835  }
836  return UNDEFINED_ENTRY_IND;
837 }
838 
839 /* Use the quadratic probing. The method has a better data locality
840  but more collisions than the current approach. In average it
841  results in a bit slower search. */
842 /*#define QUADRATIC_PROBE*/
843 
844 /* Return index of entry with HASH_VALUE and KEY in table TAB. If
845  there is no such entry, return UNDEFINED_ENTRY_IND. */
846 static st_index_t
848 {
849  st_index_t ind;
850 #ifdef QUADRATIC_PROBE
851  st_index_t d;
852 #else
853  st_index_t peterb;
854 #endif
855  st_index_t bin;
856  st_table_entry *entries = tab->entries;
857 
858  st_assert(tab != NULL && tab->bins != NULL);
859  ind = hash_bin(hash_value, tab);
860 #ifdef QUADRATIC_PROBE
861  d = 1;
862 #else
863  peterb = hash_value;
864 #endif
865  FOUND_BIN;
866  for (;;) {
867  bin = get_bin(tab->bins, get_size_ind(tab), ind);
868  if (! EMPTY_OR_DELETED_BIN_P(bin)
869  && PTR_EQUAL(tab, &entries[bin - ENTRY_BASE], hash_value, key))
870  break;
871  else if (EMPTY_BIN_P(bin))
872  return UNDEFINED_ENTRY_IND;
873 #ifdef QUADRATIC_PROBE
874  ind = hash_bin(ind + d, tab);
875  d++;
876 #else
877  ind = secondary_hash(ind, tab, &peterb);
878 #endif
879  COLLISION;
880  }
881  return bin;
882 }
883 
884 /* Find and return index of table TAB bin corresponding to an entry
885  with HASH_VALUE and KEY. If there is no such bin, return
886  UNDEFINED_BIN_IND. */
887 static st_index_t
889 {
890  st_index_t ind;
891 #ifdef QUADRATIC_PROBE
892  st_index_t d;
893 #else
894  st_index_t peterb;
895 #endif
896  st_index_t bin;
897  st_table_entry *entries = tab->entries;
898 
899  st_assert(tab != NULL && tab->bins != NULL);
900  ind = hash_bin(hash_value, tab);
901 #ifdef QUADRATIC_PROBE
902  d = 1;
903 #else
904  peterb = hash_value;
905 #endif
906  FOUND_BIN;
907  for (;;) {
908  bin = get_bin(tab->bins, get_size_ind(tab), ind);
909  if (! EMPTY_OR_DELETED_BIN_P(bin)
910  && PTR_EQUAL(tab, &entries[bin - ENTRY_BASE], hash_value, key))
911  break;
912  else if (EMPTY_BIN_P(bin))
913  return UNDEFINED_BIN_IND;
914 #ifdef QUADRATIC_PROBE
915  ind = hash_bin(ind + d, tab);
916  d++;
917 #else
918  ind = secondary_hash(ind, tab, &peterb);
919 #endif
920  COLLISION;
921  }
922  return ind;
923 }
924 
925 /* Find and return index of table TAB bin corresponding to an entry
926  with HASH_VALUE and KEY. The entry should be in the table
927  already. */
928 static st_index_t
930 {
931  st_index_t ind;
932 #ifdef QUADRATIC_PROBE
933  st_index_t d;
934 #else
935  st_index_t peterb;
936 #endif
937  st_index_t bin;
938  st_table_entry *entries = tab->entries;
939 
940  st_assert(tab != NULL && tab->bins != NULL);
941  ind = hash_bin(hash_value, tab);
942 #ifdef QUADRATIC_PROBE
943  d = 1;
944 #else
945  peterb = hash_value;
946 #endif
947  FOUND_BIN;
948  for (;;) {
949  bin = get_bin(tab->bins, get_size_ind(tab), ind);
950  if (EMPTY_OR_DELETED_BIN_P(bin))
951  return ind;
952  st_assert (! PTR_EQUAL(tab, &entries[bin - ENTRY_BASE], hash_value, key));
953 #ifdef QUADRATIC_PROBE
954  ind = hash_bin(ind + d, tab);
955  d++;
956 #else
957  ind = secondary_hash(ind, tab, &peterb);
958 #endif
959  COLLISION;
960  }
961 }
962 
963 /* Return index of table TAB bin for HASH_VALUE and KEY through
964  BIN_IND and the pointed value as the function result. Reserve the
965  bin for inclusion of the corresponding entry into the table if it
966  is not there yet. We always find such bin as bins array length is
967  bigger entries array. Although we can reuse a deleted bin, the
968  result bin value is always empty if the table has no entry with
969  KEY. Return the entries array index of the found entry or
970  UNDEFINED_ENTRY_IND if it is not found. */
971 static st_index_t
973  st_data_t key, st_index_t *bin_ind) {
974  st_index_t ind;
975  st_hash_t curr_hash_value = *hash_value;
976 #ifdef QUADRATIC_PROBE
977  st_index_t d;
978 #else
979  st_index_t peterb;
980 #endif
981  st_index_t entry_index;
982  st_index_t first_deleted_bin_ind;
983  st_table_entry *entries;
984 
985  st_assert(tab != NULL && tab->bins != NULL
986  && tab->entries_bound <= get_allocated_entries(tab)
987  && tab->entries_start <= tab->entries_bound);
988  ind = hash_bin(curr_hash_value, tab);
989 #ifdef QUADRATIC_PROBE
990  d = 1;
991 #else
992  peterb = curr_hash_value;
993 #endif
994  FOUND_BIN;
995  first_deleted_bin_ind = UNDEFINED_BIN_IND;
996  entries = tab->entries;
997  for (;;) {
998  entry_index = get_bin(tab->bins, get_size_ind(tab), ind);
999  if (EMPTY_BIN_P(entry_index)) {
1000  tab->num_entries++;
1001  entry_index = UNDEFINED_ENTRY_IND;
1002  if (first_deleted_bin_ind != UNDEFINED_BIN_IND) {
1003  /* We can reuse bin of a deleted entry. */
1004  ind = first_deleted_bin_ind;
1005  MARK_BIN_EMPTY(tab, ind);
1006  }
1007  break;
1008  } else if (! DELETED_BIN_P(entry_index)) {
1009  if (PTR_EQUAL(tab, &entries[entry_index - ENTRY_BASE], curr_hash_value, key))
1010  break;
1011  } else if (first_deleted_bin_ind == UNDEFINED_BIN_IND)
1012  first_deleted_bin_ind = ind;
1013 #ifdef QUADRATIC_PROBE
1014  ind = hash_bin(ind + d, tab);
1015  d++;
1016 #else
1017  ind = secondary_hash(ind, tab, &peterb);
1018 #endif
1019  COLLISION;
1020  }
1021  *bin_ind = ind;
1022  return entry_index;
1023 }
1024 
1025 /* Find an entry with KEY in table TAB. Return non-zero if we found
1026  it. Set up *RECORD to the found entry record. */
1027 int
1029 {
1030  st_index_t bin;
1031  st_hash_t hash = do_hash(key, tab);
1032 
1033  if (tab->bins == NULL) {
1034  bin = find_entry(tab, hash, key);
1035  if (bin == UNDEFINED_ENTRY_IND)
1036  return 0;
1037  } else {
1038  bin = find_table_entry_ind(tab, hash, key);
1039  if (bin == UNDEFINED_ENTRY_IND)
1040  return 0;
1041  bin -= ENTRY_BASE;
1042  }
1043  if (value != 0)
1044  *value = tab->entries[bin].record;
1045  return 1;
1046 }
1047 
1048 /* Find an entry with KEY in table TAB. Return non-zero if we found
1049  it. Set up *RESULT to the found table entry key. */
1050 int
1052 {
1053  st_index_t bin;
1054  st_hash_t hash = do_hash(key, tab);
1055 
1056  if (tab->bins == NULL) {
1057  bin = find_entry(tab, hash, key);
1058  if (bin == UNDEFINED_ENTRY_IND)
1059  return 0;
1060  } else {
1061  bin = find_table_entry_ind(tab, hash, key);
1062  if (bin == UNDEFINED_ENTRY_IND)
1063  return 0;
1064  bin -= ENTRY_BASE;
1065  }
1066  if (result != 0)
1067  *result = tab->entries[bin].key;
1068  return 1;
1069 }
1070 
1071 /* Check the table and rebuild it if it is necessary. */
1072 static inline void
1074 {
1075  st_index_t bound = tab->entries_bound;
1076 
1077  if (bound == get_allocated_entries(tab))
1078  rebuild_table(tab);
1080 }
1081 
1082 /* Insert (KEY, VALUE) into table TAB and return zero. If there is
1083  already entry with KEY in the table, return nonzero and and update
1084  the value of the found entry. */
1085 int
1087 {
1088  st_table_entry *entry;
1089  st_index_t bin;
1090  st_index_t ind;
1091  st_hash_t hash_value;
1092  st_index_t bin_ind;
1093  int new_p;
1094 
1096  hash_value = do_hash(key, tab);
1097  if (tab->bins == NULL) {
1098  bin = find_entry(tab, hash_value, key);
1099  new_p = bin == UNDEFINED_ENTRY_IND;
1100  if (new_p)
1101  tab->num_entries++;
1102  bin_ind = UNDEFINED_BIN_IND;
1103  } else {
1104  bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
1105  key, &bin_ind);
1106  new_p = bin == UNDEFINED_ENTRY_IND;
1107  bin -= ENTRY_BASE;
1108  }
1109  if (new_p) {
1111  ind = tab->entries_bound++;
1112  entry = &tab->entries[ind];
1113  entry->hash = hash_value;
1114  entry->key = key;
1115  entry->record = value;
1116  if (bin_ind != UNDEFINED_BIN_IND)
1117  set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
1118 #ifdef ST_DEBUG
1119  st_check(tab);
1120 #endif
1121  return 0;
1122  }
1123  tab->entries[bin].record = value;
1124 #ifdef ST_DEBUG
1125  st_check(tab);
1126 #endif
1127  return 1;
1128 }
1129 
1130 /* Insert (KEY, VALUE, HASH) into table TAB. The table should not have
1131  entry with KEY before the insertion. */
1132 static inline void
1134  st_data_t key, st_data_t value, st_hash_t hash) {
1135  st_table_entry *entry;
1136  st_index_t ind;
1137  st_index_t bin_ind;
1138 
1140  ind = tab->entries_bound++;
1141  entry = &tab->entries[ind];
1142  entry->hash = hash;
1143  entry->key = key;
1144  entry->record = value;
1145  tab->num_entries++;
1146  if (tab->bins != NULL) {
1147  bin_ind = find_table_bin_ind_direct(tab, hash, key);
1148  st_assert (bin_ind != UNDEFINED_BIN_IND);
1149  set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
1150  }
1151 #ifdef ST_DEBUG
1152  st_check(tab);
1153 #endif
1154 }
1155 
1156 /* Insert (KEY, VALUE) into table TAB. The table should not have
1157  entry with KEY before the insertion. */
1158 void
1160 {
1161  st_hash_t hash_value;
1162 
1163  hash_value = do_hash(key, tab);
1164  st_add_direct_with_hash(tab, key, value, hash_value);
1165 }
1166 
1167 /* Insert (FUNC(KEY), VALUE) into table TAB and return zero. If
1168  there is already entry with KEY in the table, return nonzero and
1169  and update the value of the found entry. */
1170 int
1172  st_data_t (*func)(st_data_t)) {
1173  st_table_entry *entry;
1174  st_index_t bin;
1175  st_index_t ind, check;
1176  st_hash_t hash_value;
1177  st_index_t bin_ind;
1178  int new_p;
1179 
1181  hash_value = do_hash(key, tab);
1182  if (tab->bins == NULL) {
1183  bin = find_entry(tab, hash_value, key);
1184  new_p = bin == UNDEFINED_ENTRY_IND;
1185  bin_ind = UNDEFINED_BIN_IND;
1186  } else {
1187  bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
1188  key, &bin_ind);
1189  new_p = bin == UNDEFINED_ENTRY_IND;
1190  bin -= ENTRY_BASE;
1191  }
1192  if (new_p) {
1194  check = tab->rebuilds_num;
1195  key = (*func)(key);
1196  st_assert(check == tab->rebuilds_num
1197  && do_hash(key, tab) == hash_value);
1198  ind = tab->entries_bound++;
1199  entry = &tab->entries[ind];
1200  entry->hash = hash_value;
1201  entry->key = key;
1202  entry->record = value;
1203  if (bin_ind != UNDEFINED_BIN_IND)
1204  set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
1205 #ifdef ST_DEBUG
1206  st_check(tab);
1207 #endif
1208  return 0;
1209  }
1210  tab->entries[bin].record = value;
1211 #ifdef ST_DEBUG
1212  st_check(tab);
1213 #endif
1214  return 1;
1215 }
1216 
1217 /* Create and return a copy of table OLD_TAB. */
1218 st_table *
1220 {
1221  st_table *new_tab;
1222 
1223  new_tab = (st_table *) malloc(sizeof(st_table));
1224  *new_tab = *old_tab;
1225  if (old_tab->bins == NULL)
1226  new_tab->bins = NULL;
1227  else
1228  new_tab->bins = (st_index_t *) malloc(bins_size(old_tab));
1229  new_tab->entries = (st_table_entry *) malloc(get_allocated_entries(old_tab)
1230  * sizeof(st_table_entry));
1231  MEMCPY(new_tab->entries, old_tab->entries, st_table_entry,
1232  get_allocated_entries(old_tab));
1233  if (old_tab->bins != NULL)
1234  MEMCPY(new_tab->bins, old_tab->bins, char, bins_size(old_tab));
1235 #ifdef ST_DEBUG
1236  st_check(new_tab);
1237 #endif
1238  return new_tab;
1239 }
1240 
1241 /* Update the entries start of table TAB after removing an entry
1242  with index N in the array entries. */
1243 static inline void
1245 {
1246  /* Do not update entries_bound here. Otherwise, we can fill all
1247  bins by deleted entry value before rebuilding the table. */
1248  if (tab->entries_start == n)
1249  tab->entries_start = n + 1;
1250 }
1251 
1252 /* Delete entry with KEY from table TAB, set up *VALUE (unless
1253  VALUE is zero) from deleted table entry, and return non-zero. If
1254  there is no entry with KEY in the table, clear *VALUE (unless VALUE
1255  is zero), and return zero. */
1256 static int
1258 {
1259  st_table_entry *entry;
1260  st_index_t bin;
1261  st_index_t bin_ind;
1262  st_hash_t hash;
1263 
1264  st_assert(tab != NULL);
1265  hash = do_hash(*key, tab);
1266  if (tab->bins == NULL) {
1267  bin = find_entry(tab, hash, *key);
1268  if (bin == UNDEFINED_ENTRY_IND) {
1269  if (value != 0) *value = 0;
1270  return 0;
1271  }
1272  } else {
1273  bin_ind = find_table_bin_ind(tab, hash, *key);
1274  if (bin_ind == UNDEFINED_BIN_IND) {
1275  if (value != 0) *value = 0;
1276  return 0;
1277  }
1278  bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
1279  MARK_BIN_DELETED(tab, bin_ind);
1280  }
1281  entry = &tab->entries[bin];
1282  *key = entry->key;
1283  if (value != 0) *value = entry->record;
1284  MARK_ENTRY_DELETED(entry);
1285  tab->num_entries--;
1286  update_range_for_deleted(tab, bin);
1287 #ifdef ST_DEBUG
1288  st_check(tab);
1289 #endif
1290  return 1;
1291 }
1292 
1293 int
1295 {
1296  return st_general_delete(tab, key, value);
1297 }
1298 
1299 /* The function and other functions with suffix '_safe' or '_check'
1300  are originated from the previous implementation of the hash tables.
1301  It was necessary for correct deleting entries during traversing
1302  tables. The current implementation permits deletion during
1303  traversing without a specific way to do this. */
1304 int
1306  st_data_t never ATTRIBUTE_UNUSED) {
1307  return st_general_delete(tab, key, value);
1308 }
1309 
1310 /* If table TAB is empty, clear *VALUE (unless VALUE is zero), and
1311  return zero. Otherwise, remove the first entry in the table.
1312  Return its key through KEY and its record through VALUE (unless
1313  VALUE is zero). */
1314 int
1316 {
1317  st_index_t i, bound;
1318  st_index_t bin;
1319  st_table_entry *entries, *curr_entry_ptr;
1320  st_index_t bin_ind;
1321 
1322  entries = tab->entries;
1323  bound = tab->entries_bound;
1324  for (i = tab->entries_start; i < bound; i++) {
1325  curr_entry_ptr = &entries[i];
1326  if (! DELETED_ENTRY_P(curr_entry_ptr)) {
1327  if (value != 0) *value = curr_entry_ptr->record;
1328  *key = curr_entry_ptr->key;
1329  if (tab->bins == NULL) {
1330  bin = find_entry(tab, curr_entry_ptr->hash, curr_entry_ptr->key);
1332  && &entries[bin] == curr_entry_ptr);
1333  } else {
1334  bin_ind = find_table_bin_ind(tab, curr_entry_ptr->hash,
1335  curr_entry_ptr->key);
1336  st_assert(bin_ind != UNDEFINED_BIN_IND
1337  && &entries[get_bin(tab->bins, get_size_ind(tab), bin_ind)
1338  - ENTRY_BASE] == curr_entry_ptr);
1339  MARK_BIN_DELETED(tab, bin_ind);
1340  }
1341  MARK_ENTRY_DELETED(curr_entry_ptr);
1342  tab->num_entries--;
1343  update_range_for_deleted(tab, i);
1344 #ifdef ST_DEBUG
1345  st_check(tab);
1346 #endif
1347  return 1;
1348  }
1349  }
1350  st_assert(tab->num_entries == 0);
1351  tab->entries_start = tab->entries_bound = 0;
1352  if (value != 0) *value = 0;
1353  return 0;
1354 }
1355 
1356 /* See comments for function st_delete_safe. */
1357 void
1359  st_data_t never ATTRIBUTE_UNUSED) {
1360 }
1361 
1362 /* Find entry with KEY in table TAB, call FUNC with the key and the
1363  value of the found entry, and non-zero as the 3rd argument. If the
1364  entry is not found, call FUNC with KEY, and 2 zero arguments. If
1365  the call returns ST_CONTINUE, the table will have an entry with key
1366  and value returned by FUNC through the 1st and 2nd parameters. If
1367  the call of FUNC returns ST_DELETE, the table will not have entry
1368  with KEY. The function returns flag of that the entry with KEY was
1369  in the table before the call. */
1370 int
1373  st_table_entry *entry = NULL; /* to avoid uninitialized value warning */
1374  st_index_t bin = 0; /* Ditto */
1375  st_table_entry *entries;
1376  st_index_t bin_ind;
1377  st_data_t value = 0, old_key;
1378  st_index_t check;
1379  int retval, existing;
1380  st_hash_t hash = do_hash(key, tab);
1381 
1382  entries = tab->entries;
1383  if (tab->bins == NULL) {
1384  bin = find_entry(tab, hash, key);
1385  existing = bin != UNDEFINED_ENTRY_IND;
1386  entry = &entries[bin];
1387  bin_ind = UNDEFINED_BIN_IND;
1388  } else {
1389  bin_ind = find_table_bin_ind(tab, hash, key);
1390  existing = bin_ind != UNDEFINED_BIN_IND;
1391  if (existing) {
1392  bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
1393  entry = &entries[bin];
1394  }
1395  }
1396  if (existing) {
1397  key = entry->key;
1398  value = entry->record;
1399  }
1400  old_key = key;
1401  check = tab->rebuilds_num;
1402  retval = (*func)(&key, &value, arg, existing);
1403  st_assert(check == tab->rebuilds_num);
1404  switch (retval) {
1405  case ST_CONTINUE:
1406  if (! existing) {
1407  st_add_direct_with_hash(tab, key, value, hash);
1408  break;
1409  }
1410  if (old_key != key) {
1411  entry->key = key;
1412  }
1413  entry->record = value;
1414  break;
1415  case ST_DELETE:
1416  if (existing) {
1417  if (bin_ind != UNDEFINED_BIN_IND)
1418  MARK_BIN_DELETED(tab, bin_ind);
1419  MARK_ENTRY_DELETED(entry);
1420  tab->num_entries--;
1421  update_range_for_deleted(tab, bin);
1422 #ifdef ST_DEBUG
1423  st_check(tab);
1424 #endif
1425  }
1426  break;
1427  }
1428 #ifdef ST_DEBUG
1429  st_check(tab);
1430 #endif
1431  return existing;
1432 }
1433 
1434 /* Traverse all entries in table TAB calling FUNC with current entry
1435  key and value and zero. If the call returns ST_STOP, stop
1436  traversing. If the call returns ST_DELETE, delete the current
1437  entry from the table. In case of ST_CHECK or ST_CONTINUE, continue
1438  traversing. The function returns zero unless an error is found.
1439  CHECK_P is flag of st_foreach_check call. The behavior is a bit
1440  different for ST_CHECK and when the current element is removed
1441  during traversing. */
1442 static inline int
1444  int check_p) {
1445  st_index_t bin;
1446  st_index_t bin_ind;
1447  st_table_entry *entries, *curr_entry_ptr;
1448  enum st_retval retval;
1449  st_index_t i, rebuilds_num;
1450  st_hash_t hash;
1451  st_data_t key;
1452  int error_p, packed_p = tab->bins == NULL;
1453 
1454  st_assert(tab->entries_start <= tab->entries_bound);
1455  entries = tab->entries;
1456  /* The bound can change inside the loop even without rebuilding
1457  the table, e.g. by an entry inesrtion. */
1458  for (i = tab->entries_start; i < tab->entries_bound; i++) {
1459  curr_entry_ptr = &entries[i];
1460  if (EXPECT(DELETED_ENTRY_P(curr_entry_ptr), 0))
1461  continue;
1462  key = curr_entry_ptr->key;
1463  rebuilds_num = tab->rebuilds_num;
1464  hash = curr_entry_ptr->hash;
1465  retval = (*func)(key, curr_entry_ptr->record, arg, 0);
1466  if (rebuilds_num != tab->rebuilds_num) {
1467  entries = tab->entries;
1468  packed_p = tab->bins == NULL;
1469  if (packed_p) {
1470  i = find_entry(tab, hash, key);
1471  error_p = i == UNDEFINED_ENTRY_IND;
1472  } else {
1473  i = find_table_entry_ind(tab, hash, key);
1474  error_p = i == UNDEFINED_ENTRY_IND;
1475  i -= ENTRY_BASE;
1476  }
1477  if (error_p && check_p) {
1478  /* call func with error notice */
1479  retval = (*func)(0, 0, arg, 1);
1480 #ifdef ST_DEBUG
1481  st_check(tab);
1482 #endif
1483  return 1;
1484  }
1485  curr_entry_ptr = &entries[i];
1486  }
1487  switch (retval) {
1488  case ST_CONTINUE:
1489  break;
1490  case ST_CHECK:
1491  if (check_p)
1492  break;
1493  case ST_STOP:
1494 #ifdef ST_DEBUG
1495  st_check(tab);
1496 #endif
1497  return 0;
1498  case ST_DELETE:
1499  if (packed_p) {
1500  bin = find_entry(tab, hash, curr_entry_ptr->key);
1501  if (bin == UNDEFINED_ENTRY_IND)
1502  break;
1503  } else {
1504  bin_ind = find_table_bin_ind(tab, hash, curr_entry_ptr->key);
1505  if (bin_ind == UNDEFINED_BIN_IND)
1506  break;
1507  bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
1508  MARK_BIN_DELETED(tab, bin_ind);
1509  }
1510  st_assert(&entries[bin] == curr_entry_ptr);
1511  MARK_ENTRY_DELETED(curr_entry_ptr);
1512  tab->num_entries--;
1513  update_range_for_deleted(tab, bin);
1514 #ifdef ST_DEBUG
1515  st_check(tab);
1516 #endif
1517  break;
1518  }
1519  }
1520 #ifdef ST_DEBUG
1521  st_check(tab);
1522 #endif
1523  return 0;
1524 }
1525 
1526 int
1528 {
1529  return st_general_foreach(tab, func, arg, FALSE);
1530 }
1531 
1532 /* See comments for function st_delete_safe. */
1533 int
1535  st_data_t never ATTRIBUTE_UNUSED) {
1536  return st_general_foreach(tab, func, arg, TRUE);
1537 }
1538 
1539 /* Set up array KEYS by at most SIZE keys of head table TAB entries.
1540  Return the number of keys set up in array KEYS. */
1541 static inline st_index_t
1543 {
1544  st_index_t i, bound;
1545  st_data_t key, *keys_start, *keys_end;
1546  st_table_entry *curr_entry_ptr, *entries = tab->entries;
1547 
1548  bound = tab->entries_bound;
1549  keys_start = keys;
1550  keys_end = keys + size;
1551  for (i = tab->entries_start; i < bound; i++) {
1552  if (keys == keys_end)
1553  break;
1554  curr_entry_ptr = &entries[i];
1555  key = curr_entry_ptr->key;
1556  if (! DELETED_ENTRY_P(curr_entry_ptr))
1557  *keys++ = key;
1558  }
1559 
1560  return keys - keys_start;
1561 }
1562 
1563 st_index_t
1565 {
1566  return st_general_keys(tab, keys, size);
1567 }
1568 
1569 /* See comments for function st_delete_safe. */
1570 st_index_t
1572  st_data_t never ATTRIBUTE_UNUSED) {
1573  return st_general_keys(tab, keys, size);
1574 }
1575 
1576 /* Set up array VALUES by at most SIZE values of head table TAB
1577  entries. Return the number of values set up in array VALUES. */
1578 static inline st_index_t
1580 {
1581  st_index_t i, bound;
1582  st_data_t *values_start, *values_end;
1583  st_table_entry *curr_entry_ptr, *entries = tab->entries;
1584 
1585  values_start = values;
1586  values_end = values + size;
1587  bound = tab->entries_bound;
1588  st_assert(bound != 0);
1589  for (i = tab->entries_start; i < bound; i++) {
1590  if (values == values_end)
1591  break;
1592  curr_entry_ptr = &entries[i];
1593  if (! DELETED_ENTRY_P(curr_entry_ptr))
1594  *values++ = curr_entry_ptr->record;
1595  }
1596 
1597  return values - values_start;
1598 }
1599 
1600 st_index_t
1602 {
1603  return st_general_values(tab, values, size);
1604 }
1605 
1606 /* See comments for function st_delete_safe. */
1607 st_index_t
1609  st_data_t never ATTRIBUTE_UNUSED) {
1610  return st_general_values(tab, values, size);
1611 }
1612 
1613 #define FNV1_32A_INIT 0x811c9dc5
1614 
1615 /*
1616  * 32 bit magic FNV-1a prime
1617  */
1618 #define FNV_32_PRIME 0x01000193
1619 
1620 #ifndef UNALIGNED_WORD_ACCESS
1621 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
1622  defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
1623  defined(__powerpc64__) || \
1624  defined(__mc68020__)
1625 # define UNALIGNED_WORD_ACCESS 1
1626 # endif
1627 #endif
1628 #ifndef UNALIGNED_WORD_ACCESS
1629 # define UNALIGNED_WORD_ACCESS 0
1630 #endif
1631 
1632 /* This hash function is quite simplified MurmurHash3
1633  * Simplification is legal, cause most of magic still happens in finalizator.
1634  * And finalizator is almost the same as in MurmurHash3 */
1635 #define BIG_CONSTANT(x,y) ((st_index_t)(x)<<32|(st_index_t)(y))
1636 #define ROTL(x,n) ((x)<<(n)|(x)>>(SIZEOF_ST_INDEX_T*CHAR_BIT-(n)))
1637 
1638 #if ST_INDEX_BITS <= 32
1639 #define C1 (st_index_t)0xcc9e2d51
1640 #define C2 (st_index_t)0x1b873593
1641 #else
1642 #define C1 BIG_CONSTANT(0x87c37b91,0x114253d5);
1643 #define C2 BIG_CONSTANT(0x4cf5ad43,0x2745937f);
1644 #endif
1645 static inline st_index_t
1647 {
1648 #if ST_INDEX_BITS <= 32
1649 #define r1 (17)
1650 #define r2 (11)
1651 #else
1652 #define r1 (33)
1653 #define r2 (24)
1654 #endif
1655  k *= C1;
1656  h ^= ROTL(k, r1);
1657  h *= C2;
1658  h = ROTL(h, r2);
1659  return h;
1660 }
1661 #undef r1
1662 #undef r2
1663 
1664 static inline st_index_t
1666 {
1667 #if ST_INDEX_BITS <= 32
1668 #define r1 (16)
1669 #define r2 (13)
1670 #define r3 (16)
1671  const st_index_t c1 = 0x85ebca6b;
1672  const st_index_t c2 = 0xc2b2ae35;
1673 #else
1674 /* values are taken from Mix13 on http://zimbry.blogspot.ru/2011/09/better-bit-mixing-improving-on.html */
1675 #define r1 (30)
1676 #define r2 (27)
1677 #define r3 (31)
1678  const st_index_t c1 = BIG_CONSTANT(0xbf58476d,0x1ce4e5b9);
1679  const st_index_t c2 = BIG_CONSTANT(0x94d049bb,0x133111eb);
1680 #endif
1681 #if ST_INDEX_BITS > 64
1682  h ^= h >> 64;
1683  h *= c2;
1684  h ^= h >> 65;
1685 #endif
1686  h ^= h >> r1;
1687  h *= c1;
1688  h ^= h >> r2;
1689  h *= c2;
1690  h ^= h >> r3;
1691  return h;
1692 }
1693 #undef r1
1694 #undef r2
1695 #undef r3
1696 
1697 st_index_t
1698 st_hash(const void *ptr, size_t len, st_index_t h)
1699 {
1700  const char *data = ptr;
1701  st_index_t t = 0;
1702  size_t l = len;
1703 
1704 #define data_at(n) (st_index_t)((unsigned char)data[(n)])
1705 #define UNALIGNED_ADD_4 UNALIGNED_ADD(2); UNALIGNED_ADD(1); UNALIGNED_ADD(0)
1706 #if SIZEOF_ST_INDEX_T > 4
1707 #define UNALIGNED_ADD_8 UNALIGNED_ADD(6); UNALIGNED_ADD(5); UNALIGNED_ADD(4); UNALIGNED_ADD(3); UNALIGNED_ADD_4
1708 #if SIZEOF_ST_INDEX_T > 8
1709 #define UNALIGNED_ADD_16 UNALIGNED_ADD(14); UNALIGNED_ADD(13); UNALIGNED_ADD(12); UNALIGNED_ADD(11); \
1710  UNALIGNED_ADD(10); UNALIGNED_ADD(9); UNALIGNED_ADD(8); UNALIGNED_ADD(7); UNALIGNED_ADD_8
1711 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_16
1712 #endif
1713 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_8
1714 #else
1715 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_4
1716 #endif
1717 #undef SKIP_TAIL
1718  if (len >= sizeof(st_index_t)) {
1719 #if !UNALIGNED_WORD_ACCESS
1720  int align = (int)((st_data_t)data % sizeof(st_index_t));
1721  if (align) {
1722  st_index_t d = 0;
1723  int sl, sr, pack;
1724 
1725  switch (align) {
1726 #ifdef WORDS_BIGENDIAN
1727 # define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \
1728  t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 2)
1729 #else
1730 # define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \
1731  t |= data_at(n) << CHAR_BIT*(n)
1732 #endif
1734 #undef UNALIGNED_ADD
1735  }
1736 
1737 #ifdef WORDS_BIGENDIAN
1738  t >>= (CHAR_BIT * align) - CHAR_BIT;
1739 #else
1740  t <<= (CHAR_BIT * align);
1741 #endif
1742 
1743  data += sizeof(st_index_t)-align;
1744  len -= sizeof(st_index_t)-align;
1745 
1746  sl = CHAR_BIT * (SIZEOF_ST_INDEX_T-align);
1747  sr = CHAR_BIT * align;
1748 
1749  while (len >= sizeof(st_index_t)) {
1750  d = *(st_index_t *)data;
1751 #ifdef WORDS_BIGENDIAN
1752  t = (t << sr) | (d >> sl);
1753 #else
1754  t = (t >> sr) | (d << sl);
1755 #endif
1756  h = murmur_step(h, t);
1757  t = d;
1758  data += sizeof(st_index_t);
1759  len -= sizeof(st_index_t);
1760  }
1761 
1762  pack = len < (size_t)align ? (int)len : align;
1763  d = 0;
1764  switch (pack) {
1765 #ifdef WORDS_BIGENDIAN
1766 # define UNALIGNED_ADD(n) case (n) + 1: \
1767  d |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1)
1768 #else
1769 # define UNALIGNED_ADD(n) case (n) + 1: \
1770  d |= data_at(n) << CHAR_BIT*(n)
1771 #endif
1773 #undef UNALIGNED_ADD
1774  }
1775 #ifdef WORDS_BIGENDIAN
1776  t = (t << sr) | (d >> sl);
1777 #else
1778  t = (t >> sr) | (d << sl);
1779 #endif
1780 
1781  if (len < (size_t)align) goto skip_tail;
1782 # define SKIP_TAIL 1
1783  h = murmur_step(h, t);
1784  data += pack;
1785  len -= pack;
1786  }
1787  else
1788 #endif
1789  {
1790  do {
1791  h = murmur_step(h, *(st_index_t *)data);
1792  data += sizeof(st_index_t);
1793  len -= sizeof(st_index_t);
1794  } while (len >= sizeof(st_index_t));
1795  }
1796  }
1797 
1798  t = 0;
1799  switch (len) {
1800 #if UNALIGNED_WORD_ACCESS && SIZEOF_ST_INDEX_T <= 8 && CHAR_BIT == 8
1801  /* in this case byteorder doesn't really matter */
1802 #if SIZEOF_ST_INDEX_T > 4
1803  case 7: t |= data_at(6) << 48;
1804  case 6: t |= data_at(5) << 40;
1805  case 5: t |= data_at(4) << 32;
1806  case 4:
1807  t |= (st_index_t)*(uint32_t*)data;
1808  goto skip_tail;
1809 # define SKIP_TAIL 1
1810 #endif
1811  case 3: t |= data_at(2) << 16;
1812  case 2: t |= data_at(1) << 8;
1813  case 1: t |= data_at(0);
1814 #else
1815 #ifdef WORDS_BIGENDIAN
1816 # define UNALIGNED_ADD(n) case (n) + 1: \
1817  t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1)
1818 #else
1819 # define UNALIGNED_ADD(n) case (n) + 1: \
1820  t |= data_at(n) << CHAR_BIT*(n)
1821 #endif
1823 #undef UNALIGNED_ADD
1824 #endif
1825 #ifdef SKIP_TAIL
1826  skip_tail:
1827 #endif
1828  h ^= t; h -= ROTL(t, 7);
1829  h *= C2;
1830  }
1831  h ^= l;
1832 
1833  return murmur_finish(h);
1834 }
1835 
1836 st_index_t
1838 {
1839  return murmur_step(h, i);
1840 }
1841 
1842 st_index_t
1844 {
1845  i += h;
1846 /* no matter if it is BigEndian or LittleEndian,
1847  * we hash just integers */
1848 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
1849  h = murmur_step(h, i >> 8*8);
1850 #endif
1851  h = murmur_step(h, i);
1852  return h;
1853 }
1854 
1855 st_index_t
1857 {
1858  h = murmur_finish(h);
1859  return h;
1860 }
1861 
1862 #undef st_hash_start
1863 st_index_t
1865 {
1866  return h;
1867 }
1868 
1869 static st_index_t
1871 {
1872  register const char *string = (const char *)arg;
1873  return st_hash(string, strlen(string), FNV1_32A_INIT);
1874 }
1875 
1876 int
1877 st_locale_insensitive_strcasecmp(const char *s1, const char *s2)
1878 {
1879  unsigned int c1, c2;
1880 
1881  while (1) {
1882  c1 = (unsigned char)*s1++;
1883  c2 = (unsigned char)*s2++;
1884  if (c1 == '\0' || c2 == '\0') {
1885  if (c1 != '\0') return 1;
1886  if (c2 != '\0') return -1;
1887  return 0;
1888  }
1889  if ((unsigned int)(c1 - 'A') <= ('Z' - 'A')) c1 += 'a' - 'A';
1890  if ((unsigned int)(c2 - 'A') <= ('Z' - 'A')) c2 += 'a' - 'A';
1891  if (c1 != c2) {
1892  if (c1 > c2)
1893  return 1;
1894  else
1895  return -1;
1896  }
1897  }
1898 }
1899 
1900 int
1901 st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n)
1902 {
1903  unsigned int c1, c2;
1904 
1905  while (n--) {
1906  c1 = (unsigned char)*s1++;
1907  c2 = (unsigned char)*s2++;
1908  if (c1 == '\0' || c2 == '\0') {
1909  if (c1 != '\0') return 1;
1910  if (c2 != '\0') return -1;
1911  return 0;
1912  }
1913  if ((unsigned int)(c1 - 'A') <= ('Z' - 'A')) c1 += 'a' - 'A';
1914  if ((unsigned int)(c2 - 'A') <= ('Z' - 'A')) c2 += 'a' - 'A';
1915  if (c1 != c2) {
1916  if (c1 > c2)
1917  return 1;
1918  else
1919  return -1;
1920  }
1921  }
1922  return 0;
1923 }
1924 
1926 static st_index_t
1928 {
1929  register const char *string = (const char *)arg;
1930  register st_index_t hval = FNV1_32A_INIT;
1931 
1932  /*
1933  * FNV-1a hash each octet in the buffer
1934  */
1935  while (*string) {
1936  unsigned int c = (unsigned char)*string++;
1937  if ((unsigned int)(c - 'A') <= ('Z' - 'A')) c += 'a' - 'A';
1938  hval ^= c;
1939 
1940  /* multiply by the 32 bit FNV magic prime mod 2^32 */
1941  hval *= FNV_32_PRIME;
1942  }
1943  return hval;
1944 }
1945 
1946 int
1948 {
1949  return x != y;
1950 }
1951 
1952 st_index_t
1954 {
1955  enum {s1 = 11, s2 = 3};
1956  return (st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
1957 }
Definition: st.h:99
int st_insert2(st_table *tab, st_data_t key, st_data_t value, st_data_t(*func)(st_data_t))
Definition: st.c:1171
static st_index_t bins_size(const st_table *tab)
Definition: st.c:448
#define FALSE
Definition: nkf.h:174
#define free
Definition: st.c:170
size_t strlen(const char *)
int st_foreach_check(st_table *tab, int(*func)(ANYARGS), st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1534
Definition: st.h:79
Definition: st.h:99
static int st_general_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1257
st_index_t st_hash_uint32(st_index_t h, uint32_t i)
Definition: st.c:1837
int st_locale_insensitive_strcasecmp(const char *s1, const char *s2)
Definition: st.c:1877
#define IND_DELETED_BIN_P(tab, i)
Definition: st.c:402
static const struct st_features features[]
Definition: st.c:264
#define r1
#define FNV_32_PRIME
Definition: st.c:1618
st_index_t st_numhash(st_data_t n)
Definition: st.c:1953
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1159
Definition: st.h:99
#define RESERVED_HASH_SUBSTITUTION_VAL
Definition: st.c:302
PUREFUNC(static st_index_t strcasehash(st_data_t))
static st_index_t murmur_step(st_index_t h, st_index_t k)
Definition: st.c:1646
static st_index_t get_bins_num(const st_table *tab)
Definition: st.c:419
static st_index_t st_general_keys(st_table *tab, st_data_t *keys, st_index_t size)
Definition: st.c:1542
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:54
#define BIG_CONSTANT(x, y)
Definition: st.c:1635
st_table * st_init_strcasetable_with_size(st_index_t size)
Definition: st.c:646
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1371
#define PTR_EQUAL(tab, ptr, hash_val, key)
Definition: st.c:174
static const struct st_hash_type type_strhash
Definition: st.c:145
static st_index_t bins_mask(const st_table *tab)
Definition: st.c:426
unsigned char size_ind
Definition: st.h:81
st_index_t st_hash_start(st_index_t h)
Definition: st.c:1864
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2207
static void set_bin(st_index_t *bins, int s, st_index_t n, st_index_t v)
Definition: st.c:358
static void initialize_bins(st_table *tab)
Definition: st.c:455
#define r3
static st_index_t get_bin(st_index_t *bins, int s, st_index_t n)
Definition: st.c:347
st_data_t record
Definition: st.c:134
st_data_t st_index_t
Definition: st.h:50
st_table * st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
Definition: st.c:553
st_table * st_init_numtable(void)
Definition: st.c:608
unsigned char entry_power
Definition: st.c:180
#define assert(x)
Definition: dlmalloc.c:1176
static st_hash_t do_hash(st_data_t key, st_table *tab)
Definition: st.c:306
static st_index_t find_entry(st_table *tab, st_hash_t hash_value, st_data_t key)
Definition: st.c:825
#define C2
Definition: st.c:1640
st_index_t bins_words
Definition: st.c:189
#define PREFETCH(addr, write_p)
Definition: st.c:117
st_index_t * bins
Definition: st.h:88
static st_index_t find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
Definition: st.c:847
static st_index_t find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value, st_data_t key, st_index_t *bin_ind)
Definition: st.c:972
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
Definition: st.c:1028
st_table * st_init_strtable_with_size(st_index_t size)
Definition: st.c:630
st_table * st_init_strtable(void)
Definition: st.c:623
void st_free_table(st_table *tab)
Definition: st.c:664
#define SIZEOF_ST_INDEX_T
Definition: st.h:59
static st_index_t secondary_hash(st_index_t ind, st_table *tab, st_index_t *perterb)
Definition: st.c:814
st_table * st_init_strcasetable(void)
Definition: st.c:638
st_index_t st_hash_end(st_index_t h)
Definition: st.c:1856
VALUE rb_eRuntimeError
Definition: error.c:761
static void rebuild_table(st_table *tab)
Definition: st.c:732
size_t st_memsize(const st_table *tab)
Definition: st.c:674
static st_index_t find_table_bin_ind_direct(st_table *table, st_hash_t hash_value, st_data_t key)
Definition: st.c:929
#define UNALIGNED_ADD_ALL
unsigned char size_ind
Definition: st.c:186
Definition: st.c:131
#define FOUND_BIN
Definition: st.c:715
static st_index_t murmur_finish(st_index_t h)
Definition: st.c:1665
#define EXPECT(expr, val)
Definition: st.c:118
#define snprintf
Definition: subst.h:6
#define UNDEFINED_ENTRY_IND
Definition: st.c:380
int st_foreach(st_table *tab, int(*func)(ANYARGS), st_data_t arg)
Definition: st.c:1527
static st_index_t get_allocated_entries(const st_table *tab)
Definition: st.c:441
#define ENTRY_BASE
Definition: st.c:372
register int hval
Definition: zonetab.h:82
#define EMPTY_BIN_P(b)
Definition: st.c:395
static st_index_t strhash(st_data_t)
Definition: st.c:1870
#define RESERVED_HASH_VAL
Definition: st.c:301
#define IND_EMPTY_BIN_P(tab, i)
Definition: st.c:401
st_index_t st_hash_t
Definition: st.c:129
st_index_t st_keys(st_table *tab, st_data_t *keys, st_index_t size)
Definition: st.c:1564
static void make_tab_empty(st_table *tab)
Definition: st.c:462
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1661
st_index_t(* hash)(ANYARGS)
Definition: st.h:63
#define ATTRIBUTE_UNUSED
Definition: st.c:119
#define MAX_POWER2_FOR_TABLES_WITHOUT_BINS
Definition: st.c:324
static st_index_t find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
Definition: st.c:888
#define malloc
Definition: st.c:167
unsigned int rebuilds_num
Definition: st.h:83
st_hash_t hash
Definition: st.c:132
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
Definition: st.c:1698
#define TRUE
Definition: nkf.h:175
#define MINIMAL_POWER2
Definition: st.c:316
st_index_t st_keys_check(st_table *tab, st_data_t *keys, st_index_t size, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1571
static const struct st_hash_type type_strcasehash
Definition: st.c:151
#define MARK_BIN_DELETED(tab, i)
Definition: st.c:386
static void rebuild_table_if_necessary(st_table *tab)
Definition: st.c:1073
#define DELETED_BIN_P(b)
Definition: st.c:396
st_index_t st_values(st_table *tab, st_data_t *values, st_index_t size)
Definition: st.c:1601
static int get_power2(st_index_t size)
Definition: st.c:328
st_index_t entries_bound
Definition: st.h:92
st_retval
Definition: st.h:99
#define MARK_ENTRY_DELETED(e_ptr)
Definition: st.c:407
static VALUE result
Definition: nkf.c:40
#define FNV1_32A_INIT
Definition: st.c:1613
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1294
unsigned char bin_power
Definition: st.h:81
st_data_t key
Definition: st.c:133
static st_index_t hash_bin(st_hash_t hash_value, st_table *tab)
Definition: st.c:434
char bin[32]
Definition: siphash.c:135
#define CHAR_BIT
Definition: ruby.h:196
int st_shift(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1315
#define REBUILD_THRESHOLD
Definition: st.c:721
unsigned int uint32_t
Definition: sha2.h:101
register unsigned int len
Definition: zonetab.h:51
#define getenv(name)
Definition: win32.c:71
unsigned char entry_power
Definition: st.h:81
#define ROTL(x, n)
Definition: st.c:1636
int size
Definition: encoding.c:57
st_table * st_copy(st_table *old_tab)
Definition: st.c:1219
#define f
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1086
#define type_numhash
Definition: st.c:137
static void st_add_direct_with_hash(st_table *tab, st_data_t key, st_data_t value, st_hash_t hash)
Definition: st.c:1133
#define ANYARGS
Definition: defines.h:173
#define st_assert(cond)
Definition: st.c:125
int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: st.c:1901
const struct st_hash_type * type
Definition: st.h:84
Definition: st.h:99
int st_delete_safe(st_table *tab, st_data_t *key, st_data_t *value, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1305
#define ST_INIT_VAL
Definition: st.c:159
static st_index_t st_general_values(st_table *tab, st_data_t *values, st_index_t size)
Definition: st.c:1579
int st_numcmp(st_data_t x, st_data_t y)
Definition: st.c:1947
#define ST_INIT_VAL_BYTE
Definition: st.c:160
st_index_t st_values_check(st_table *tab, st_data_t *values, st_index_t size, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1608
static void update_range_for_deleted(st_table *tab, st_index_t n)
Definition: st.c:1244
void st_clear(st_table *tab)
Definition: st.c:653
#define r2
#define data_at(n)
static unsigned int get_size_ind(const st_table *tab)
Definition: st.c:412
static int st_general_foreach(st_table *tab, int(*func)(ANYARGS), st_data_t arg, int check_p)
Definition: st.c:1443
const struct st_hash_type st_hashtype_num
Definition: st.c:138
#define UNDEFINED_BIN_IND
Definition: st.c:381
struct st_table_entry st_table_entry
Definition: st.h:75
static st_index_t strcasehash(st_data_t)
Definition: st.c:1927
#define MAX_POWER2
Definition: st.c:262
#define C1
Definition: st.c:1639
#define NULL
Definition: _sdbm.c:102
#define MARK_BIN_EMPTY(tab, i)
Definition: st.c:376
st_table_entry * entries
Definition: st.h:94
st_index_t st_hash_uint(st_index_t h, st_index_t i)
Definition: st.c:1843
void st_cleanup_safe(st_table *tab ATTRIBUTE_UNUSED, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1358
st_index_t num_entries
Definition: st.h:86
int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
Definition: st.h:116
#define DELETED_ENTRY_P(e_ptr)
Definition: st.c:408
st_table * st_init_table(const struct st_hash_type *type)
Definition: st.c:600
st_index_t entries_start
Definition: st.h:92
st_table * st_init_numtable_with_size(st_index_t size)
Definition: st.c:615
#define COLLISION
Definition: st.c:714
#define EMPTY_OR_DELETED_BIN_P(b)
Definition: st.c:397
unsigned char bin_power
Definition: st.c:184
int st_get_key(st_table *tab, st_data_t key, st_data_t *result)
Definition: st.c:1051