summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-01-18 23:19:47 +0900
committerGitHub <[email protected]>2021-01-18 23:19:47 +0900
commit0661ebb66988ce6d5e2104ab1c8acf63666c5370 (patch)
treebc85d11b7f60e83a5d74cd892bd05cf522771292
parente4fc42ea115a481845b68b8fd6d8dca95c81a17c (diff)
parentdd81de49a6114dc725a1991d052a056dc5b53649 (diff)
downloadmruby-0661ebb66988ce6d5e2104ab1c8acf63666c5370.tar.gz
mruby-0661ebb66988ce6d5e2104ab1c8acf63666c5370.zip
Merge pull request #5294 from shuujii/fix-that-Hash-may-not-contain-any-empty-buckets
Fix that Hash may not contain any empty buckets
-rw-r--r--src/hash.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/src/hash.c b/src/hash.c
index 8ca2f666e..3195c3e7e 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -52,10 +52,10 @@
* the number of used slots and the number of empty slots.
*/
+#define EA_N_RESERVED_INDICES 2 /* empty and deleted */
#define EA_INCREASE_RATIO 6 / 5 + 6
#define EA_MAX_INCREASE UINT16_MAX
-#define EA_MAX_CAPA /* `- 2` means reserved indices (empty and deleted) */ \
- U32(lesser(IB_MAX_CAPA - 2, MRB_INT_MAX))
+#define EA_MAX_CAPA U32(lesser(IB_MAX_CAPA - EA_N_RESERVED_INDICES, MRB_INT_MAX))
#define IB_MAX_CAPA (U32(1) << IB_MAX_BIT)
#define IB_TYPE_BIT 32
#define IB_INIT_BIT ( \
@@ -360,7 +360,7 @@ ea_next_capa_for(uint32_t size, uint32_t max_capa)
}
else {
/*
- * For 32-bit CPU, the theoretical value of max EA capa is
+ * For 32-bit CPU, the theoretical value of maximum EA capacity is
* `UINT32_MAX / sizeof (hash_entry)`. At this time, if
* `EA_INCREASE_RATIO` is the current value, 32-bit range will not be
* exceeded during the calculation of `capa`, so `size_t` is used.
@@ -839,12 +839,16 @@ ht_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
if (size != ht_ea_n_used(h)) ea_compress(ht_ea(h), ht_ea_n_used(h));
ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ++ib_bit_width);
}
- else if (ht_ea_capa(h) == ht_ea_n_used(h) && size != ht_ea_n_used(h)) {
- if (size <= AR_MAX_SIZE) {ht_set_as_ar(mrb, h, key, val); return;}
- if (ea_next_capa_for(size, EA_MAX_CAPA) <= ht_ea_capa(h)) {
- ea_compress(ht_ea(h), ht_ea_n_used(h));
- ht_adjust_ea(mrb, h, size, ht_ea_capa(h));
- ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ib_bit_width);
+ else if (size != ht_ea_n_used(h)) {
+ if (ib_capa - EA_N_RESERVED_INDICES <= ht_ea_n_used(h)) goto compress;
+ if (ht_ea_capa(h) == ht_ea_n_used(h)) {
+ if (size <= AR_MAX_SIZE) {ht_set_as_ar(mrb, h, key, val); return;}
+ if (ea_next_capa_for(size, EA_MAX_CAPA) <= ht_ea_capa(h)) {
+ compress:
+ ea_compress(ht_ea(h), ht_ea_n_used(h));
+ ht_adjust_ea(mrb, h, size, ht_ea_capa(h));
+ ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ib_bit_width);
+ }
}
}
ht_set_without_ib_adjustment(mrb, h, key, val);