Skip to content

Commit

Permalink
Dict: decrement h.ndel when overwriting deleted entry (JuliaLang#47825
Browse files Browse the repository at this point in the history
)

Fixes JuliaLang#47823 by decrementing `h.ndel` when overwriting deleted entries as well as making sure to not add unnecessary tombstones when deleting.

Co-authored-by: Christian Rorvik <[email protected]>
Co-authored-by: Petr Vana <[email protected]
  • Loading branch information
oscardssmith and ancapdev committed Dec 11, 2022
1 parent 827b165 commit f082329
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ end
ht_keyindex2!(h::Dict, key) = ht_keyindex2_shorthash!(h, key)[1]

@propagate_inbounds function _setindex!(h::Dict, v, key, index, sh = _shorthash7(hash(key)))
h.ndel -= isslotmissing(h, index)
h.slots[index] = sh
h.keys[index] = key
h.vals[index] = v
Expand Down Expand Up @@ -629,13 +630,30 @@ function pop!(h::Dict)
end

function _delete!(h::Dict{K,V}, index) where {K,V}
@inbounds h.slots[index] = 0x7f
@inbounds _unsetindex!(h.keys, index)
@inbounds _unsetindex!(h.vals, index)
h.ndel += 1
@inbounds begin
slots = h.slots
sz = length(slots)
_unsetindex!(h.keys, index)
_unsetindex!(h.vals, index)
# if the next slot is empty we don't need a tombstone
# and can remove all tombstones that were required by the element we just deleted
ndel = 1
nextind = (index & (sz-1)) + 1
if isslotempty(h, nextind)
while true
ndel -= 1
slots[index] = 0x00
index = ((index - 2) & (sz-1)) + 1
isslotmissing(h, index) || break
end
else
slots[index] = 0x7f
end
h.ndel += ndel
h.count -= 1
h.age += 1
return h
end
end

"""
Expand Down

0 comments on commit f082329

Please sign in to comment.