diff --git a/src/libponyrt/ds/hash.c b/src/libponyrt/ds/hash.c index 13fb003256e..5decc0dfc6d 100644 --- a/src/libponyrt/ds/hash.c +++ b/src/libponyrt/ds/hash.c @@ -114,7 +114,6 @@ static void resize(hashmap_t* map, cmp_fn cmp, alloc_fn alloc, static size_t optimize_item(hashmap_t* map, alloc_fn alloc, free_size_fn fr, cmp_fn cmp, size_t old_index) { - size_t mask = map->size - 1; size_t h = map->buckets[old_index].hash; @@ -133,17 +132,26 @@ static size_t optimize_item(hashmap_t* map, alloc_fn alloc, ib_index = index >> HASHMAP_BITMAP_TYPE_BITS; ib_offset = index & HASHMAP_BITMAP_TYPE_MASK; - // don't need to check probe counts for filled buckets because - // earlier items are guaranteed to have a lower probe count - // than us and we cannot displace them - // found an earlier empty bucket so move item if((map->item_bitmap[ib_index] & ((bitmap_t)1 << ib_offset)) == 0) { ponyint_hashmap_clearindex(map, old_index); ponyint_hashmap_putindex(map, entry, h, cmp, alloc, fr, index); return 1; } - + else + { + size_t item_probe_length = + get_probe_length(map, h, index, mask); + size_t there_probe_length = + get_probe_length(map, map->buckets[index].hash, index, mask); + + if (item_probe_length > there_probe_length) + { + ponyint_hashmap_clearindex(map, old_index); + ponyint_hashmap_putindex(map, entry, h, cmp, alloc, fr, index); + return 1; + } + } // find next bucket index index = (index + 1) & mask; }