113 #define PREFETCH(addr, write_p) __builtin_prefetch(addr, write_p) 114 #define EXPECT(expr, val) __builtin_expect(expr, val) 115 #define ATTRIBUTE_UNUSED __attribute__((unused)) 117 #define PREFETCH(addr, write_p) 118 #define EXPECT(expr, val) (expr) 119 #define ATTRIBUTE_UNUSED 123 #define st_assert assert 125 #define st_assert(cond) ((void)(0 && (cond))) 137 #define type_numhash st_hashtype_num 159 #define ST_INIT_VAL 0xafafafafafafafaf 160 #define ST_INIT_VAL_BYTE 0xafa 167 #define malloc ruby_xmalloc 168 #define calloc ruby_xcalloc 169 #define realloc ruby_xrealloc 170 #define free ruby_xfree 173 #define EQUAL(tab,x,y) ((x) == (y) || (*(tab)->type->compare)((x),(y)) == 0) 174 #define PTR_EQUAL(tab, ptr, hash_val, key_) \ 175 ((ptr)->hash == (hash_val) && EQUAL((tab), (key_), (ptr)->key)) 193 #if SIZEOF_ST_INDEX_T == 8 194 #define MAX_POWER2 62 212 {16, 17, 2, 0x10000},
213 {17, 18, 2, 0x20000},
214 {18, 19, 2, 0x40000},
215 {19, 20, 2, 0x80000},
216 {20, 21, 2, 0x100000},
217 {21, 22, 2, 0x200000},
218 {22, 23, 2, 0x400000},
219 {23, 24, 2, 0x800000},
220 {24, 25, 2, 0x1000000},
221 {25, 26, 2, 0x2000000},
222 {26, 27, 2, 0x4000000},
223 {27, 28, 2, 0x8000000},
224 {28, 29, 2, 0x10000000},
225 {29, 30, 2, 0x20000000},
226 {30, 31, 2, 0x40000000},
227 {31, 32, 2, 0x80000000},
228 {32, 33, 3, 0x200000000},
229 {33, 34, 3, 0x400000000},
230 {34, 35, 3, 0x800000000},
231 {35, 36, 3, 0x1000000000},
232 {36, 37, 3, 0x2000000000},
233 {37, 38, 3, 0x4000000000},
234 {38, 39, 3, 0x8000000000},
235 {39, 40, 3, 0x10000000000},
236 {40, 41, 3, 0x20000000000},
237 {41, 42, 3, 0x40000000000},
238 {42, 43, 3, 0x80000000000},
239 {43, 44, 3, 0x100000000000},
240 {44, 45, 3, 0x200000000000},
241 {45, 46, 3, 0x400000000000},
242 {46, 47, 3, 0x800000000000},
243 {47, 48, 3, 0x1000000000000},
244 {48, 49, 3, 0x2000000000000},
245 {49, 50, 3, 0x4000000000000},
246 {50, 51, 3, 0x8000000000000},
247 {51, 52, 3, 0x10000000000000},
248 {52, 53, 3, 0x20000000000000},
249 {53, 54, 3, 0x40000000000000},
250 {54, 55, 3, 0x80000000000000},
251 {55, 56, 3, 0x100000000000000},
252 {56, 57, 3, 0x200000000000000},
253 {57, 58, 3, 0x400000000000000},
254 {58, 59, 3, 0x800000000000000},
255 {59, 60, 3, 0x1000000000000000},
256 {60, 61, 3, 0x2000000000000000},
257 {61, 62, 3, 0x4000000000000000},
258 {62, 63, 3, 0x8000000000000000},
262 #define MAX_POWER2 30 281 {16, 17, 2, 0x20000},
282 {17, 18, 2, 0x40000},
283 {18, 19, 2, 0x80000},
284 {19, 20, 2, 0x100000},
285 {20, 21, 2, 0x200000},
286 {21, 22, 2, 0x400000},
287 {22, 23, 2, 0x800000},
288 {23, 24, 2, 0x1000000},
289 {24, 25, 2, 0x2000000},
290 {25, 26, 2, 0x4000000},
291 {26, 27, 2, 0x8000000},
292 {27, 28, 2, 0x10000000},
293 {28, 29, 2, 0x20000000},
294 {29, 30, 2, 0x40000000},
295 {30, 31, 2, 0x80000000},
301 #define RESERVED_HASH_VAL (~(st_hash_t) 0) 302 #define RESERVED_HASH_SUBSTITUTION_VAL ((st_hash_t) 0) 316 #define MINIMAL_POWER2 2 318 #if MINIMAL_POWER2 < 2 319 #error "MINIMAL_POWER2 should be >= 2" 324 #define MAX_POWER2_FOR_TABLES_WITHOUT_BINS 4 332 for (n = 0; size != 0; n++)
349 return (s == 0 ? ((
unsigned char *) bins)[n]
350 : s == 1 ? ((
unsigned short *) bins)[n]
351 : s == 2 ? ((
unsigned int *) bins)[n]
360 if (s == 0) ((
unsigned char *) bins)[n] = (
unsigned char) v;
361 else if (s == 1) ((
unsigned short *) bins)[n] = (
unsigned short) v;
362 else if (s == 2) ((
unsigned int *) bins)[n] = (
unsigned int) v;
370 #define DELETED_BIN 1 376 #define MARK_BIN_EMPTY(tab, i) (set_bin((tab)->bins, get_size_ind(tab), i, EMPTY_BIN)) 380 #define UNDEFINED_ENTRY_IND (~(st_index_t) 0) 381 #define UNDEFINED_BIN_IND (~(st_index_t) 0) 386 #define MARK_BIN_DELETED(tab, i) \ 388 st_assert(i != UNDEFINED_BIN_IND); \ 389 st_assert(! IND_EMPTY_OR_DELETED_BIN_P(tab, i)); \ 390 set_bin((tab)->bins, get_size_ind(tab), i, DELETED_BIN); \ 395 #define EMPTY_BIN_P(b) ((b) == EMPTY_BIN) 396 #define DELETED_BIN_P(b) ((b) == DELETED_BIN) 397 #define EMPTY_OR_DELETED_BIN_P(b) ((b) <= DELETED_BIN) 401 #define IND_EMPTY_BIN_P(tab, i) (EMPTY_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i))) 402 #define IND_DELETED_BIN_P(tab, i) (DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i))) 403 #define IND_EMPTY_OR_DELETED_BIN_P(tab, i) (EMPTY_OR_DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i))) 407 #define MARK_ENTRY_DELETED(e_ptr) ((e_ptr)->hash = RESERVED_HASH_VAL) 408 #define DELETED_ENTRY_P(e_ptr) ((e_ptr)->hash == RESERVED_HASH_VAL) 411 static inline unsigned int 428 return get_bins_num(tab) - 1;
436 return hash_value & bins_mask(tab);
441 get_allocated_entries(
const st_table *tab)
457 memset(tab->
bins, 0, bins_size(tab));
467 initialize_bins(tab);
471 #define st_assert_notinitial(ent) \ 473 st_assert(ent.hash != (st_hash_t) ST_INIT_VAL); \ 474 st_assert(ent.key != ST_INIT_VAL); \ 475 st_assert(ent.record != ST_INIT_VAL); \ 484 for (p = get_allocated_entries(tab), i = 0; p > 1; i++, p>>=1)
494 st_assert_notinitial(tab->
entries[i]);
503 for (n = d = i = 0; i < get_bins_num(tab); i++) {
515 st_assert_notinitial(tab->
entries[e]);
528 int all, total, num, str, strcase;
533 static int init_st = 0;
540 char fname[10+
sizeof(long)*3];
542 if (!collision.total)
return;
543 f = fopen((
snprintf(fname,
sizeof(fname),
"/tmp/col%ld", (
long)getpid()), fname),
"w");
544 fprintf(f,
"collision: %d / %d (%6.2f)\n", collision.all, collision.total,
545 ((
double)collision.all / (collision.total)) * 100);
546 fprintf(f,
"num: %d, str: %d, strcase: %d\n", collision.num, collision.str, collision.strcase);
563 const char *e =
getenv(
"ST_HASH_LOG");
564 if (!e || !*e) init_st = 1;
573 n = get_power2(size);
679 + (tab->
bins ==
NULL ? 0 : bins_size(tab))
704 else if (type == &type_strhash) {
707 else if (type == &type_strcasehash) {
712 #define COLLISION (collision_check ? count_collision(tab->type) : (void)0) 713 #define FOUND_BIN (collision_check ? collision.total++ : (void)0) 714 #define collision_check 0 723 #define REBUILD_THRESHOLD 4 725 #if REBUILD_THRESHOLD < 2 726 #error "REBUILD_THRESHOLD should be >= 2" 737 unsigned int size_ind;
747 if ((2 * tab->
num_entries <= get_allocated_entries(tab)
753 initialize_bins(tab);
755 new_entries = entries;
760 new_entries = new_tab->
entries;
763 bins = new_tab->
bins;
764 size_ind = get_size_ind(new_tab);
766 curr_entry_ptr = &entries[i];
770 if (&new_entries[ni] != curr_entry_ptr)
771 new_entries[ni] = *curr_entry_ptr;
773 bin_ind = find_table_bin_ind_direct(new_tab, curr_entry_ptr->
hash,
774 curr_entry_ptr->
key);
778 set_bin(bins, size_ind, bin_ind, ni +
ENTRY_BASE);
783 if (new_tab != tab) {
820 ind = (ind << 2) + ind + *perterb + 1;
821 return hash_bin(ind, tab);
836 if (
PTR_EQUAL(tab, &entries[i], hash_value, key))
853 #ifdef QUADRATIC_PROBE 863 ind = hash_bin(hash_value, tab);
864 #ifdef QUADRATIC_PROBE 871 bin = get_bin(tab->
bins, get_size_ind(tab), ind);
877 #ifdef QUADRATIC_PROBE 878 ind = hash_bin(ind + d, tab);
881 ind = secondary_hash(ind, tab, &peterb);
895 #ifdef QUADRATIC_PROBE 905 ind = hash_bin(hash_value, tab);
906 #ifdef QUADRATIC_PROBE 913 bin = get_bin(tab->
bins, get_size_ind(tab), ind);
919 #ifdef QUADRATIC_PROBE 920 ind = hash_bin(ind + d, tab);
923 ind = secondary_hash(ind, tab, &peterb);
937 #ifdef QUADRATIC_PROBE 947 ind = hash_bin(hash_value, tab);
948 #ifdef QUADRATIC_PROBE 955 bin = get_bin(tab->
bins, get_size_ind(tab), ind);
959 #ifdef QUADRATIC_PROBE 960 ind = hash_bin(ind + d, tab);
963 ind = secondary_hash(ind, tab, &peterb);
983 #ifdef QUADRATIC_PROBE 996 ind = hash_bin(curr_hash_value, tab);
997 #ifdef QUADRATIC_PROBE 1000 peterb = curr_hash_value;
1006 entry_index = get_bin(tab->
bins, get_size_ind(tab), ind);
1012 ind = first_deleted_bin_ind;
1022 first_deleted_bin_ind = ind;
1023 #ifdef QUADRATIC_PROBE 1024 ind = hash_bin(ind + d, tab);
1027 ind = secondary_hash(ind, tab, &peterb);
1044 bin = find_entry(tab, hash, key);
1049 bin = find_table_entry_ind(tab, hash, key);
1068 bin = find_entry(tab, hash, key);
1073 bin = find_table_entry_ind(tab, hash, key);
1085 rebuild_table_if_necessary (
st_table *tab)
1089 if (bound == get_allocated_entries(tab))
1107 rebuild_table_if_necessary(tab);
1108 hash_value = do_hash(key, tab);
1110 bin = find_entry(tab, hash_value, key);
1117 bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
1126 entry->
hash = hash_value;
1130 set_bin(tab->
bins, get_size_ind(tab), bin_ind, ind +
ENTRY_BASE);
1146 st_add_direct_with_hash(
st_table *tab,
1153 rebuild_table_if_necessary(tab);
1161 bin_ind = find_table_bin_ind_direct(tab, hash,
key);
1163 set_bin(tab->
bins, get_size_ind(tab), bin_ind, ind +
ENTRY_BASE);
1177 hash_value = do_hash(key, tab);
1178 st_add_direct_with_hash(tab, key, value, hash_value);
1195 rebuild_table_if_necessary (tab);
1196 hash_value = do_hash(key, tab);
1198 bin = find_entry(tab, hash_value, key);
1205 bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
1215 st_assert(do_hash(key, tab) == hash_value);
1218 entry->
hash = hash_value;
1222 set_bin(tab->
bins, get_size_ind(tab), bin_ind, ind +
ENTRY_BASE);
1242 *new_tab = *old_tab;
1250 get_allocated_entries(old_tab));
1283 hash = do_hash(*key, tab);
1285 bin = find_entry(tab, hash, *key);
1287 if (value != 0) *value = 0;
1292 bin_ind = find_table_bin_ind(tab, hash, *key);
1294 if (value != 0) *value = 0;
1297 bin = get_bin(tab->
bins, get_size_ind(tab), bin_ind) -
ENTRY_BASE;
1302 if (value != 0) *value = entry->
record;
1305 update_range_for_deleted(tab, bin);
1315 return st_general_delete(tab, key, value);
1327 return st_general_delete(tab, key, value);
1345 curr_entry_ptr = &entries[i];
1347 if (value != 0) *value = curr_entry_ptr->
record;
1348 *key = curr_entry_ptr->
key;
1350 bin = find_entry(tab, curr_entry_ptr->
hash, curr_entry_ptr->
key);
1352 st_assert(&entries[bin] == curr_entry_ptr);
1355 bin_ind = find_table_bin_ind(tab, curr_entry_ptr->
hash,
1356 curr_entry_ptr->
key);
1358 st_assert(&entries[get_bin(tab->
bins, get_size_ind(tab), bin_ind)
1364 update_range_for_deleted(tab, i);
1373 if (value != 0) *value = 0;
1402 int retval, existing;
1407 bin = find_entry(tab, hash, key);
1409 entry = &entries[
bin];
1413 bin_ind = find_table_bin_ind(tab, hash, key);
1416 bin = get_bin(tab->
bins, get_size_ind(tab), bin_ind) -
ENTRY_BASE;
1417 entry = &entries[
bin];
1426 retval = (*func)(&
key, &value, arg, existing);
1431 st_add_direct_with_hash(tab, key, value, hash);
1434 if (old_key != key) {
1445 update_range_for_deleted(tab, bin);
1477 int error_p, packed_p = tab->
bins ==
NULL;
1484 curr_entry_ptr = &entries[i];
1487 key = curr_entry_ptr->
key;
1489 hash = curr_entry_ptr->
hash;
1490 retval = (*func)(
key, curr_entry_ptr->
record, arg, 0);
1495 i = find_entry(tab, hash, key);
1499 i = find_table_entry_ind(tab, hash, key);
1503 if (error_p && check_p) {
1505 retval = (*func)(0, 0, arg, 1);
1511 curr_entry_ptr = &entries[i];
1526 bin = find_entry(tab, hash, curr_entry_ptr->
key);
1531 bin_ind = find_table_bin_ind(tab, hash, curr_entry_ptr->
key);
1534 bin = get_bin(tab->
bins, get_size_ind(tab), bin_ind) -
ENTRY_BASE;
1537 st_assert(&entries[bin] == curr_entry_ptr);
1540 update_range_for_deleted(tab, bin);
1556 return st_general_foreach(tab, func, arg,
FALSE);
1564 return st_general_foreach(tab, func, arg,
TRUE);
1578 keys_end = keys +
size;
1580 if (keys == keys_end)
1582 curr_entry_ptr = &entries[i];
1583 key = curr_entry_ptr->
key;
1588 return keys - keys_start;
1594 return st_general_keys(tab, keys, size);
1602 return st_general_keys(tab, keys, size);
1614 values_start = values;
1615 values_end = values +
size;
1619 if (values == values_end)
1621 curr_entry_ptr = &entries[i];
1623 *values++ = curr_entry_ptr->
record;
1626 return values - values_start;
1632 return st_general_values(tab, values, size);
1640 return st_general_values(tab, values, size);
1643 #define FNV1_32A_INIT 0x811c9dc5 1648 #define FNV_32_PRIME 0x01000193 1650 #ifndef UNALIGNED_WORD_ACCESS 1651 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ 1652 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ 1653 defined(__powerpc64__) || \ 1654 defined(__mc68020__) 1655 # define UNALIGNED_WORD_ACCESS 1 1658 #ifndef UNALIGNED_WORD_ACCESS 1659 # define UNALIGNED_WORD_ACCESS 0 1665 #define BIG_CONSTANT(x,y) ((st_index_t)(x)<<32|(st_index_t)(y)) 1666 #define ROTL(x,n) ((x)<<(n)|(x)>>(SIZEOF_ST_INDEX_T*CHAR_BIT-(n))) 1668 #if ST_INDEX_BITS <= 32 1669 #define C1 (st_index_t)0xcc9e2d51 1670 #define C2 (st_index_t)0x1b873593 1672 #define C1 BIG_CONSTANT(0x87c37b91,0x114253d5); 1673 #define C2 BIG_CONSTANT(0x4cf5ad43,0x2745937f); 1678 #if ST_INDEX_BITS <= 32 1697 #if ST_INDEX_BITS <= 32 1711 #if ST_INDEX_BITS > 64 1730 const char *data = ptr;
1734 #define data_at(n) (st_index_t)((unsigned char)data[(n)]) 1735 #define UNALIGNED_ADD_4 UNALIGNED_ADD(2); UNALIGNED_ADD(1); UNALIGNED_ADD(0) 1736 #if SIZEOF_ST_INDEX_T > 4 1737 #define UNALIGNED_ADD_8 UNALIGNED_ADD(6); UNALIGNED_ADD(5); UNALIGNED_ADD(4); UNALIGNED_ADD(3); UNALIGNED_ADD_4 1738 #if SIZEOF_ST_INDEX_T > 8 1739 #define UNALIGNED_ADD_16 UNALIGNED_ADD(14); UNALIGNED_ADD(13); UNALIGNED_ADD(12); UNALIGNED_ADD(11); \ 1740 UNALIGNED_ADD(10); UNALIGNED_ADD(9); UNALIGNED_ADD(8); UNALIGNED_ADD(7); UNALIGNED_ADD_8 1741 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_16 1743 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_8 1745 #define UNALIGNED_ADD_ALL UNALIGNED_ADD_4 1749 #if !UNALIGNED_WORD_ACCESS 1756 #ifdef WORDS_BIGENDIAN 1757 # define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \ 1758 t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 2) 1760 # define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \ 1761 t |= data_at(n) << CHAR_BIT*(n) 1764 #undef UNALIGNED_ADD 1767 #ifdef WORDS_BIGENDIAN 1781 #ifdef WORDS_BIGENDIAN 1782 t = (t << sr) | (d >> sl);
1784 t = (t >> sr) | (d << sl);
1786 h = murmur_step(h, t);
1792 pack = len < (size_t)align ? (
int)
len : align;
1795 #ifdef WORDS_BIGENDIAN 1796 # define UNALIGNED_ADD(n) case (n) + 1: \ 1797 d |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1) 1799 # define UNALIGNED_ADD(n) case (n) + 1: \ 1800 d |= data_at(n) << CHAR_BIT*(n) 1803 #undef UNALIGNED_ADD 1805 #ifdef WORDS_BIGENDIAN 1806 t = (t << sr) | (d >> sl);
1808 t = (t >> sr) | (d << sl);
1811 if (len < (
size_t)align)
goto skip_tail;
1812 # define SKIP_TAIL 1 1813 h = murmur_step(h, t);
1830 #if UNALIGNED_WORD_ACCESS && SIZEOF_ST_INDEX_T <= 8 && CHAR_BIT == 8 1832 #if SIZEOF_ST_INDEX_T > 4 1833 case 7: t |=
data_at(6) << 48;
1834 case 6: t |=
data_at(5) << 40;
1835 case 5: t |=
data_at(4) << 32;
1839 # define SKIP_TAIL 1 1841 case 3: t |=
data_at(2) << 16;
1845 #ifdef WORDS_BIGENDIAN 1846 # define UNALIGNED_ADD(n) case (n) + 1: \ 1847 t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1) 1849 # define UNALIGNED_ADD(n) case (n) + 1: \ 1850 t |= data_at(n) << CHAR_BIT*(n) 1853 #undef UNALIGNED_ADD 1858 h ^= t; h -=
ROTL(t, 7);
1863 return murmur_finish(h);
1869 return murmur_step(h, i);
1878 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8 1879 h = murmur_step(h, i >> 8*8);
1881 h = murmur_step(h, i);
1888 h = murmur_finish(h);
1892 #undef st_hash_start 1902 register const char *
string = (
const char *)arg;
1909 unsigned int c1, c2;
1912 c1 = (
unsigned char)*s1++;
1913 c2 = (
unsigned char)*s2++;
1914 if (c1 ==
'\0' || c2 ==
'\0') {
1915 if (c1 !=
'\0')
return 1;
1916 if (c2 !=
'\0')
return -1;
1919 if ((
unsigned int)(c1 -
'A') <= (
'Z' -
'A')) c1 +=
'a' -
'A';
1920 if ((
unsigned int)(c2 -
'A') <= (
'Z' -
'A')) c2 +=
'a' -
'A';
1933 unsigned int c1, c2;
1936 c1 = (
unsigned char)*s1++;
1937 c2 = (
unsigned char)*s2++;
1938 if (c1 ==
'\0' || c2 ==
'\0') {
1939 if (c1 !=
'\0')
return 1;
1940 if (c2 !=
'\0')
return -1;
1943 if ((
unsigned int)(c1 -
'A') <= (
'Z' -
'A')) c1 +=
'a' -
'A';
1944 if ((
unsigned int)(c2 -
'A') <= (
'Z' -
'A')) c2 +=
'a' -
'A';
1959 register const char *
string = (
const char *)arg;
1966 unsigned int c = (
unsigned char)*
string++;
1967 if ((
unsigned int)(c -
'A') <= (
'Z' -
'A')) c +=
'a' -
'A';
1985 enum {s1 = 11, s2 = 3};
1986 return (
st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
1998 if (siz <= get_allocated_entries(tab))
2002 n = get_allocated_entries(tab);
2041 update_range_for_deleted(tab, j);
2053 unsigned int const size_ind = get_size_ind(tab);
2057 initialize_bins(tab);
2061 #ifdef QUADRATIC_PROBE 2070 ind = hash_bin(p->
hash, tab);
2076 set_bin(bins, size_ind, ind, i +
ENTRY_BASE);
2085 update_range_for_deleted(tab, bin);
2090 #ifdef QUADRATIC_PROBE 2091 ind = hash_bin(ind + d, tab);
2094 ind = secondary_hash(ind, tab, &peterb);
2108 st_rehash_linear(tab);
2110 st_rehash_indexed(tab);
2115 st_stringify(
VALUE key)
2126 e.
hash = do_hash(k, tab);
2141 for (i = 0; i <
argc; ) {
2156 for (i = 0; i <
argc; ) {
2157 VALUE key = argv[i++];
2158 VALUE val = argv[i++];
2159 st_insert_single(tab, hash, key, val);
2184 st_expand_table(tab, n);
2186 st_insert_generic(tab, argc, argv, hash);
2188 st_insert_single(tab, hash, argv[0], argv[1]);
2190 st_insert_linear(tab, argc, argv, hash);
2192 st_insert_generic(tab, argc, argv, hash);
RUBY_EXTERN VALUE rb_cString
#define RBASIC_CLEAR_CLASS(obj)
int st_insert2(st_table *tab, st_data_t key, st_data_t value, st_data_t(*func)(st_data_t))
size_t strlen(const char *)
int st_foreach_check(st_table *tab, int(*func)(ANYARGS), st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
#define RB_OBJ_WRITTEN(a, oldv, b)
st_index_t st_hash_uint32(st_index_t h, uint32_t i)
int st_locale_insensitive_strcasecmp(const char *s1, const char *s2)
#define IND_DELETED_BIN_P(tab, i)
void rb_raise(VALUE exc, const char *fmt,...)
st_index_t st_numhash(st_data_t n)
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
#define RESERVED_HASH_SUBSTITUTION_VAL
PUREFUNC(static st_index_t strcasehash(st_data_t))
#define BIG_CONSTANT(x, y)
#define PTR_EQUAL(tab, ptr, hash_val, key_)
st_table * st_init_strcasetable_with_size(st_index_t size)
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
st_index_t st_hash_start(st_index_t h)
st_table * st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
st_table * st_init_numtable(void)
unsigned char entry_power
VALUE rb_hash_new_with_size(st_index_t size)
#define PREFETCH(addr, write_p)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
st_table * st_init_strtable_with_size(st_index_t size)
st_table * st_init_strtable(void)
void st_free_table(st_table *tab)
#define SIZEOF_ST_INDEX_T
st_table * st_init_strcasetable(void)
st_index_t st_hash_end(st_index_t h)
size_t st_memsize(const st_table *tab)
#define UNALIGNED_ADD_ALL
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
#define EXPECT(expr, val)
#define UNDEFINED_ENTRY_IND
int st_foreach(st_table *tab, int(*func)(ANYARGS), st_data_t arg)
#define RESERVED_HASH_VAL
#define IND_EMPTY_BIN_P(tab, i)
st_index_t st_keys(st_table *tab, st_data_t *keys, st_index_t size)
#define MEMCPY(p1, p2, type, n)
st_index_t(* hash)(ANYARGS)
#define MAX_POWER2_FOR_TABLES_WITHOUT_BINS
unsigned int rebuilds_num
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
st_index_t st_keys_check(st_table *tab, st_data_t *keys, st_index_t size, st_data_t never ATTRIBUTE_UNUSED)
#define MARK_BIN_DELETED(tab, i)
st_index_t st_values(st_table *tab, st_data_t *values, st_index_t size)
#define MARK_ENTRY_DELETED(e_ptr)
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
int st_shift(st_table *tab, st_data_t *key, st_data_t *value)
#define REBUILD_THRESHOLD
register unsigned int len
unsigned char entry_power
st_table * st_copy(st_table *old_tab)
int st_insert(st_table *tab, st_data_t key, st_data_t value)
int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n)
const struct st_hash_type * type
int st_delete_safe(st_table *tab, st_data_t *key, st_data_t *value, st_data_t never ATTRIBUTE_UNUSED)
int st_numcmp(st_data_t x, st_data_t y)
VALUE rb_str_new_frozen(VALUE)
st_index_t st_values_check(st_table *tab, st_data_t *values, st_index_t size, st_data_t never ATTRIBUTE_UNUSED)
void st_clear(st_table *tab)
const struct st_hash_type st_hashtype_num
#define UNDEFINED_BIN_IND
struct st_table_entry st_table_entry
#define MARK_BIN_EMPTY(tab, i)
st_index_t st_hash_uint(st_index_t h, st_index_t i)
void st_cleanup_safe(st_table *tab ATTRIBUTE_UNUSED, st_data_t never ATTRIBUTE_UNUSED)
int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
#define DELETED_ENTRY_P(e_ptr)
st_table * st_init_table(const struct st_hash_type *type)
st_table * st_init_numtable_with_size(st_index_t size)
#define EMPTY_OR_DELETED_BIN_P(b)
int st_get_key(st_table *tab, st_data_t key, st_data_t *result)