diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-01-18 23:19:47 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-01-18 23:19:47 +0900 |
| commit | 0661ebb66988ce6d5e2104ab1c8acf63666c5370 (patch) | |
| tree | bc85d11b7f60e83a5d74cd892bd05cf522771292 | |
| parent | e4fc42ea115a481845b68b8fd6d8dca95c81a17c (diff) | |
| parent | dd81de49a6114dc725a1991d052a056dc5b53649 (diff) | |
| download | mruby-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.c | 22 |
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); |
