Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

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. */
134 typedef st_index_t st_hash_t;
135
136 struct st_table_entry {
137 st_hash_t hash;
138 st_data_t key;
139 st_data_t record;
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. */
204 st_index_t bins_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
319 const st_hash_t st_reserved_hash_val = RESERVED_HASH_VAL;
320 const st_hash_t st_reserved_hash_substitution_val = RESERVED_HASH_SUBSTITUTION_VAL;
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;
507 st_assert(p >= MINIMAL_POWER2);
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)
520 st_assert(p <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS);
521 else {
522 st_assert(p > MAX_POWER2_FOR_TABLES_WITHOUT_BINS);
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 *
577 st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
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;
609 if (n <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS)
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
629 memset(tab->entries, ST_INIT_VAL_BYTE,
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 *
645 st_init_table(const struct st_hash_type *type)
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 *
653 st_init_numtable(void)
654 {
655 return st_init_table(&type_numhash);
656 }
657
658 /* Create and return table which can hold SIZE numbers. */
659 st_table *
660 st_init_numtable_with_size(st_index_t size)
661 {
662 return st_init_table_with_size(&type_numhash, size);
663 }
664
665 /* Create and return table which can hold a minimal number of
666 strings. */
667 st_table *
668 st_init_strtable(void)
669 {
670 return st_init_table(&type_strhash);
671 }
672
673 /* Create and return table which can hold SIZE strings. */
674 st_table *
675 st_init_strtable_with_size(st_index_t size)
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 *
683 st_init_strcasetable(void)
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 *
691 st_init_strcasetable_with_size(st_index_t size)
692 {
693 return st_init_table_with_size(&type_strcasehash, size);
694 }
695
696 /* Make table TAB empty. */
697 void
698 st_clear(st_table *tab)
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
709 st_free_table(st_table *tab)
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;
876 st_table_entry *entries;
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))
883 return REBUILT_TABLE_ENTRY_IND;
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;
909 st_table_entry *entries = tab->entries;
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))
925 return REBUILT_TABLE_ENTRY_IND;
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;
956 st_table_entry *entries = tab->entries;
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);
1014 if (EMPTY_OR_DELETED_BIN_P(bin))
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;
1050 st_table_entry *entries;
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
1101 st_lookup(st_table *tab, st_data_t key, st_data_t *value)
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
1130 st_get_key(st_table *tab, st_data_t key, st_data_t *result)
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
1171 st_insert(st_table *tab, st_data_t key, st_data_t value)
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
1251 st_add_direct(st_table *tab, st_data_t key, st_data_t value)
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
1263 st_insert2(st_table *tab, st_data_t key, st_data_t value,
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 *
1320 st_copy(st_table *old_tab)
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
1418 st_delete(st_table *tab, st_data_t *key, st_data_t *value)
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
1429 st_delete_safe(st_table *tab, st_data_t *key, st_data_t *value,
1430 st_data_t never ATTRIBUTE_UNUSED)
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
1440 st_shift(st_table *tab, st_data_t *key, st_data_t *value)
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 }
1464 st_assert(bin != UNDEFINED_ENTRY_IND);
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
1496 st_cleanup_safe(st_table *tab ATTRIBUTE_UNUSED,
1497 st_data_t never ATTRIBUTE_UNUSED)
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
1510 st_update(st_table *tab, st_data_t key,
1511 st_update_callback_func *func, st_data_t arg)
1512 {
1513 st_table_entry *entry = NULL; /* to avoid uninitialized value warning */
1514 st_index_t bin = 0; /* Ditto */
1515 st_table_entry *entries;
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
1700 st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
1701 {
1702 return st_general_foreach(tab, func, replace, arg, TRUE);
1703 }
1704
1705 struct functor {
1706 st_foreach_callback_func *func;
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
1718 st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
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
1726 st_foreach_check(st_table *tab, st_foreach_check_callback_func *func, st_data_t arg,
1727 st_data_t never ATTRIBUTE_UNUSED)
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
1757 st_keys(st_table *tab, st_data_t *keys, st_index_t size)
1758 {
1759 return st_general_keys(tab, keys, size);
1760 }
1761
1762 /* See comments for function st_delete_safe. */
1763 st_index_t
1764 st_keys_check(st_table *tab, st_data_t *keys, st_index_t size,
1765 st_data_t never ATTRIBUTE_UNUSED)
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
1795 st_values(st_table *tab, st_data_t *values, st_index_t size)
1796 {
1797 return st_general_values(tab, values, size);
1798 }
1799
1800 /* See comments for function st_delete_safe. */
1801 st_index_t
1802 st_values_check(st_table *tab, st_data_t *values, st_index_t size,
1803 st_data_t never ATTRIBUTE_UNUSED)
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
1932 UNALIGNED_ADD_ALL;
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
1971 UNALIGNED_ADD_ALL;
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
2026 UNALIGNED_ADD_ALL;
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
2042 st_hash_uint32(st_index_t h, uint32_t i)
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
2049 st_hash_uint(st_index_t h, st_index_t i)
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
2062 st_hash_end(st_index_t h)
2063 {
2064 h = murmur_finish(h);
2065 return h;
2066 }
2067
2068 #undef st_hash_start
2069 st_index_t
2070 rb_st_hash_start(st_index_t h)
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;
2145 return st_locale_insensitive_strcasecmp(s1, s2);
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
2170 st_numcmp(st_data_t x, st_data_t y)
2171 {
2172 return x != y;
2173 }
2174
2175 st_index_t
2176 st_numhash(st_data_t n)
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 {
2317 if (tab->bin_power <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS)
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
2380 rb_hash_bulk_insert_into_st_table(long argc, const VALUE *argv, VALUE hash)
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]);
2392 else if (tab->bin_power <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS)
2393 st_insert_linear(tab, argc, argv, hash);
2394 else
2395 st_insert_generic(tab, argc, argv, hash);
2396 }
2397 #endif
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
memset
void * memset(void *, int, size_t)
size_t
long unsigned int size_t
Definition: rb_mjit_min_header-2.7.0.h:666
PUREFUNC
#define PUREFUNC(x)
Definition: defines.h:30
short
#define short
Definition: rb_mjit_min_header-2.7.0.h:2877
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
snprintf
int snprintf(char *__restrict, size_t, const char *__restrict,...) __attribute__((__format__(__printf__
st_hash
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
Definition: st.c:1897
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
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
st_retval
st_retval
Definition: st.h:99
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
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
FOUND_BIN
#define FOUND_BIN
Definition: st.c:760
st_table_entry::record
st_data_t record
Definition: st.c:139
assert.h
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:74
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:906
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
atexit
int atexit(void(*__func)(void))
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
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:2669
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
ST_REPLACE
@ ST_REPLACE
Definition: st.h:99
fprintf
int fprintf(FILE *__restrict, const char *__restrict,...) __attribute__((__format__(__printf__
st_clear
void st_clear(st_table *tab)
Definition: st.c:698
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:907
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
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
long
#define long
Definition: rb_mjit_min_header-2.7.0.h:2880
st_assert
#define st_assert(cond)
Definition: st.c:130
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
entries
struct iseq_catch_table_entry entries[]
Definition: rb_mjit_min_header-2.7.0.h:10827
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
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)
st_features
Definition: st.c:193
getpid
pid_t getpid(void)
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
strcmp
int strcmp(const char *, const char *)
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
char
#define char
Definition: rb_mjit_min_header-2.7.0.h:2876
C1
#define C1
Definition: st.c:1834
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
fopen
FILE * fopen(const char *__restrict _name, const char *__restrict _type)
st_table_entry::key
st_data_t key
Definition: st.c:138
internal.h
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
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
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.0.h:5363
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
keys
const rb_iseq_t const char const VALUE keys
Definition: rb_mjit_min_header-2.7.0.h:13506
functor::arg
st_data_t arg
Definition: hash.c:908
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
fclose
int fclose(FILE *)
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
s2
const char * s2
Definition: rb_mjit_min_header-2.7.0.h:5454
st_table::rebuilds_num
unsigned int rebuilds_num
Definition: st.h:83
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
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:2729
RHASH_TBL_RAW
#define RHASH_TBL_RAW(h)
Definition: internal.h:1689
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
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.0.h:5462
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
st_free_table
void st_free_table(st_table *tab)
Definition: st.c:709
st_table
Definition: st.h:79
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
__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