Ruby  2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
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  o The implementation takes into account that the table can be
94  rebuilt during hashing or comparison functions. It can happen if
95  the functions are implemented in Ruby and a thread switch occurs
96  during their execution.
97 
98  This implementation speeds up the Ruby hash table benchmarks in
99  average by more 40% on Intel Haswell CPU.
100 
101 */
102 
103 #ifdef NOT_RUBY
104 #include "regint.h"
105 #include "st.h"
106 #else
107 #include "internal.h"
108 #endif
109 
110 #include <stdio.h>
111 #ifdef HAVE_STDLIB_H
112 #include <stdlib.h>
113 #endif
114 #include <string.h>
115 #include <assert.h>
116 
117 #ifdef __GNUC__
118 #define PREFETCH(addr, write_p) __builtin_prefetch(addr, write_p)
119 #define EXPECT(expr, val) __builtin_expect(expr, val)
120 #define ATTRIBUTE_UNUSED __attribute__((unused))
121 #else
122 #define PREFETCH(addr, write_p)
123 #define EXPECT(expr, val) (expr)
124 #define ATTRIBUTE_UNUSED
125 #endif
126 
127 #ifdef ST_DEBUG
128 #define st_assert assert
129 #else
130 #define st_assert(cond) ((void)(0 && (cond)))
131 #endif
132 
133 /* The type of hashes. */
135 
140 };
141 
142 #define type_numhash st_hashtype_num
143 static const struct st_hash_type st_hashtype_num = {
144  st_numcmp,
145  st_numhash,
146 };
147 
148 static int st_strcmp(st_data_t, st_data_t);
149 static st_index_t strhash(st_data_t);
150 static const struct st_hash_type type_strhash = {
151  st_strcmp,
152  strhash,
153 };
154 
155 static int st_locale_insensitive_strcasecmp_i(st_data_t lhs, st_data_t rhs);
156 static st_index_t strcasehash(st_data_t);
157 static const struct st_hash_type type_strcasehash = {
158  st_locale_insensitive_strcasecmp_i,
159  strcasehash,
160 };
161 
162 /* Value used to catch uninitialized entries/bins during debugging.
163  There is a possibility for a false alarm, but its probability is
164  extremely small. */
165 #define ST_INIT_VAL 0xafafafafafafafaf
166 #define ST_INIT_VAL_BYTE 0xafa
167 
168 #ifdef RUBY
169 #undef malloc
170 #undef realloc
171 #undef calloc
172 #undef free
173 #define malloc ruby_xmalloc
174 #define calloc ruby_xcalloc
175 #define realloc ruby_xrealloc
176 #define free ruby_xfree
177 #endif
178 
179 #define EQUAL(tab,x,y) ((x) == (y) || (*(tab)->type->compare)((x),(y)) == 0)
180 #define PTR_EQUAL(tab, ptr, hash_val, key_) \
181  ((ptr)->hash == (hash_val) && EQUAL((tab), (key_), (ptr)->key))
182 
183 /* As PRT_EQUAL only its result is returned in RES. REBUILT_P is set
184  up to TRUE if the table is rebuilt during the comparison. */
185 #define DO_PTR_EQUAL_CHECK(tab, ptr, hash_val, key, res, rebuilt_p) \
186  do { \
187  unsigned int _old_rebuilds_num = (tab)->rebuilds_num; \
188  res = PTR_EQUAL(tab, ptr, hash_val, key); \
189  rebuilt_p = _old_rebuilds_num != (tab)->rebuilds_num; \
190  } while (FALSE)
191 
192 /* Features of a table. */
193 struct st_features {
194  /* Power of 2 used for number of allocated entries. */
195  unsigned char entry_power;
196  /* Power of 2 used for number of allocated bins. Depending on the
197  table size, the number of bins is 2-4 times more than the
198  number of entries. */
199  unsigned char bin_power;
200  /* Enumeration of sizes of bins (8-bit, 16-bit etc). */
201  unsigned char size_ind;
202  /* Bins are packed in words of type st_index_t. The following is
203  a size of bins counted by words. */
205 };
206 
207 /* Features of all possible size tables. */
208 #if SIZEOF_ST_INDEX_T == 8
209 #define MAX_POWER2 62
210 static const struct st_features features[] = {
211  {0, 1, 0, 0x0},
212  {1, 2, 0, 0x1},
213  {2, 3, 0, 0x1},
214  {3, 4, 0, 0x2},
215  {4, 5, 0, 0x4},
216  {5, 6, 0, 0x8},
217  {6, 7, 0, 0x10},
218  {7, 8, 0, 0x20},
219  {8, 9, 1, 0x80},
220  {9, 10, 1, 0x100},
221  {10, 11, 1, 0x200},
222  {11, 12, 1, 0x400},
223  {12, 13, 1, 0x800},
224  {13, 14, 1, 0x1000},
225  {14, 15, 1, 0x2000},
226  {15, 16, 1, 0x4000},
227  {16, 17, 2, 0x10000},
228  {17, 18, 2, 0x20000},
229  {18, 19, 2, 0x40000},
230  {19, 20, 2, 0x80000},
231  {20, 21, 2, 0x100000},
232  {21, 22, 2, 0x200000},
233  {22, 23, 2, 0x400000},
234  {23, 24, 2, 0x800000},
235  {24, 25, 2, 0x1000000},
236  {25, 26, 2, 0x2000000},
237  {26, 27, 2, 0x4000000},
238  {27, 28, 2, 0x8000000},
239  {28, 29, 2, 0x10000000},
240  {29, 30, 2, 0x20000000},
241  {30, 31, 2, 0x40000000},
242  {31, 32, 2, 0x80000000},
243  {32, 33, 3, 0x200000000},
244  {33, 34, 3, 0x400000000},
245  {34, 35, 3, 0x800000000},
246  {35, 36, 3, 0x1000000000},
247  {36, 37, 3, 0x2000000000},
248  {37, 38, 3, 0x4000000000},
249  {38, 39, 3, 0x8000000000},
250  {39, 40, 3, 0x10000000000},
251  {40, 41, 3, 0x20000000000},
252  {41, 42, 3, 0x40000000000},
253  {42, 43, 3, 0x80000000000},
254  {43, 44, 3, 0x100000000000},
255  {44, 45, 3, 0x200000000000},
256  {45, 46, 3, 0x400000000000},
257  {46, 47, 3, 0x800000000000},
258  {47, 48, 3, 0x1000000000000},
259  {48, 49, 3, 0x2000000000000},
260  {49, 50, 3, 0x4000000000000},
261  {50, 51, 3, 0x8000000000000},
262  {51, 52, 3, 0x10000000000000},
263  {52, 53, 3, 0x20000000000000},
264  {53, 54, 3, 0x40000000000000},
265  {54, 55, 3, 0x80000000000000},
266  {55, 56, 3, 0x100000000000000},
267  {56, 57, 3, 0x200000000000000},
268  {57, 58, 3, 0x400000000000000},
269  {58, 59, 3, 0x800000000000000},
270  {59, 60, 3, 0x1000000000000000},
271  {60, 61, 3, 0x2000000000000000},
272  {61, 62, 3, 0x4000000000000000},
273  {62, 63, 3, 0x8000000000000000},
274 };
275 
276 #else
277 #define MAX_POWER2 30
278 
279 static const struct st_features features[] = {
280  {0, 1, 0, 0x1},
281  {1, 2, 0, 0x1},
282  {2, 3, 0, 0x2},
283  {3, 4, 0, 0x4},
284  {4, 5, 0, 0x8},
285  {5, 6, 0, 0x10},
286  {6, 7, 0, 0x20},
287  {7, 8, 0, 0x40},
288  {8, 9, 1, 0x100},
289  {9, 10, 1, 0x200},
290  {10, 11, 1, 0x400},
291  {11, 12, 1, 0x800},
292  {12, 13, 1, 0x1000},
293  {13, 14, 1, 0x2000},
294  {14, 15, 1, 0x4000},
295  {15, 16, 1, 0x8000},
296  {16, 17, 2, 0x20000},
297  {17, 18, 2, 0x40000},
298  {18, 19, 2, 0x80000},
299  {19, 20, 2, 0x100000},
300  {20, 21, 2, 0x200000},
301  {21, 22, 2, 0x400000},
302  {22, 23, 2, 0x800000},
303  {23, 24, 2, 0x1000000},
304  {24, 25, 2, 0x2000000},
305  {25, 26, 2, 0x4000000},
306  {26, 27, 2, 0x8000000},
307  {27, 28, 2, 0x10000000},
308  {28, 29, 2, 0x20000000},
309  {29, 30, 2, 0x40000000},
310  {30, 31, 2, 0x80000000},
311 };
312 
313 #endif
314 
315 /* The reserved hash value and its substitution. */
316 #define RESERVED_HASH_VAL (~(st_hash_t) 0)
317 #define RESERVED_HASH_SUBSTITUTION_VAL ((st_hash_t) 0)
318 
321 
322 /* Return hash value of KEY for table TAB. */
323 static inline st_hash_t
324 do_hash(st_data_t key, st_table *tab)
325 {
326  st_hash_t hash = (st_hash_t)(tab->type->hash)(key);
327 
328  /* RESERVED_HASH_VAL is used for a deleted entry. Map it into
329  another value. Such mapping should be extremely rare. */
330  return hash == RESERVED_HASH_VAL ? RESERVED_HASH_SUBSTITUTION_VAL : hash;
331 }
332 
333 /* Power of 2 defining the minimal number of allocated entries. */
334 #define MINIMAL_POWER2 2
335 
336 #if MINIMAL_POWER2 < 2
337 #error "MINIMAL_POWER2 should be >= 2"
338 #endif
339 
340 /* If the power2 of the allocated `entries` is less than the following
341  value, don't allocate bins and use a linear search. */
342 #define MAX_POWER2_FOR_TABLES_WITHOUT_BINS 4
343 
344 /* Return smallest n >= MINIMAL_POWER2 such 2^n > SIZE. */
345 static int
346 get_power2(st_index_t size)
347 {
348  unsigned int n = ST_INDEX_BITS - nlz_intptr(size);
349  if (n <= MAX_POWER2)
350  return n < MINIMAL_POWER2 ? MINIMAL_POWER2 : n;
351 #ifndef NOT_RUBY
352  /* Ran out of the table entries */
353  rb_raise(rb_eRuntimeError, "st_table too big");
354 #endif
355  /* should raise exception */
356  return -1;
357 }
358 
359 /* Return value of N-th bin in array BINS of table with bins size
360  index S. */
361 static inline st_index_t
362 get_bin(st_index_t *bins, int s, st_index_t n)
363 {
364  return (s == 0 ? ((unsigned char *) bins)[n]
365  : s == 1 ? ((unsigned short *) bins)[n]
366  : s == 2 ? ((unsigned int *) bins)[n]
367  : ((st_index_t *) bins)[n]);
368 }
369 
370 /* Set up N-th bin in array BINS of table with bins size index S to
371  value V. */
372 static inline void
373 set_bin(st_index_t *bins, int s, st_index_t n, st_index_t v)
374 {
375  if (s == 0) ((unsigned char *) bins)[n] = (unsigned char) v;
376  else if (s == 1) ((unsigned short *) bins)[n] = (unsigned short) v;
377  else if (s == 2) ((unsigned int *) bins)[n] = (unsigned int) v;
378  else ((st_index_t *) bins)[n] = v;
379 }
380 
381 /* These macros define reserved values for empty table bin and table
382  bin which contains a deleted entry. We will never use such values
383  for an entry index in bins. */
384 #define EMPTY_BIN 0
385 #define DELETED_BIN 1
386 /* Base of a real entry index in the bins. */
387 #define ENTRY_BASE 2
388 
389 /* Mark I-th bin of table TAB as empty, in other words not
390  corresponding to any entry. */
391 #define MARK_BIN_EMPTY(tab, i) (set_bin((tab)->bins, get_size_ind(tab), i, EMPTY_BIN))
392 
393 /* Values used for not found entry and bin with given
394  characteristics. */
395 #define UNDEFINED_ENTRY_IND (~(st_index_t) 0)
396 #define UNDEFINED_BIN_IND (~(st_index_t) 0)
397 
398 /* Entry and bin values returned when we found a table rebuild during
399  the search. */
400 #define REBUILT_TABLE_ENTRY_IND (~(st_index_t) 1)
401 #define REBUILT_TABLE_BIN_IND (~(st_index_t) 1)
402 
403 /* Mark I-th bin of table TAB as corresponding to a deleted table
404  entry. Update number of entries in the table and number of bins
405  corresponding to deleted entries. */
406 #define MARK_BIN_DELETED(tab, i) \
407  do { \
408  st_assert(i != UNDEFINED_BIN_IND); \
409  st_assert(! IND_EMPTY_OR_DELETED_BIN_P(tab, i)); \
410  set_bin((tab)->bins, get_size_ind(tab), i, DELETED_BIN); \
411  } while (0)
412 
413 /* Macros to check that value B is used empty bins and bins
414  corresponding deleted entries. */
415 #define EMPTY_BIN_P(b) ((b) == EMPTY_BIN)
416 #define DELETED_BIN_P(b) ((b) == DELETED_BIN)
417 #define EMPTY_OR_DELETED_BIN_P(b) ((b) <= DELETED_BIN)
418 
419 /* Macros to check empty bins and bins corresponding to deleted
420  entries. Bins are given by their index I in table TAB. */
421 #define IND_EMPTY_BIN_P(tab, i) (EMPTY_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
422 #define IND_DELETED_BIN_P(tab, i) (DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
423 #define IND_EMPTY_OR_DELETED_BIN_P(tab, i) (EMPTY_OR_DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
424 
425 /* Macros for marking and checking deleted entries given by their
426  pointer E_PTR. */
427 #define MARK_ENTRY_DELETED(e_ptr) ((e_ptr)->hash = RESERVED_HASH_VAL)
428 #define DELETED_ENTRY_P(e_ptr) ((e_ptr)->hash == RESERVED_HASH_VAL)
429 
430 /* Return bin size index of table TAB. */
431 static inline unsigned int
432 get_size_ind(const st_table *tab)
433 {
434  return tab->size_ind;
435 }
436 
437 /* Return the number of allocated bins of table TAB. */
438 static inline st_index_t
439 get_bins_num(const st_table *tab)
440 {
441  return ((st_index_t) 1)<<tab->bin_power;
442 }
443 
444 /* Return mask for a bin index in table TAB. */
445 static inline st_index_t
446 bins_mask(const st_table *tab)
447 {
448  return get_bins_num(tab) - 1;
449 }
450 
451 /* Return the index of table TAB bin corresponding to
452  HASH_VALUE. */
453 static inline st_index_t
454 hash_bin(st_hash_t hash_value, st_table *tab)
455 {
456  return hash_value & bins_mask(tab);
457 }
458 
459 /* Return the number of allocated entries of table TAB. */
460 static inline st_index_t
461 get_allocated_entries(const st_table *tab)
462 {
463  return ((st_index_t) 1)<<tab->entry_power;
464 }
465 
466 /* Return size of the allocated bins of table TAB. */
467 static inline st_index_t
468 bins_size(const st_table *tab)
469 {
470  return features[tab->entry_power].bins_words * sizeof (st_index_t);
471 }
472 
473 /* Mark all bins of table TAB as empty. */
474 static void
475 initialize_bins(st_table *tab)
476 {
477  memset(tab->bins, 0, bins_size(tab));
478 }
479 
480 /* Make table TAB empty. */
481 static void
482 make_tab_empty(st_table *tab)
483 {
484  tab->num_entries = 0;
485  tab->entries_start = tab->entries_bound = 0;
486  if (tab->bins != NULL)
487  initialize_bins(tab);
488 }
489 
490 #ifdef ST_DEBUG
491 #define st_assert_notinitial(ent) \
492  do { \
493  st_assert(ent.hash != (st_hash_t) ST_INIT_VAL); \
494  st_assert(ent.key != ST_INIT_VAL); \
495  st_assert(ent.record != ST_INIT_VAL); \
496  } while (0)
497 /* Check the table T consistency. It can be extremely slow. So use
498  it only for debugging. */
499 static void
500 st_check(st_table *tab)
501 {
502  st_index_t d, e, i, n, p;
503 
504  for (p = get_allocated_entries(tab), i = 0; p > 1; i++, p>>=1)
505  ;
506  p = i;
508  st_assert(tab->entries_bound <= get_allocated_entries(tab));
509  st_assert(tab->entries_start <= tab->entries_bound);
510  n = 0;
511  return;
512  if (tab->entries_bound != 0)
513  for (i = tab->entries_start; i < tab->entries_bound; i++) {
514  st_assert_notinitial(tab->entries[i]);
515  if (! DELETED_ENTRY_P(&tab->entries[i]))
516  n++;
517  }
518  st_assert(n == tab->num_entries);
519  if (tab->bins == NULL)
521  else {
523  for (n = d = i = 0; i < get_bins_num(tab); i++) {
524  st_assert(get_bin(tab->bins, tab->size_ind, i) != ST_INIT_VAL);
525  if (IND_DELETED_BIN_P(tab, i)) {
526  d++;
527  continue;
528  }
529  else if (IND_EMPTY_BIN_P(tab, i))
530  continue;
531  n++;
532  e = get_bin(tab->bins, tab->size_ind, i) - ENTRY_BASE;
533  st_assert(tab->entries_start <= e && e < tab->entries_bound);
534  st_assert(! DELETED_ENTRY_P(&tab->entries[e]));
535  st_assert_notinitial(tab->entries[e]);
536  }
537  st_assert(n == tab->num_entries);
538  st_assert(n + d < get_bins_num(tab));
539  }
540 }
541 #endif
542 
543 #ifdef HASH_LOG
544 #ifdef HAVE_UNISTD_H
545 #include <unistd.h>
546 #endif
547 static struct {
548  int all, total, num, str, strcase;
549 } collision;
550 
551 /* Flag switching off output of package statistics at the end of
552  program. */
553 static int init_st = 0;
554 
555 /* Output overall number of table searches and collisions into a
556  temporary file. */
557 static void
558 stat_col(void)
559 {
560  char fname[10+sizeof(long)*3];
561  FILE *f;
562  if (!collision.total) return;
563  f = fopen((snprintf(fname, sizeof(fname), "/tmp/col%ld", (long)getpid()), fname), "w");
564  if (f == NULL)
565  return;
566  fprintf(f, "collision: %d / %d (%6.2f)\n", collision.all, collision.total,
567  ((double)collision.all / (collision.total)) * 100);
568  fprintf(f, "num: %d, str: %d, strcase: %d\n", collision.num, collision.str, collision.strcase);
569  fclose(f);
570 }
571 #endif
572 
573 /* Create and return table with TYPE which can hold at least SIZE
574  entries. The real number of entries which the table can hold is
575  the nearest power of two for SIZE. */
576 st_table *
578 {
579  st_table *tab;
580  int n;
581 
582 #ifdef HASH_LOG
583 #if HASH_LOG+0 < 0
584  {
585  const char *e = getenv("ST_HASH_LOG");
586  if (!e || !*e) init_st = 1;
587  }
588 #endif
589  if (init_st == 0) {
590  init_st = 1;
591  atexit(stat_col);
592  }
593 #endif
594 
595  n = get_power2(size);
596 #ifndef RUBY
597  if (n < 0)
598  return NULL;
599 #endif
600  tab = (st_table *) malloc(sizeof (st_table));
601 #ifndef RUBY
602  if (tab == NULL)
603  return NULL;
604 #endif
605  tab->type = type;
606  tab->entry_power = n;
607  tab->bin_power = features[n].bin_power;
608  tab->size_ind = features[n].size_ind;
610  tab->bins = NULL;
611  else {
612  tab->bins = (st_index_t *) malloc(bins_size(tab));
613 #ifndef RUBY
614  if (tab->bins == NULL) {
615  free(tab);
616  return NULL;
617  }
618 #endif
619  }
620  tab->entries = (st_table_entry *) malloc(get_allocated_entries(tab)
621  * sizeof(st_table_entry));
622 #ifndef RUBY
623  if (tab->entries == NULL) {
624  st_free_table(tab);
625  return NULL;
626  }
627 #endif
628 #ifdef ST_DEBUG
630  get_allocated_entries(tab) * sizeof(st_table_entry));
631  if (tab->bins != NULL)
632  memset(tab->bins, ST_INIT_VAL_BYTE, bins_size(tab));
633 #endif
634  make_tab_empty(tab);
635  tab->rebuilds_num = 0;
636 #ifdef ST_DEBUG
637  st_check(tab);
638 #endif
639  return tab;
640 }
641 
642 /* Create and return table with TYPE which can hold a minimal number
643  of entries (see comments for get_power2). */
644 st_table *
646 {
647  return st_init_table_with_size(type, 0);
648 }
649 
650 /* Create and return table which can hold a minimal number of
651  numbers. */
652 st_table *
654 {
655  return st_init_table(&type_numhash);
656 }
657 
658 /* Create and return table which can hold SIZE numbers. */
659 st_table *
661 {
663 }
664 
665 /* Create and return table which can hold a minimal number of
666  strings. */
667 st_table *
669 {
670  return st_init_table(&type_strhash);
671 }
672 
673 /* Create and return table which can hold SIZE strings. */
674 st_table *
676 {
677  return st_init_table_with_size(&type_strhash, size);
678 }
679 
680 /* Create and return table which can hold a minimal number of strings
681  whose character case is ignored. */
682 st_table *
684 {
685  return st_init_table(&type_strcasehash);
686 }
687 
688 /* Create and return table which can hold SIZE strings whose character
689  case is ignored. */
690 st_table *
692 {
693  return st_init_table_with_size(&type_strcasehash, size);
694 }
695 
696 /* Make table TAB empty. */
697 void
699 {
700  make_tab_empty(tab);
701  tab->rebuilds_num++;
702 #ifdef ST_DEBUG
703  st_check(tab);
704 #endif
705 }
706 
707 /* Free table TAB space. */
708 void
710 {
711  if (tab->bins != NULL)
712  free(tab->bins);
713  free(tab->entries);
714  free(tab);
715 }
716 
717 /* Return byte size of memory allocated for table TAB. */
718 size_t
719 st_memsize(const st_table *tab)
720 {
721  return(sizeof(st_table)
722  + (tab->bins == NULL ? 0 : bins_size(tab))
723  + get_allocated_entries(tab) * sizeof(st_table_entry));
724 }
725 
726 static st_index_t
727 find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key);
728 
729 static st_index_t
730 find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key);
731 
732 static st_index_t
733 find_table_bin_ind_direct(st_table *table, st_hash_t hash_value, st_data_t key);
734 
735 static st_index_t
736 find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value,
737  st_data_t key, st_index_t *bin_ind);
738 
739 #ifdef HASH_LOG
740 static void
741 count_collision(const struct st_hash_type *type)
742 {
743  collision.all++;
744  if (type == &type_numhash) {
745  collision.num++;
746  }
747  else if (type == &type_strhash) {
748  collision.strcase++;
749  }
750  else if (type == &type_strcasehash) {
751  collision.str++;
752  }
753 }
754 
755 #define COLLISION (collision_check ? count_collision(tab->type) : (void)0)
756 #define FOUND_BIN (collision_check ? collision.total++ : (void)0)
757 #define collision_check 0
758 #else
759 #define COLLISION
760 #define FOUND_BIN
761 #endif
762 
763 /* If the number of entries in the table is at least REBUILD_THRESHOLD
764  times less than the entry array length, decrease the table
765  size. */
766 #define REBUILD_THRESHOLD 4
767 
768 #if REBUILD_THRESHOLD < 2
769 #error "REBUILD_THRESHOLD should be >= 2"
770 #endif
771 
772 /* Rebuild table TAB. Rebuilding removes all deleted bins and entries
773  and can change size of the table entries and bins arrays.
774  Rebuilding is implemented by creation of a new table or by
775  compaction of the existing one. */
776 static void
777 rebuild_table(st_table *tab)
778 {
779  st_index_t i, ni, bound;
780  unsigned int size_ind;
781  st_table *new_tab;
782  st_table_entry *entries, *new_entries;
783  st_table_entry *curr_entry_ptr;
784  st_index_t *bins;
785  st_index_t bin_ind;
786 
787  st_assert(tab != NULL);
788  bound = tab->entries_bound;
789  entries = tab->entries;
790  if ((2 * tab->num_entries <= get_allocated_entries(tab)
791  && REBUILD_THRESHOLD * tab->num_entries > get_allocated_entries(tab))
792  || tab->num_entries < (1 << MINIMAL_POWER2)) {
793  /* Compaction: */
794  tab->num_entries = 0;
795  if (tab->bins != NULL)
796  initialize_bins(tab);
797  new_tab = tab;
798  new_entries = entries;
799  }
800  else {
801  new_tab = st_init_table_with_size(tab->type,
802  2 * tab->num_entries - 1);
803  new_entries = new_tab->entries;
804  }
805  ni = 0;
806  bins = new_tab->bins;
807  size_ind = get_size_ind(new_tab);
808  for (i = tab->entries_start; i < bound; i++) {
809  curr_entry_ptr = &entries[i];
810  PREFETCH(entries + i + 1, 0);
811  if (EXPECT(DELETED_ENTRY_P(curr_entry_ptr), 0))
812  continue;
813  if (&new_entries[ni] != curr_entry_ptr)
814  new_entries[ni] = *curr_entry_ptr;
815  if (EXPECT(bins != NULL, 1)) {
816  bin_ind = find_table_bin_ind_direct(new_tab, curr_entry_ptr->hash,
817  curr_entry_ptr->key);
818  st_assert(bin_ind != UNDEFINED_BIN_IND);
819  st_assert(tab == new_tab || new_tab->rebuilds_num == 0);
820  st_assert(IND_EMPTY_BIN_P(new_tab, bin_ind));
821  set_bin(bins, size_ind, bin_ind, ni + ENTRY_BASE);
822  }
823  new_tab->num_entries++;
824  ni++;
825  }
826  if (new_tab != tab) {
827  tab->entry_power = new_tab->entry_power;
828  tab->bin_power = new_tab->bin_power;
829  tab->size_ind = new_tab->size_ind;
830  st_assert(tab->num_entries == ni);
831  st_assert(new_tab->num_entries == ni);
832  if (tab->bins != NULL)
833  free(tab->bins);
834  tab->bins = new_tab->bins;
835  free(tab->entries);
836  tab->entries = new_tab->entries;
837  free(new_tab);
838  }
839  tab->entries_start = 0;
840  tab->entries_bound = tab->num_entries;
841  tab->rebuilds_num++;
842 #ifdef ST_DEBUG
843  st_check(tab);
844 #endif
845 }
846 
847 /* Return the next secondary hash index for table TAB using previous
848  index IND and PERTERB. Finally modulo of the function becomes a
849  full *cycle linear congruential generator*, in other words it
850  guarantees traversing all table bins in extreme case.
851 
852  According the Hull-Dobell theorem a generator
853  "Xnext = (a*Xprev + c) mod m" is a full cycle generator iff
854  o m and c are relatively prime
855  o a-1 is divisible by all prime factors of m
856  o a-1 is divisible by 4 if m is divisible by 4.
857 
858  For our case a is 5, c is 1, and m is a power of two. */
859 static inline st_index_t
860 secondary_hash(st_index_t ind, st_table *tab, st_index_t *perterb)
861 {
862  *perterb >>= 11;
863  ind = (ind << 2) + ind + *perterb + 1;
864  return hash_bin(ind, tab);
865 }
866 
867 /* Find an entry with HASH_VALUE and KEY in TABLE using a linear
868  search. Return the index of the found entry in array `entries`.
869  If it is not found, return UNDEFINED_ENTRY_IND. If the table was
870  rebuilt during the search, return REBUILT_TABLE_ENTRY_IND. */
871 static inline st_index_t
872 find_entry(st_table *tab, st_hash_t hash_value, st_data_t key)
873 {
874  int eq_p, rebuilt_p;
875  st_index_t i, bound;
877 
878  bound = tab->entries_bound;
879  entries = tab->entries;
880  for (i = tab->entries_start; i < bound; i++) {
881  DO_PTR_EQUAL_CHECK(tab, &entries[i], hash_value, key, eq_p, rebuilt_p);
882  if (EXPECT(rebuilt_p, 0))
884  if (eq_p)
885  return i;
886  }
887  return UNDEFINED_ENTRY_IND;
888 }
889 
890 /* Use the quadratic probing. The method has a better data locality
891  but more collisions than the current approach. In average it
892  results in a bit slower search. */
893 /*#define QUADRATIC_PROBE*/
894 
895 /* Return index of entry with HASH_VALUE and KEY in table TAB. If
896  there is no such entry, return UNDEFINED_ENTRY_IND. If the table
897  was rebuilt during the search, return REBUILT_TABLE_ENTRY_IND. */
898 static st_index_t
899 find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
900 {
901  int eq_p, rebuilt_p;
902  st_index_t ind;
903 #ifdef QUADRATIC_PROBE
904  st_index_t d;
905 #else
906  st_index_t peterb;
907 #endif
908  st_index_t bin;
910 
911  st_assert(tab != NULL);
912  st_assert(tab->bins != NULL);
913  ind = hash_bin(hash_value, tab);
914 #ifdef QUADRATIC_PROBE
915  d = 1;
916 #else
917  peterb = hash_value;
918 #endif
919  FOUND_BIN;
920  for (;;) {
921  bin = get_bin(tab->bins, get_size_ind(tab), ind);
922  if (! EMPTY_OR_DELETED_BIN_P(bin)) {
923  DO_PTR_EQUAL_CHECK(tab, &entries[bin - ENTRY_BASE], hash_value, key, eq_p, rebuilt_p);
924  if (EXPECT(rebuilt_p, 0))
926  if (eq_p)
927  break;
928  } else if (EMPTY_BIN_P(bin))
929  return UNDEFINED_ENTRY_IND;
930 #ifdef QUADRATIC_PROBE
931  ind = hash_bin(ind + d, tab);
932  d++;
933 #else
934  ind = secondary_hash(ind, tab, &peterb);
935 #endif
936  COLLISION;
937  }
938  return bin;
939 }
940 
941 /* Find and return index of table TAB bin corresponding to an entry
942  with HASH_VALUE and KEY. If there is no such bin, return
943  UNDEFINED_BIN_IND. If the table was rebuilt during the search,
944  return REBUILT_TABLE_BIN_IND. */
945 static st_index_t
946 find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
947 {
948  int eq_p, rebuilt_p;
949  st_index_t ind;
950 #ifdef QUADRATIC_PROBE
951  st_index_t d;
952 #else
953  st_index_t peterb;
954 #endif
955  st_index_t bin;
957 
958  st_assert(tab != NULL);
959  st_assert(tab->bins != NULL);
960  ind = hash_bin(hash_value, tab);
961 #ifdef QUADRATIC_PROBE
962  d = 1;
963 #else
964  peterb = hash_value;
965 #endif
966  FOUND_BIN;
967  for (;;) {
968  bin = get_bin(tab->bins, get_size_ind(tab), ind);
969  if (! EMPTY_OR_DELETED_BIN_P(bin)) {
970  DO_PTR_EQUAL_CHECK(tab, &entries[bin - ENTRY_BASE], hash_value, key, eq_p, rebuilt_p);
971  if (EXPECT(rebuilt_p, 0))
972  return REBUILT_TABLE_BIN_IND;
973  if (eq_p)
974  break;
975  } else if (EMPTY_BIN_P(bin))
976  return UNDEFINED_BIN_IND;
977 #ifdef QUADRATIC_PROBE
978  ind = hash_bin(ind + d, tab);
979  d++;
980 #else
981  ind = secondary_hash(ind, tab, &peterb);
982 #endif
983  COLLISION;
984  }
985  return ind;
986 }
987 
988 /* Find and return index of table TAB bin corresponding to an entry
989  with HASH_VALUE and KEY. The entry should be in the table
990  already. */
991 static st_index_t
992 find_table_bin_ind_direct(st_table *tab, st_hash_t hash_value, st_data_t key)
993 {
994  st_index_t ind;
995 #ifdef QUADRATIC_PROBE
996  st_index_t d;
997 #else
998  st_index_t peterb;
999 #endif
1000  st_index_t bin;
1001  st_table_entry *entries = tab->entries;
1002 
1003  st_assert(tab != NULL);
1004  st_assert(tab->bins != NULL);
1005  ind = hash_bin(hash_value, tab);
1006 #ifdef QUADRATIC_PROBE
1007  d = 1;
1008 #else
1009  peterb = hash_value;
1010 #endif
1011  FOUND_BIN;
1012  for (;;) {
1013  bin = get_bin(tab->bins, get_size_ind(tab), ind);
1015  return ind;
1016  st_assert (entries[bin - ENTRY_BASE].hash != hash_value);
1017 #ifdef QUADRATIC_PROBE
1018  ind = hash_bin(ind + d, tab);
1019  d++;
1020 #else
1021  ind = secondary_hash(ind, tab, &peterb);
1022 #endif
1023  COLLISION;
1024  }
1025 }
1026 
1027 /* Return index of table TAB bin for HASH_VALUE and KEY through
1028  BIN_IND and the pointed value as the function result. Reserve the
1029  bin for inclusion of the corresponding entry into the table if it
1030  is not there yet. We always find such bin as bins array length is
1031  bigger entries array. Although we can reuse a deleted bin, the
1032  result bin value is always empty if the table has no entry with
1033  KEY. Return the entries array index of the found entry or
1034  UNDEFINED_ENTRY_IND if it is not found. If the table was rebuilt
1035  during the search, return REBUILT_TABLE_ENTRY_IND. */
1036 static st_index_t
1037 find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value,
1038  st_data_t key, st_index_t *bin_ind)
1039 {
1040  int eq_p, rebuilt_p;
1041  st_index_t ind;
1042  st_hash_t curr_hash_value = *hash_value;
1043 #ifdef QUADRATIC_PROBE
1044  st_index_t d;
1045 #else
1046  st_index_t peterb;
1047 #endif
1048  st_index_t entry_index;
1049  st_index_t first_deleted_bin_ind;
1051 
1052  st_assert(tab != NULL);
1053  st_assert(tab->bins != NULL);
1054  st_assert(tab->entries_bound <= get_allocated_entries(tab));
1055  st_assert(tab->entries_start <= tab->entries_bound);
1056  ind = hash_bin(curr_hash_value, tab);
1057 #ifdef QUADRATIC_PROBE
1058  d = 1;
1059 #else
1060  peterb = curr_hash_value;
1061 #endif
1062  FOUND_BIN;
1063  first_deleted_bin_ind = UNDEFINED_BIN_IND;
1064  entries = tab->entries;
1065  for (;;) {
1066  entry_index = get_bin(tab->bins, get_size_ind(tab), ind);
1067  if (EMPTY_BIN_P(entry_index)) {
1068  tab->num_entries++;
1069  entry_index = UNDEFINED_ENTRY_IND;
1070  if (first_deleted_bin_ind != UNDEFINED_BIN_IND) {
1071  /* We can reuse bin of a deleted entry. */
1072  ind = first_deleted_bin_ind;
1073  MARK_BIN_EMPTY(tab, ind);
1074  }
1075  break;
1076  }
1077  else if (! DELETED_BIN_P(entry_index)) {
1078  DO_PTR_EQUAL_CHECK(tab, &entries[entry_index - ENTRY_BASE], curr_hash_value, key, eq_p, rebuilt_p);
1079  if (EXPECT(rebuilt_p, 0))
1080  return REBUILT_TABLE_ENTRY_IND;
1081  if (eq_p)
1082  break;
1083  }
1084  else if (first_deleted_bin_ind == UNDEFINED_BIN_IND)
1085  first_deleted_bin_ind = ind;
1086 #ifdef QUADRATIC_PROBE
1087  ind = hash_bin(ind + d, tab);
1088  d++;
1089 #else
1090  ind = secondary_hash(ind, tab, &peterb);
1091 #endif
1092  COLLISION;
1093  }
1094  *bin_ind = ind;
1095  return entry_index;
1096 }
1097 
1098 /* Find an entry with KEY in table TAB. Return non-zero if we found
1099  it. Set up *RECORD to the found entry record. */
1100 int
1102 {
1103  st_index_t bin;
1104  st_hash_t hash = do_hash(key, tab);
1105 
1106  retry:
1107  if (tab->bins == NULL) {
1108  bin = find_entry(tab, hash, key);
1109  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1110  goto retry;
1111  if (bin == UNDEFINED_ENTRY_IND)
1112  return 0;
1113  }
1114  else {
1115  bin = find_table_entry_ind(tab, hash, key);
1116  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1117  goto retry;
1118  if (bin == UNDEFINED_ENTRY_IND)
1119  return 0;
1120  bin -= ENTRY_BASE;
1121  }
1122  if (value != 0)
1123  *value = tab->entries[bin].record;
1124  return 1;
1125 }
1126 
1127 /* Find an entry with KEY in table TAB. Return non-zero if we found
1128  it. Set up *RESULT to the found table entry key. */
1129 int
1131 {
1132  st_index_t bin;
1133  st_hash_t hash = do_hash(key, tab);
1134 
1135  retry:
1136  if (tab->bins == NULL) {
1137  bin = find_entry(tab, hash, key);
1138  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1139  goto retry;
1140  if (bin == UNDEFINED_ENTRY_IND)
1141  return 0;
1142  }
1143  else {
1144  bin = find_table_entry_ind(tab, hash, key);
1145  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1146  goto retry;
1147  if (bin == UNDEFINED_ENTRY_IND)
1148  return 0;
1149  bin -= ENTRY_BASE;
1150  }
1151  if (result != 0)
1152  *result = tab->entries[bin].key;
1153  return 1;
1154 }
1155 
1156 /* Check the table and rebuild it if it is necessary. */
1157 static inline void
1158 rebuild_table_if_necessary (st_table *tab)
1159 {
1160  st_index_t bound = tab->entries_bound;
1161 
1162  if (bound == get_allocated_entries(tab))
1163  rebuild_table(tab);
1164  st_assert(tab->entries_bound < get_allocated_entries(tab));
1165 }
1166 
1167 /* Insert (KEY, VALUE) into table TAB and return zero. If there is
1168  already entry with KEY in the table, return nonzero and and update
1169  the value of the found entry. */
1170 int
1172 {
1173  st_table_entry *entry;
1174  st_index_t bin;
1175  st_index_t ind;
1176  st_hash_t hash_value;
1177  st_index_t bin_ind;
1178  int new_p;
1179 
1180  hash_value = do_hash(key, tab);
1181  retry:
1182  rebuild_table_if_necessary(tab);
1183  if (tab->bins == NULL) {
1184  bin = find_entry(tab, hash_value, key);
1185  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1186  goto retry;
1187  new_p = bin == UNDEFINED_ENTRY_IND;
1188  if (new_p)
1189  tab->num_entries++;
1190  bin_ind = UNDEFINED_BIN_IND;
1191  }
1192  else {
1193  bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
1194  key, &bin_ind);
1195  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1196  goto retry;
1197  new_p = bin == UNDEFINED_ENTRY_IND;
1198  bin -= ENTRY_BASE;
1199  }
1200  if (new_p) {
1201  st_assert(tab->entries_bound < get_allocated_entries(tab));
1202  ind = tab->entries_bound++;
1203  entry = &tab->entries[ind];
1204  entry->hash = hash_value;
1205  entry->key = key;
1206  entry->record = value;
1207  if (bin_ind != UNDEFINED_BIN_IND)
1208  set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
1209 #ifdef ST_DEBUG
1210  st_check(tab);
1211 #endif
1212  return 0;
1213  }
1214  tab->entries[bin].record = value;
1215 #ifdef ST_DEBUG
1216  st_check(tab);
1217 #endif
1218  return 1;
1219 }
1220 
1221 /* Insert (KEY, VALUE, HASH) into table TAB. The table should not have
1222  entry with KEY before the insertion. */
1223 static inline void
1224 st_add_direct_with_hash(st_table *tab,
1225  st_data_t key, st_data_t value, st_hash_t hash)
1226 {
1227  st_table_entry *entry;
1228  st_index_t ind;
1229  st_index_t bin_ind;
1230 
1231  rebuild_table_if_necessary(tab);
1232  ind = tab->entries_bound++;
1233  entry = &tab->entries[ind];
1234  entry->hash = hash;
1235  entry->key = key;
1236  entry->record = value;
1237  tab->num_entries++;
1238  if (tab->bins != NULL) {
1239  bin_ind = find_table_bin_ind_direct(tab, hash, key);
1240  st_assert (bin_ind != UNDEFINED_BIN_IND);
1241  set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
1242  }
1243 #ifdef ST_DEBUG
1244  st_check(tab);
1245 #endif
1246 }
1247 
1248 /* Insert (KEY, VALUE) into table TAB. The table should not have
1249  entry with KEY before the insertion. */
1250 void
1252 {
1253  st_hash_t hash_value;
1254 
1255  hash_value = do_hash(key, tab);
1256  st_add_direct_with_hash(tab, key, value, hash_value);
1257 }
1258 
1259 /* Insert (FUNC(KEY), VALUE) into table TAB and return zero. If
1260  there is already entry with KEY in the table, return nonzero and
1261  and update the value of the found entry. */
1262 int
1264  st_data_t (*func)(st_data_t))
1265 {
1266  st_table_entry *entry;
1267  st_index_t bin;
1268  st_index_t ind, check;
1269  st_hash_t hash_value;
1270  st_index_t bin_ind;
1271  int new_p;
1272 
1273  hash_value = do_hash(key, tab);
1274  retry:
1275  rebuild_table_if_necessary (tab);
1276  if (tab->bins == NULL) {
1277  bin = find_entry(tab, hash_value, key);
1278  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1279  goto retry;
1280  new_p = bin == UNDEFINED_ENTRY_IND;
1281  if (new_p)
1282  tab->num_entries++;
1283  bin_ind = UNDEFINED_BIN_IND;
1284  }
1285  else {
1286  bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
1287  key, &bin_ind);
1288  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1289  goto retry;
1290  new_p = bin == UNDEFINED_ENTRY_IND;
1291  bin -= ENTRY_BASE;
1292  }
1293  if (new_p) {
1294  st_assert(tab->entries_bound < get_allocated_entries(tab));
1295  check = tab->rebuilds_num;
1296  key = (*func)(key);
1297  st_assert(check == tab->rebuilds_num);
1298  ind = tab->entries_bound++;
1299  entry = &tab->entries[ind];
1300  entry->hash = hash_value;
1301  entry->key = key;
1302  entry->record = value;
1303  if (bin_ind != UNDEFINED_BIN_IND)
1304  set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
1305  st_assert(do_hash(key, tab) == hash_value);
1306 #ifdef ST_DEBUG
1307  st_check(tab);
1308 #endif
1309  return 0;
1310  }
1311  tab->entries[bin].record = value;
1312 #ifdef ST_DEBUG
1313  st_check(tab);
1314 #endif
1315  return 1;
1316 }
1317 
1318 /* Create and return a copy of table OLD_TAB. */
1319 st_table *
1321 {
1322  st_table *new_tab;
1323 
1324  new_tab = (st_table *) malloc(sizeof(st_table));
1325 #ifndef RUBY
1326  if (new_tab == NULL)
1327  return NULL;
1328 #endif
1329  *new_tab = *old_tab;
1330  if (old_tab->bins == NULL)
1331  new_tab->bins = NULL;
1332  else {
1333  new_tab->bins = (st_index_t *) malloc(bins_size(old_tab));
1334 #ifndef RUBY
1335  if (new_tab->bins == NULL) {
1336  free(new_tab);
1337  return NULL;
1338  }
1339 #endif
1340  }
1341  new_tab->entries = (st_table_entry *) malloc(get_allocated_entries(old_tab)
1342  * sizeof(st_table_entry));
1343 #ifndef RUBY
1344  if (new_tab->entries == NULL) {
1345  st_free_table(new_tab);
1346  return NULL;
1347  }
1348 #endif
1349  MEMCPY(new_tab->entries, old_tab->entries, st_table_entry,
1350  get_allocated_entries(old_tab));
1351  if (old_tab->bins != NULL)
1352  MEMCPY(new_tab->bins, old_tab->bins, char, bins_size(old_tab));
1353 #ifdef ST_DEBUG
1354  st_check(new_tab);
1355 #endif
1356  return new_tab;
1357 }
1358 
1359 /* Update the entries start of table TAB after removing an entry
1360  with index N in the array entries. */
1361 static inline void
1362 update_range_for_deleted(st_table *tab, st_index_t n)
1363 {
1364  /* Do not update entries_bound here. Otherwise, we can fill all
1365  bins by deleted entry value before rebuilding the table. */
1366  if (tab->entries_start == n)
1367  tab->entries_start = n + 1;
1368 }
1369 
1370 /* Delete entry with KEY from table TAB, set up *VALUE (unless
1371  VALUE is zero) from deleted table entry, and return non-zero. If
1372  there is no entry with KEY in the table, clear *VALUE (unless VALUE
1373  is zero), and return zero. */
1374 static int
1375 st_general_delete(st_table *tab, st_data_t *key, st_data_t *value)
1376 {
1377  st_table_entry *entry;
1378  st_index_t bin;
1379  st_index_t bin_ind;
1380  st_hash_t hash;
1381 
1382  st_assert(tab != NULL);
1383  hash = do_hash(*key, tab);
1384  retry:
1385  if (tab->bins == NULL) {
1386  bin = find_entry(tab, hash, *key);
1387  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1388  goto retry;
1389  if (bin == UNDEFINED_ENTRY_IND) {
1390  if (value != 0) *value = 0;
1391  return 0;
1392  }
1393  }
1394  else {
1395  bin_ind = find_table_bin_ind(tab, hash, *key);
1396  if (EXPECT(bin_ind == REBUILT_TABLE_BIN_IND, 0))
1397  goto retry;
1398  if (bin_ind == UNDEFINED_BIN_IND) {
1399  if (value != 0) *value = 0;
1400  return 0;
1401  }
1402  bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
1403  MARK_BIN_DELETED(tab, bin_ind);
1404  }
1405  entry = &tab->entries[bin];
1406  *key = entry->key;
1407  if (value != 0) *value = entry->record;
1408  MARK_ENTRY_DELETED(entry);
1409  tab->num_entries--;
1410  update_range_for_deleted(tab, bin);
1411 #ifdef ST_DEBUG
1412  st_check(tab);
1413 #endif
1414  return 1;
1415 }
1416 
1417 int
1419 {
1420  return st_general_delete(tab, key, value);
1421 }
1422 
1423 /* The function and other functions with suffix '_safe' or '_check'
1424  are originated from the previous implementation of the hash tables.
1425  It was necessary for correct deleting entries during traversing
1426  tables. The current implementation permits deletion during
1427  traversing without a specific way to do this. */
1428 int
1431 {
1432  return st_general_delete(tab, key, value);
1433 }
1434 
1435 /* If table TAB is empty, clear *VALUE (unless VALUE is zero), and
1436  return zero. Otherwise, remove the first entry in the table.
1437  Return its key through KEY and its record through VALUE (unless
1438  VALUE is zero). */
1439 int
1441 {
1442  st_index_t i, bound;
1443  st_index_t bin;
1444  st_table_entry *entries, *curr_entry_ptr;
1445  st_index_t bin_ind;
1446 
1447  entries = tab->entries;
1448  bound = tab->entries_bound;
1449  for (i = tab->entries_start; i < bound; i++) {
1450  curr_entry_ptr = &entries[i];
1451  if (! DELETED_ENTRY_P(curr_entry_ptr)) {
1452  st_hash_t entry_hash = curr_entry_ptr->hash;
1453  st_data_t entry_key = curr_entry_ptr->key;
1454 
1455  if (value != 0) *value = curr_entry_ptr->record;
1456  *key = entry_key;
1457  retry:
1458  if (tab->bins == NULL) {
1459  bin = find_entry(tab, entry_hash, entry_key);
1460  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0)) {
1461  entries = tab->entries;
1462  goto retry;
1463  }
1465  curr_entry_ptr = &entries[bin];
1466  }
1467  else {
1468  bin_ind = find_table_bin_ind(tab, entry_hash, entry_key);
1469  if (EXPECT(bin_ind == REBUILT_TABLE_BIN_IND, 0)) {
1470  entries = tab->entries;
1471  goto retry;
1472  }
1473  st_assert(bin_ind != UNDEFINED_BIN_IND);
1474  curr_entry_ptr = &entries[get_bin(tab->bins, get_size_ind(tab), bin_ind)
1475  - ENTRY_BASE];
1476  MARK_BIN_DELETED(tab, bin_ind);
1477  }
1478  st_assert(entry_hash != curr_entry_ptr->hash && entry_key == curr_entry_ptr->key);
1479  MARK_ENTRY_DELETED(curr_entry_ptr);
1480  tab->num_entries--;
1481  update_range_for_deleted(tab, i);
1482 #ifdef ST_DEBUG
1483  st_check(tab);
1484 #endif
1485  return 1;
1486  }
1487  }
1488  st_assert(tab->num_entries == 0);
1489  tab->entries_start = tab->entries_bound = 0;
1490  if (value != 0) *value = 0;
1491  return 0;
1492 }
1493 
1494 /* See comments for function st_delete_safe. */
1495 void
1498 {
1499 }
1500 
1501 /* Find entry with KEY in table TAB, call FUNC with the key and the
1502  value of the found entry, and non-zero as the 3rd argument. If the
1503  entry is not found, call FUNC with KEY, and 2 zero arguments. If
1504  the call returns ST_CONTINUE, the table will have an entry with key
1505  and value returned by FUNC through the 1st and 2nd parameters. If
1506  the call of FUNC returns ST_DELETE, the table will not have entry
1507  with KEY. The function returns flag of that the entry with KEY was
1508  in the table before the call. */
1509 int
1512 {
1513  st_table_entry *entry = NULL; /* to avoid uninitialized value warning */
1514  st_index_t bin = 0; /* Ditto */
1516  st_index_t bin_ind;
1517  st_data_t value = 0, old_key;
1518  st_index_t check;
1519  int retval, existing;
1520  st_hash_t hash = do_hash(key, tab);
1521 
1522  retry:
1523  entries = tab->entries;
1524  if (tab->bins == NULL) {
1525  bin = find_entry(tab, hash, key);
1526  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1527  goto retry;
1528  existing = bin != UNDEFINED_ENTRY_IND;
1529  entry = &entries[bin];
1530  bin_ind = UNDEFINED_BIN_IND;
1531  }
1532  else {
1533  bin_ind = find_table_bin_ind(tab, hash, key);
1534  if (EXPECT(bin_ind == REBUILT_TABLE_BIN_IND, 0))
1535  goto retry;
1536  existing = bin_ind != UNDEFINED_BIN_IND;
1537  if (existing) {
1538  bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
1539  entry = &entries[bin];
1540  }
1541  }
1542  if (existing) {
1543  key = entry->key;
1544  value = entry->record;
1545  }
1546  old_key = key;
1547  check = tab->rebuilds_num;
1548  retval = (*func)(&key, &value, arg, existing);
1549  st_assert(check == tab->rebuilds_num);
1550  switch (retval) {
1551  case ST_CONTINUE:
1552  if (! existing) {
1553  st_add_direct_with_hash(tab, key, value, hash);
1554  break;
1555  }
1556  if (old_key != key) {
1557  entry->key = key;
1558  }
1559  entry->record = value;
1560  break;
1561  case ST_DELETE:
1562  if (existing) {
1563  if (bin_ind != UNDEFINED_BIN_IND)
1564  MARK_BIN_DELETED(tab, bin_ind);
1565  MARK_ENTRY_DELETED(entry);
1566  tab->num_entries--;
1567  update_range_for_deleted(tab, bin);
1568 #ifdef ST_DEBUG
1569  st_check(tab);
1570 #endif
1571  }
1572  break;
1573  }
1574 #ifdef ST_DEBUG
1575  st_check(tab);
1576 #endif
1577  return existing;
1578 }
1579 
1580 /* Traverse all entries in table TAB calling FUNC with current entry
1581  key and value and zero. If the call returns ST_STOP, stop
1582  traversing. If the call returns ST_DELETE, delete the current
1583  entry from the table. In case of ST_CHECK or ST_CONTINUE, continue
1584  traversing. The function returns zero unless an error is found.
1585  CHECK_P is flag of st_foreach_check call. The behavior is a bit
1586  different for ST_CHECK and when the current element is removed
1587  during traversing. */
1588 static inline int
1589 st_general_foreach(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg,
1590  int check_p)
1591 {
1592  st_index_t bin;
1593  st_index_t bin_ind;
1594  st_table_entry *entries, *curr_entry_ptr;
1595  enum st_retval retval;
1596  st_index_t i, rebuilds_num;
1597  st_hash_t hash;
1598  st_data_t key;
1599  int error_p, packed_p = tab->bins == NULL;
1600 
1601  st_assert(tab->entries_start <= tab->entries_bound);
1602  entries = tab->entries;
1603  /* The bound can change inside the loop even without rebuilding
1604  the table, e.g. by an entry inesrtion. */
1605  for (i = tab->entries_start; i < tab->entries_bound; i++) {
1606  curr_entry_ptr = &entries[i];
1607  if (EXPECT(DELETED_ENTRY_P(curr_entry_ptr), 0))
1608  continue;
1609  key = curr_entry_ptr->key;
1610  rebuilds_num = tab->rebuilds_num;
1611  hash = curr_entry_ptr->hash;
1612  retval = (*func)(key, curr_entry_ptr->record, arg, 0);
1613 
1614  if (retval == ST_REPLACE && replace) {
1615  st_data_t value;
1616  value = curr_entry_ptr->record;
1617  retval = (*replace)(&key, &value, arg, TRUE);
1618  curr_entry_ptr->key = key;
1619  curr_entry_ptr->record = value;
1620  }
1621 
1622  if (rebuilds_num != tab->rebuilds_num) {
1623  retry:
1624  entries = tab->entries;
1625  packed_p = tab->bins == NULL;
1626  if (packed_p) {
1627  i = find_entry(tab, hash, key);
1628  if (EXPECT(i == REBUILT_TABLE_ENTRY_IND, 0))
1629  goto retry;
1630  error_p = i == UNDEFINED_ENTRY_IND;
1631  }
1632  else {
1633  i = find_table_entry_ind(tab, hash, key);
1634  if (EXPECT(i == REBUILT_TABLE_ENTRY_IND, 0))
1635  goto retry;
1636  error_p = i == UNDEFINED_ENTRY_IND;
1637  i -= ENTRY_BASE;
1638  }
1639  if (error_p && check_p) {
1640  /* call func with error notice */
1641  retval = (*func)(0, 0, arg, 1);
1642 #ifdef ST_DEBUG
1643  st_check(tab);
1644 #endif
1645  return 1;
1646  }
1647  curr_entry_ptr = &entries[i];
1648  }
1649  switch (retval) {
1650  case ST_REPLACE:
1651  break;
1652  case ST_CONTINUE:
1653  break;
1654  case ST_CHECK:
1655  if (check_p)
1656  break;
1657  case ST_STOP:
1658 #ifdef ST_DEBUG
1659  st_check(tab);
1660 #endif
1661  return 0;
1662  case ST_DELETE: {
1663  st_data_t key = curr_entry_ptr->key;
1664 
1665  again:
1666  if (packed_p) {
1667  bin = find_entry(tab, hash, key);
1668  if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
1669  goto again;
1670  if (bin == UNDEFINED_ENTRY_IND)
1671  break;
1672  }
1673  else {
1674  bin_ind = find_table_bin_ind(tab, hash, key);
1675  if (EXPECT(bin_ind == REBUILT_TABLE_BIN_IND, 0))
1676  goto again;
1677  if (bin_ind == UNDEFINED_BIN_IND)
1678  break;
1679  bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
1680  MARK_BIN_DELETED(tab, bin_ind);
1681  }
1682  curr_entry_ptr = &entries[bin];
1683  MARK_ENTRY_DELETED(curr_entry_ptr);
1684  tab->num_entries--;
1685  update_range_for_deleted(tab, bin);
1686 #ifdef ST_DEBUG
1687  st_check(tab);
1688 #endif
1689  break;
1690  }
1691  }
1692  }
1693 #ifdef ST_DEBUG
1694  st_check(tab);
1695 #endif
1696  return 0;
1697 }
1698 
1699 int
1701 {
1702  return st_general_foreach(tab, func, replace, arg, TRUE);
1703 }
1704 
1705 struct functor {
1707  st_data_t arg;
1708 };
1709 
1710 static int
1711 apply_functor(st_data_t k, st_data_t v, st_data_t d, int _)
1712 {
1713  const struct functor *f = (void *)d;
1714  return f->func(k, v, f->arg);
1715 }
1716 
1717 int
1719 {
1720  const struct functor f = { func, arg };
1721  return st_general_foreach(tab, apply_functor, NULL, (st_data_t)&f, FALSE);
1722 }
1723 
1724 /* See comments for function st_delete_safe. */
1725 int
1728 {
1729  return st_general_foreach(tab, func, NULL, arg, TRUE);
1730 }
1731 
1732 /* Set up array KEYS by at most SIZE keys of head table TAB entries.
1733  Return the number of keys set up in array KEYS. */
1734 static inline st_index_t
1735 st_general_keys(st_table *tab, st_data_t *keys, st_index_t size)
1736 {
1737  st_index_t i, bound;
1738  st_data_t key, *keys_start, *keys_end;
1739  st_table_entry *curr_entry_ptr, *entries = tab->entries;
1740 
1741  bound = tab->entries_bound;
1742  keys_start = keys;
1743  keys_end = keys + size;
1744  for (i = tab->entries_start; i < bound; i++) {
1745  if (keys == keys_end)
1746  break;
1747  curr_entry_ptr = &entries[i];
1748  key = curr_entry_ptr->key;
1749  if (! DELETED_ENTRY_P(curr_entry_ptr))
1750  *keys++ = key;
1751  }
1752 
1753  return keys - keys_start;
1754 }
1755 
1756 st_index_t
1758 {
1759  return st_general_keys(tab, keys, size);
1760 }
1761 
1762 /* See comments for function st_delete_safe. */
1763 st_index_t
1766 {
1767  return st_general_keys(tab, keys, size);
1768 }
1769 
1770 /* Set up array VALUES by at most SIZE values of head table TAB
1771  entries. Return the number of values set up in array VALUES. */
1772 static inline st_index_t
1773 st_general_values(st_table *tab, st_data_t *values, st_index_t size)
1774 {
1775  st_index_t i, bound;
1776  st_data_t *values_start, *values_end;
1777  st_table_entry *curr_entry_ptr, *entries = tab->entries;
1778 
1779  values_start = values;
1780  values_end = values + size;
1781  bound = tab->entries_bound;
1782  st_assert(bound != 0);
1783  for (i = tab->entries_start; i < bound; i++) {
1784  if (values == values_end)
1785  break;
1786  curr_entry_ptr = &entries[i];
1787  if (! DELETED_ENTRY_P(curr_entry_ptr))
1788  *values++ = curr_entry_ptr->record;
1789  }
1790 
1791  return values - values_start;
1792 }
1793 
1794 st_index_t
1796 {
1797  return st_general_values(tab, values, size);
1798 }
1799 
1800 /* See comments for function st_delete_safe. */
1801 st_index_t
1804 {
1805  return st_general_values(tab, values, size);
1806 }
1807 
1808 #define FNV1_32A_INIT 0x811c9dc5
1809 
1810 /*
1811  * 32 bit magic FNV-1a prime
1812  */
1813 #define FNV_32_PRIME 0x01000193
1814 
1815 #ifndef UNALIGNED_WORD_ACCESS
1816 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
1817  defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
1818  defined(__powerpc64__) || \
1819  defined(__mc68020__)
1820 # define UNALIGNED_WORD_ACCESS 1
1821 # endif
1822 #endif
1823 #ifndef UNALIGNED_WORD_ACCESS
1824 # define UNALIGNED_WORD_ACCESS 0
1825 #endif
1826 
1827 /* This hash function is quite simplified MurmurHash3
1828  * Simplification is legal, cause most of magic still happens in finalizator.
1829  * And finalizator is almost the same as in MurmurHash3 */
1830 #define BIG_CONSTANT(x,y) ((st_index_t)(x)<<32|(st_index_t)(y))
1831 #define ROTL(x,n) ((x)<<(n)|(x)>>(SIZEOF_ST_INDEX_T*CHAR_BIT-(n)))
1832 
1833 #if ST_INDEX_BITS <= 32
1834 #define C1 (st_index_t)0xcc9e2d51
1835 #define C2 (st_index_t)0x1b873593
1836 #else
1837 #define C1 BIG_CONSTANT(0x87c37b91,0x114253d5);
1838 #define C2 BIG_CONSTANT(0x4cf5ad43,0x2745937f);
1839 #endif
1840 NO_SANITIZE("unsigned-integer-overflow", static inline st_index_t murmur_step(st_index_t h, st_index_t k));
1841 NO_SANITIZE("unsigned-integer-overflow", static inline st_index_t murmur_finish(st_index_t h));
1842 NO_SANITIZE("unsigned-integer-overflow", extern st_index_t st_hash(const void *ptr, size_t len, st_index_t h));
1843 
1844 static inline st_index_t
1845 murmur_step(st_index_t h, st_index_t k)
1846 {
1847 #if ST_INDEX_BITS <= 32
1848 #define r1 (17)
1849 #define r2 (11)
1850 #else
1851 #define r1 (33)
1852 #define r2 (24)
1853 #endif
1854  k *= C1;
1855  h ^= ROTL(k, r1);
1856  h *= C2;
1857  h = ROTL(h, r2);
1858  return h;
1859 }
1860 #undef r1
1861 #undef r2
1862 
1863 static inline st_index_t
1864 murmur_finish(st_index_t h)
1865 {
1866 #if ST_INDEX_BITS <= 32
1867 #define r1 (16)
1868 #define r2 (13)
1869 #define r3 (16)
1870  const st_index_t c1 = 0x85ebca6b;
1871  const st_index_t c2 = 0xc2b2ae35;
1872 #else
1873 /* values are taken from Mix13 on http://zimbry.blogspot.ru/2011/09/better-bit-mixing-improving-on.html */
1874 #define r1 (30)
1875 #define r2 (27)
1876 #define r3 (31)
1877  const st_index_t c1 = BIG_CONSTANT(0xbf58476d,0x1ce4e5b9);
1878  const st_index_t c2 = BIG_CONSTANT(0x94d049bb,0x133111eb);
1879 #endif
1880 #if ST_INDEX_BITS > 64
1881  h ^= h >> 64;
1882  h *= c2;
1883  h ^= h >> 65;
1884 #endif
1885  h ^= h >> r1;
1886  h *= c1;
1887  h ^= h >> r2;
1888  h *= c2;
1889  h ^= h >> r3;
1890  return h;
1891 }
1892 #undef r1
1893 #undef r2
1894 #undef r3
1895 
1896 st_index_t
1897 st_hash(const void *ptr, size_t len, st_index_t h)
1898 {
1899  const char *data = ptr;
1900  st_index_t t = 0;
1901  size_t l = len;
1902 
1903 #define data_at(n) (st_index_t)((unsigned char)data[(n)])
1904 #define UNALIGNED_ADD_4 UNALIGNED_ADD(2); UNALIGNED_ADD(1); UNALIGNED_ADD(0)
1905 #if SIZEOF_ST_INDEX_T > 4
1906 #define UNALIGNED_ADD_8 UNALIGNED_ADD(6); UNALIGNED_ADD(5); UNALIGNED_ADD(4); UNALIGNED_ADD(3); UNALIGNED_ADD_4
1907 #if SIZEOF_ST_INDEX_T > 8
1908 #define UNALIGNED_ADD_16 UNALIGNED_ADD(14); UNALIGNED_ADD(13); UNALIGNED_ADD(12); UNALIGNED_ADD(11); \
1909  UNALIGNED_ADD(10); UNALIGNED_ADD(9); UNALIGNED_ADD(8); UNALIGNED_ADD(7); UNALIGNED_ADD_8
1910 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_16
1911 #endif
1912 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_8
1913 #else
1914 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_4
1915 #endif
1916 #undef SKIP_TAIL
1917  if (len >= sizeof(st_index_t)) {
1918 #if !UNALIGNED_WORD_ACCESS
1919  int align = (int)((st_data_t)data % sizeof(st_index_t));
1920  if (align) {
1921  st_index_t d = 0;
1922  int sl, sr, pack;
1923 
1924  switch (align) {
1925 #ifdef WORDS_BIGENDIAN
1926 # define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \
1927  t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 2)
1928 #else
1929 # define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \
1930  t |= data_at(n) << CHAR_BIT*(n)
1931 #endif
1933 #undef UNALIGNED_ADD
1934  }
1935 
1936 #ifdef WORDS_BIGENDIAN
1937  t >>= (CHAR_BIT * align) - CHAR_BIT;
1938 #else
1939  t <<= (CHAR_BIT * align);
1940 #endif
1941 
1942  data += sizeof(st_index_t)-align;
1943  len -= sizeof(st_index_t)-align;
1944 
1945  sl = CHAR_BIT * (SIZEOF_ST_INDEX_T-align);
1946  sr = CHAR_BIT * align;
1947 
1948  while (len >= sizeof(st_index_t)) {
1949  d = *(st_index_t *)data;
1950 #ifdef WORDS_BIGENDIAN
1951  t = (t << sr) | (d >> sl);
1952 #else
1953  t = (t >> sr) | (d << sl);
1954 #endif
1955  h = murmur_step(h, t);
1956  t = d;
1957  data += sizeof(st_index_t);
1958  len -= sizeof(st_index_t);
1959  }
1960 
1961  pack = len < (size_t)align ? (int)len : align;
1962  d = 0;
1963  switch (pack) {
1964 #ifdef WORDS_BIGENDIAN
1965 # define UNALIGNED_ADD(n) case (n) + 1: \
1966  d |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1)
1967 #else
1968 # define UNALIGNED_ADD(n) case (n) + 1: \
1969  d |= data_at(n) << CHAR_BIT*(n)
1970 #endif
1972 #undef UNALIGNED_ADD
1973  }
1974 #ifdef WORDS_BIGENDIAN
1975  t = (t << sr) | (d >> sl);
1976 #else
1977  t = (t >> sr) | (d << sl);
1978 #endif
1979 
1980  if (len < (size_t)align) goto skip_tail;
1981 # define SKIP_TAIL 1
1982  h = murmur_step(h, t);
1983  data += pack;
1984  len -= pack;
1985  }
1986  else
1987 #endif
1988 #ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
1989 #define aligned_data __builtin_assume_aligned(data, sizeof(st_index_t))
1990 #else
1991 #define aligned_data data
1992 #endif
1993  {
1994  do {
1995  h = murmur_step(h, *(st_index_t *)aligned_data);
1996  data += sizeof(st_index_t);
1997  len -= sizeof(st_index_t);
1998  } while (len >= sizeof(st_index_t));
1999  }
2000  }
2001 
2002  t = 0;
2003  switch (len) {
2004 #if UNALIGNED_WORD_ACCESS && SIZEOF_ST_INDEX_T <= 8 && CHAR_BIT == 8
2005  /* in this case byteorder doesn't really matter */
2006 #if SIZEOF_ST_INDEX_T > 4
2007  case 7: t |= data_at(6) << 48;
2008  case 6: t |= data_at(5) << 40;
2009  case 5: t |= data_at(4) << 32;
2010  case 4:
2011  t |= (st_index_t)*(uint32_t*)aligned_data;
2012  goto skip_tail;
2013 # define SKIP_TAIL 1
2014 #endif
2015  case 3: t |= data_at(2) << 16;
2016  case 2: t |= data_at(1) << 8;
2017  case 1: t |= data_at(0);
2018 #else
2019 #ifdef WORDS_BIGENDIAN
2020 # define UNALIGNED_ADD(n) case (n) + 1: \
2021  t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1)
2022 #else
2023 # define UNALIGNED_ADD(n) case (n) + 1: \
2024  t |= data_at(n) << CHAR_BIT*(n)
2025 #endif
2027 #undef UNALIGNED_ADD
2028 #endif
2029 #ifdef SKIP_TAIL
2030  skip_tail:
2031 #endif
2032  h ^= t; h -= ROTL(t, 7);
2033  h *= C2;
2034  }
2035  h ^= l;
2036 #undef aligned_data
2037 
2038  return murmur_finish(h);
2039 }
2040 
2041 st_index_t
2043 {
2044  return murmur_step(h, i);
2045 }
2046 
2047 NO_SANITIZE("unsigned-integer-overflow", extern st_index_t st_hash_uint(st_index_t h, st_index_t i));
2048 st_index_t
2050 {
2051  i += h;
2052 /* no matter if it is BigEndian or LittleEndian,
2053  * we hash just integers */
2054 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
2055  h = murmur_step(h, i >> 8*8);
2056 #endif
2057  h = murmur_step(h, i);
2058  return h;
2059 }
2060 
2061 st_index_t
2063 {
2064  h = murmur_finish(h);
2065  return h;
2066 }
2067 
2068 #undef st_hash_start
2069 st_index_t
2071 {
2072  return h;
2073 }
2074 
2075 static st_index_t
2076 strhash(st_data_t arg)
2077 {
2078  register const char *string = (const char *)arg;
2079  return st_hash(string, strlen(string), FNV1_32A_INIT);
2080 }
2081 
2082 int
2083 st_locale_insensitive_strcasecmp(const char *s1, const char *s2)
2084 {
2085  char c1, c2;
2086 
2087  while (1) {
2088  c1 = *s1++;
2089  c2 = *s2++;
2090  if (c1 == '\0' || c2 == '\0') {
2091  if (c1 != '\0') return 1;
2092  if (c2 != '\0') return -1;
2093  return 0;
2094  }
2095  if (('A' <= c1) && (c1 <= 'Z')) c1 += 'a' - 'A';
2096  if (('A' <= c2) && (c2 <= 'Z')) c2 += 'a' - 'A';
2097  if (c1 != c2) {
2098  if (c1 > c2)
2099  return 1;
2100  else
2101  return -1;
2102  }
2103  }
2104 }
2105 
2106 int
2107 st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n)
2108 {
2109  char c1, c2;
2110  size_t i;
2111 
2112  for (i = 0; i < n; i++) {
2113  c1 = *s1++;
2114  c2 = *s2++;
2115  if (c1 == '\0' || c2 == '\0') {
2116  if (c1 != '\0') return 1;
2117  if (c2 != '\0') return -1;
2118  return 0;
2119  }
2120  if (('A' <= c1) && (c1 <= 'Z')) c1 += 'a' - 'A';
2121  if (('A' <= c2) && (c2 <= 'Z')) c2 += 'a' - 'A';
2122  if (c1 != c2) {
2123  if (c1 > c2)
2124  return 1;
2125  else
2126  return -1;
2127  }
2128  }
2129  return 0;
2130 }
2131 
2132 static int
2133 st_strcmp(st_data_t lhs, st_data_t rhs)
2134 {
2135  const char *s1 = (char *)lhs;
2136  const char *s2 = (char *)rhs;
2137  return strcmp(s1, s2);
2138 }
2139 
2140 static int
2141 st_locale_insensitive_strcasecmp_i(st_data_t lhs, st_data_t rhs)
2142 {
2143  const char *s1 = (char *)lhs;
2144  const char *s2 = (char *)rhs;
2146 }
2147 
2148 NO_SANITIZE("unsigned-integer-overflow", PUREFUNC(static st_index_t strcasehash(st_data_t)));
2149 static st_index_t
2150 strcasehash(st_data_t arg)
2151 {
2152  register const char *string = (const char *)arg;
2153  register st_index_t hval = FNV1_32A_INIT;
2154 
2155  /*
2156  * FNV-1a hash each octet in the buffer
2157  */
2158  while (*string) {
2159  unsigned int c = (unsigned char)*string++;
2160  if ((unsigned int)(c - 'A') <= ('Z' - 'A')) c += 'a' - 'A';
2161  hval ^= c;
2162 
2163  /* multiply by the 32 bit FNV magic prime mod 2^32 */
2164  hval *= FNV_32_PRIME;
2165  }
2166  return hval;
2167 }
2168 
2169 int
2171 {
2172  return x != y;
2173 }
2174 
2175 st_index_t
2177 {
2178  enum {s1 = 11, s2 = 3};
2179  return (st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
2180 }
2181 
2182 /* Expand TAB to be suitable for holding SIZ entries in total.
2183  Pre-existing entries remain not deleted inside of TAB, but its bins
2184  are cleared to expect future reconstruction. See rehash below. */
2185 static void
2186 st_expand_table(st_table *tab, st_index_t siz)
2187 {
2188  st_table *tmp;
2189  st_index_t n;
2190 
2191  if (siz <= get_allocated_entries(tab))
2192  return; /* enough room already */
2193 
2194  tmp = st_init_table_with_size(tab->type, siz);
2195  n = get_allocated_entries(tab);
2196  MEMCPY(tmp->entries, tab->entries, st_table_entry, n);
2197  free(tab->entries);
2198  if (tab->bins != NULL)
2199  free(tab->bins);
2200  if (tmp->bins != NULL)
2201  free(tmp->bins);
2202  tab->entry_power = tmp->entry_power;
2203  tab->bin_power = tmp->bin_power;
2204  tab->size_ind = tmp->size_ind;
2205  tab->entries = tmp->entries;
2206  tab->bins = NULL;
2207  tab->rebuilds_num++;
2208  free(tmp);
2209 }
2210 
2211 /* Rehash using linear search. Return TRUE if we found that the table
2212  was rebuilt. */
2213 static int
2214 st_rehash_linear(st_table *tab)
2215 {
2216  int eq_p, rebuilt_p;
2217  st_index_t i, j;
2218  st_table_entry *p, *q;
2219  if (tab->bins) {
2220  free(tab->bins);
2221  tab->bins = NULL;
2222  }
2223  for (i = tab->entries_start; i < tab->entries_bound; i++) {
2224  p = &tab->entries[i];
2225  if (DELETED_ENTRY_P(p))
2226  continue;
2227  for (j = i + 1; j < tab->entries_bound; j++) {
2228  q = &tab->entries[j];
2229  if (DELETED_ENTRY_P(q))
2230  continue;
2231  DO_PTR_EQUAL_CHECK(tab, p, q->hash, q->key, eq_p, rebuilt_p);
2232  if (EXPECT(rebuilt_p, 0))
2233  return TRUE;
2234  if (eq_p) {
2235  st_assert(p < q);
2236  *p = *q;
2237  MARK_ENTRY_DELETED(q);
2238  tab->num_entries--;
2239  update_range_for_deleted(tab, j);
2240  }
2241  }
2242  }
2243  return FALSE;
2244 }
2245 
2246 /* Rehash using index. Return TRUE if we found that the table was
2247  rebuilt. */
2248 static int
2249 st_rehash_indexed(st_table *tab)
2250 {
2251  int eq_p, rebuilt_p;
2252  st_index_t i;
2253  st_index_t const n = bins_size(tab);
2254  unsigned int const size_ind = get_size_ind(tab);
2255  st_index_t *bins = realloc(tab->bins, n);
2256  st_assert(bins != NULL);
2257  tab->bins = bins;
2258  initialize_bins(tab);
2259  for (i = tab->entries_start; i < tab->entries_bound; i++) {
2260  st_table_entry *p = &tab->entries[i];
2261  st_index_t ind;
2262 #ifdef QUADRATIC_PROBE
2263  st_index_t d = 1;
2264 #else
2265  st_index_t peterb = p->hash;
2266 #endif
2267 
2268  if (DELETED_ENTRY_P(p))
2269  continue;
2270 
2271  ind = hash_bin(p->hash, tab);
2272  for(;;) {
2273  st_index_t bin = get_bin(bins, size_ind, ind);
2274  if (EMPTY_OR_DELETED_BIN_P(bin)) {
2275  /* ok, new room */
2276  set_bin(bins, size_ind, ind, i + ENTRY_BASE);
2277  break;
2278  }
2279  else {
2280  st_table_entry *q = &tab->entries[bin - ENTRY_BASE];
2281  DO_PTR_EQUAL_CHECK(tab, q, p->hash, p->key, eq_p, rebuilt_p);
2282  if (EXPECT(rebuilt_p, 0))
2283  return TRUE;
2284  if (eq_p) {
2285  /* duplicated key; delete it */
2286  st_assert(q < p);
2287  q->record = p->record;
2288  MARK_ENTRY_DELETED(p);
2289  tab->num_entries--;
2290  update_range_for_deleted(tab, bin);
2291  break;
2292  }
2293  else {
2294  /* hash collision; skip it */
2295 #ifdef QUADRATIC_PROBE
2296  ind = hash_bin(ind + d, tab);
2297  d++;
2298 #else
2299  ind = secondary_hash(ind, tab, &peterb);
2300 #endif
2301  }
2302  }
2303  }
2304  }
2305  return FALSE;
2306 }
2307 
2308 /* Reconstruct TAB's bins according to TAB's entries. This function
2309  permits conflicting keys inside of entries. No errors are reported
2310  then. All but one of them are discarded silently. */
2311 static void
2312 st_rehash(st_table *tab)
2313 {
2314  int rebuilt_p;
2315 
2316  do {
2318  rebuilt_p = st_rehash_linear(tab);
2319  else
2320  rebuilt_p = st_rehash_indexed(tab);
2321  } while (rebuilt_p);
2322 }
2323 
2324 #ifdef RUBY
2325 static st_data_t
2326 st_stringify(VALUE key)
2327 {
2328  return (rb_obj_class(key) == rb_cString && !RB_OBJ_FROZEN(key)) ?
2329  rb_hash_key_str(key) : key;
2330 }
2331 
2332 static void
2333 st_insert_single(st_table *tab, VALUE hash, VALUE key, VALUE val)
2334 {
2335  st_data_t k = st_stringify(key);
2336  st_table_entry e;
2337  e.hash = do_hash(k, tab);
2338  e.key = k;
2339  e.record = val;
2340 
2341  tab->entries[tab->entries_bound++] = e;
2342  tab->num_entries++;
2343  RB_OBJ_WRITTEN(hash, Qundef, k);
2344  RB_OBJ_WRITTEN(hash, Qundef, val);
2345 }
2346 
2347 static void
2348 st_insert_linear(st_table *tab, long argc, const VALUE *argv, VALUE hash)
2349 {
2350  long i;
2351 
2352  for (i = 0; i < argc; /* */) {
2353  st_data_t k = st_stringify(argv[i++]);
2354  st_data_t v = argv[i++];
2355  st_insert(tab, k, v);
2356  RB_OBJ_WRITTEN(hash, Qundef, k);
2357  RB_OBJ_WRITTEN(hash, Qundef, v);
2358  }
2359 }
2360 
2361 static void
2362 st_insert_generic(st_table *tab, long argc, const VALUE *argv, VALUE hash)
2363 {
2364  long i;
2365 
2366  /* push elems */
2367  for (i = 0; i < argc; /* */) {
2368  VALUE key = argv[i++];
2369  VALUE val = argv[i++];
2370  st_insert_single(tab, hash, key, val);
2371  }
2372 
2373  /* reindex */
2374  st_rehash(tab);
2375 }
2376 
2377 /* Mimics ruby's { foo => bar } syntax. This function is subpart
2378  of rb_hash_bulk_insert. */
2379 void
2381 {
2382  st_index_t n, size = argc / 2;
2383  st_table *tab = RHASH_ST_TABLE(hash);
2384 
2385  tab = RHASH_TBL_RAW(hash);
2386  n = tab->entries_bound + size;
2387  st_expand_table(tab, n);
2388  if (UNLIKELY(tab->num_entries))
2389  st_insert_generic(tab, argc, argv, hash);
2390  else if (argc <= 2)
2391  st_insert_single(tab, hash, argv[0], argv[1]);
2393  st_insert_linear(tab, argc, argv, hash);
2394  else
2395  st_insert_generic(tab, argc, argv, hash);
2396 }
2397 #endif
memset
void * memset(void *, int, size_t)
REBUILT_TABLE_ENTRY_IND
#define REBUILT_TABLE_ENTRY_IND
Definition: st.c:400
UNDEFINED_BIN_IND
#define UNDEFINED_BIN_IND
Definition: st.c:396
UNLIKELY
#define UNLIKELY(x)
Definition: ffi_common.h:126
TRUE
#define TRUE
Definition: nkf.h:175
st_foreach_with_replace
int st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
Definition: st.c:1700
ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED
Definition: st.c:124
st_update_callback_func
int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
Definition: st.h:131
r2
#define r2
st_copy
st_table * st_copy(st_table *old_tab)
Definition: st.c:1320
st_table::entry_power
unsigned char entry_power
Definition: st.h:81
st_table::num_entries
st_index_t num_entries
Definition: st.h:86
DELETED_ENTRY_P
#define DELETED_ENTRY_P(e_ptr)
Definition: st.c:428
st_table::size_ind
unsigned char size_ind
Definition: st.h:81
ROTL
#define ROTL(x, n)
Definition: st.c:1831
ST_CHECK
@ ST_CHECK
Definition: st.h:99
s2
const char * s2
Definition: rb_mjit_min_header-2.7.2.h:5450
PUREFUNC
#define PUREFUNC(x)
Definition: defines.h:30
int
__inline__ int
Definition: rb_mjit_min_header-2.7.2.h:2845
st_features::entry_power
unsigned char entry_power
Definition: st.c:195
ST_STOP
@ ST_STOP
Definition: st.h:99
st_hash_t
st_index_t st_hash_t
Definition: st.c:134
fclose
int fclose(FILE *)
st_hash
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
Definition: st.c:1897
i
uint32_t i
Definition: rb_mjit_min_header-2.7.2.h:5460
st_cleanup_safe
void st_cleanup_safe(st_table *tab ATTRIBUTE_UNUSED, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1496
RESERVED_HASH_VAL
#define RESERVED_HASH_VAL
Definition: st.c:316
st_shift
int st_shift(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1440
st_hash_uint
st_index_t st_hash_uint(st_index_t h, st_index_t i)
Definition: st.c:2049
ST_INIT_VAL
#define ST_INIT_VAL
Definition: st.c:165
st_init_numtable
st_table * st_init_numtable(void)
Definition: st.c:653
VALUE
unsigned long VALUE
Definition: ruby.h:102
long
#define long
Definition: rb_mjit_min_header-2.7.2.h:2889
REBUILT_TABLE_BIN_IND
#define REBUILT_TABLE_BIN_IND
Definition: st.c:401
st_table_entry
struct st_table_entry st_table_entry
Definition: st.h:75
st_foreach_check
int st_foreach_check(st_table *tab, st_foreach_check_callback_func *func, st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1726
st_delete
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1418
st_add_direct
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1251
RESERVED_HASH_SUBSTITUTION_VAL
#define RESERVED_HASH_SUBSTITUTION_VAL
Definition: st.c:317
short
#define short
Definition: rb_mjit_min_header-2.7.2.h:2885
st_retval
st_retval
Definition: st.h:99
REBUILD_THRESHOLD
#define REBUILD_THRESHOLD
Definition: st.c:766
UNALIGNED_ADD_ALL
#define UNALIGNED_ADD_ALL
getenv
#define getenv(name)
Definition: win32.c:73
IND_EMPTY_BIN_P
#define IND_EMPTY_BIN_P(tab, i)
Definition: st.c:421
st_features::bin_power
unsigned char bin_power
Definition: st.c:199
entries
struct iseq_catch_table_entry entries[]
FOUND_BIN
#define FOUND_BIN
Definition: st.c:760
st_table_entry::record
st_data_t record
Definition: st.c:139
assert.h
atexit
int atexit(void(*__func)(void))
Qundef
#define Qundef
Definition: ruby.h:470
st_reserved_hash_substitution_val
const st_hash_t st_reserved_hash_substitution_val
Definition: st.c:320
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:227
ptr
struct RIMemo * ptr
Definition: debug.c:65
st_hash_uint32
st_index_t st_hash_uint32(st_index_t h, uint32_t i)
Definition: st.c:2042
RB_OBJ_FROZEN
#define RB_OBJ_FROZEN(x)
Definition: ruby.h:1342
st_insert2
int st_insert2(st_table *tab, st_data_t key, st_data_t value, st_data_t(*func)(st_data_t))
Definition: st.c:1263
EMPTY_OR_DELETED_BIN_P
#define EMPTY_OR_DELETED_BIN_P(b)
Definition: st.c:417
NULL
#define NULL
Definition: _sdbm.c:101
ST_DELETE
@ ST_DELETE
Definition: st.h:99
uint32_t
unsigned int uint32_t
Definition: sha2.h:101
st_table::entries
st_table_entry * entries
Definition: st.h:94
functor
Definition: hash.c:909
rb_hash_bulk_insert_into_st_table
void rb_hash_bulk_insert_into_st_table(long argc, const VALUE *argv, VALUE hash)
Definition: st.c:2380
st_insert
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1171
strlen
size_t strlen(const char *)
rb_st_hash_start
st_index_t rb_st_hash_start(st_index_t h)
Definition: st.c:2070
NO_SANITIZE
NO_SANITIZE("unsigned-integer-overflow", static inline st_index_t murmur_step(st_index_t h, st_index_t k))
r3
#define r3
ENTRY_BASE
#define ENTRY_BASE
Definition: st.c:387
st_init_table_with_size
st_table * st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
Definition: st.c:577
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
SIZEOF_ST_INDEX_T
#define SIZEOF_ST_INDEX_T
Definition: st.h:59
st_table::bin_power
unsigned char bin_power
Definition: st.h:81
st_reserved_hash_val
const st_hash_t st_reserved_hash_val
Definition: st.c:319
st_table_entry
Definition: st.c:136
ST_INIT_VAL_BYTE
#define ST_INIT_VAL_BYTE
Definition: st.c:166
st_numcmp
int st_numcmp(st_data_t x, st_data_t y)
Definition: st.c:2170
r1
#define r1
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
st_foreach_check_callback_func
int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int)
Definition: st.h:138
snprintf
int snprintf(char *__restrict, size_t, const char *__restrict,...) __attribute__((__format__(__printf__
ST_REPLACE
@ ST_REPLACE
Definition: st.h:99
keys
const rb_iseq_t const char const VALUE keys
Definition: rb_mjit_min_header-2.7.2.h:13471
st_clear
void st_clear(st_table *tab)
Definition: st.c:698
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.2.h:5458
st_init_numtable_with_size
st_table * st_init_numtable_with_size(st_index_t size)
Definition: st.c:660
st_foreach_callback_func
int st_foreach_callback_func(st_data_t, st_data_t, st_data_t)
Definition: st.h:137
functor::func
st_foreach_callback_func * func
Definition: hash.c:910
RB_OBJ_WRITTEN
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1509
PREFETCH
#define PREFETCH(addr, write_p)
Definition: st.c:122
st_numhash
st_index_t st_numhash(st_data_t n)
Definition: st.c:2176
st_init_strtable
st_table * st_init_strtable(void)
Definition: st.c:668
st_assert
#define st_assert(cond)
Definition: st.c:130
getpid
pid_t getpid(void)
st_init_strcasetable_with_size
st_table * st_init_strcasetable_with_size(st_index_t size)
Definition: st.c:691
bin
char bin[32]
Definition: siphash.c:135
st_index_t
st_data_t st_index_t
Definition: st.h:50
st_locale_insensitive_strncasecmp
int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: st.c:2107
st_hash_type
Definition: st.h:61
st_table_entry::hash
st_hash_t hash
Definition: st.c:137
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:922
MARK_BIN_EMPTY
#define MARK_BIN_EMPTY(tab, i)
Definition: st.c:391
st_init_strcasetable
st_table * st_init_strcasetable(void)
Definition: st.c:683
MAX_POWER2
#define MAX_POWER2
Definition: st.c:277
MINIMAL_POWER2
#define MINIMAL_POWER2
Definition: st.c:334
st_init_strtable_with_size
st_table * st_init_strtable_with_size(st_index_t size)
Definition: st.c:675
FNV1_32A_INIT
#define FNV1_32A_INIT
Definition: st.c:1808
MARK_ENTRY_DELETED
#define MARK_ENTRY_DELETED(e_ptr)
Definition: st.c:427
size
int size
Definition: encoding.c:58
EMPTY_BIN_P
#define EMPTY_BIN_P(b)
Definition: st.c:415
FALSE
#define FALSE
Definition: nkf.h:174
data_at
#define data_at(n)
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.2.h:5597
st_features
Definition: st.c:193
ST_INDEX_BITS
#define ST_INDEX_BITS
Definition: st.h:66
st_update
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1510
key
key
Definition: openssl_missing.h:181
IND_DELETED_BIN_P
#define IND_DELETED_BIN_P(tab, i)
Definition: st.c:422
malloc
#define malloc
Definition: st.c:173
st_values
st_index_t st_values(st_table *tab, st_data_t *values, st_index_t size)
Definition: st.c:1795
st_foreach
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
Definition: st.c:1718
st_values_check
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:1802
C1
#define C1
Definition: st.c:1834
st_table_entry::key
st_data_t key
Definition: st.c:138
internal.h
argv
char ** argv
Definition: ruby.c:223
f
#define f
DO_PTR_EQUAL_CHECK
#define DO_PTR_EQUAL_CHECK(tab, ptr, hash_val, key, res, rebuilt_p)
Definition: st.c:185
RHASH_ST_TABLE
#define RHASH_ST_TABLE(hash)
Definition: internal.h:856
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
st_init_table
st_table * st_init_table(const struct st_hash_type *type)
Definition: st.c:645
st_keys
st_index_t st_keys(st_table *tab, st_data_t *keys, st_index_t size)
Definition: st.c:1757
st_table::entries_start
st_index_t entries_start
Definition: st.h:92
BIG_CONSTANT
#define BIG_CONSTANT(x, y)
Definition: st.c:1830
st_keys_check
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:1764
st_delete_safe
int st_delete_safe(st_table *tab, st_data_t *key, st_data_t *value, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1429
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
UNDEFINED_ENTRY_IND
#define UNDEFINED_ENTRY_IND
Definition: st.c:395
functor::arg
st_data_t arg
Definition: hash.c:911
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1753
st_table::type
const struct st_hash_type * type
Definition: st.h:84
MAX_POWER2_FOR_TABLES_WITHOUT_BINS
#define MAX_POWER2_FOR_TABLES_WITHOUT_BINS
Definition: st.c:342
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:2044
st_features::size_ind
unsigned char size_ind
Definition: st.c:201
argc
int argc
Definition: ruby.c:222
st_locale_insensitive_strcasecmp
int st_locale_insensitive_strcasecmp(const char *s1, const char *s2)
Definition: st.c:2083
regint.h
st_table::bins
st_index_t * bins
Definition: st.h:88
DELETED_BIN_P
#define DELETED_BIN_P(b)
Definition: st.c:416
aligned_data
#define aligned_data
FNV_32_PRIME
#define FNV_32_PRIME
Definition: st.c:1813
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.2.h:5359
st_table::rebuilds_num
unsigned int rebuilds_num
Definition: st.h:83
size_t
unsigned int size_t
Definition: rb_mjit_min_header-2.7.2.h:663
st_hash_t
st_index_t st_hash_t
Definition: hash.c:327
_
#define _(args)
Definition: dln.h:28
st_memsize
size_t st_memsize(const st_table *tab)
Definition: st.c:719
v
int VALUE v
Definition: rb_mjit_min_header-2.7.2.h:12300
len
uint8_t len
Definition: escape.c:17
realloc
#define realloc
Definition: st.c:175
COLLISION
#define COLLISION
Definition: st.c:759
st_table::entries_bound
st_index_t entries_bound
Definition: st.h:92
rb_hash_key_str
VALUE rb_hash_key_str(VALUE key)
Definition: hash.c:2802
RHASH_TBL_RAW
#define RHASH_TBL_RAW(h)
Definition: internal.h:1695
free
#define free
Definition: st.c:176
MARK_BIN_DELETED
#define MARK_BIN_DELETED(tab, i)
Definition: st.c:406
type_numhash
#define type_numhash
Definition: st.c:142
st_lookup
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
Definition: st.c:1101
st_hash_end
st_index_t st_hash_end(st_index_t h)
Definition: st.c:2062
EXPECT
#define EXPECT(expr, val)
Definition: st.c:123
fprintf
int fprintf(FILE *__restrict, const char *__restrict,...) __attribute__((__format__(__printf__
st_free_table
void st_free_table(st_table *tab)
Definition: st.c:709
char
#define char
Definition: rb_mjit_min_header-2.7.2.h:2884
st_table
Definition: st.h:79
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
strcmp
int strcmp(const char *, const char *)
__sFILE
Definition: vsnprintf.c:169
st_features::bins_words
st_index_t bins_words
Definition: st.c:204
C2
#define C2
Definition: st.c:1835
st_get_key
int st_get_key(st_table *tab, st_data_t key, st_data_t *result)
Definition: st.c:1130
st_hash_type::hash
st_index_t(* hash)(st_data_t)
Definition: st.h:63
n
const char size_t n
Definition: rb_mjit_min_header-2.7.2.h:5452
fopen
FILE * fopen(const char *__restrict _name, const char *__restrict _type)