Skip to content

Commit

Permalink
add a dirty flag to Dict
Browse files Browse the repository at this point in the history
makes `get!` work with default functions that modify the dict. fixes #9573
  • Loading branch information
JeffBezanson committed Jan 4, 2015
1 parent c355304 commit f064838
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,11 @@ type Dict{K,V} <: Associative{K,V}
ndel::Int
count::Int
deleter::Function
dirty::Bool

function Dict()
n = 16
new(zeros(UInt8,n), Array(K,n), Array(V,n), 0, 0, identity)
new(zeros(UInt8,n), Array(K,n), Array(V,n), 0, 0, identity, false)
end
function Dict(kv)
h = Dict{K,V}()
Expand Down Expand Up @@ -424,6 +425,7 @@ function rehash!{K,V}(h::Dict{K,V}, newsz = length(h.keys))
oldv = h.vals
sz = length(olds)
newsz = _tablesz(newsz)
h.dirty = true
if h.count == 0
resize!(h.slots, newsz)
fill!(h.slots, 0)
Expand Down Expand Up @@ -490,6 +492,7 @@ function empty!{K,V}(h::Dict{K,V})
resize!(h.vals, sz)
h.ndel = 0
h.count = 0
h.dirty = true
return h
end

Expand Down Expand Up @@ -561,6 +564,7 @@ function _setindex!(h::Dict, v, key, index)
h.keys[index] = key
h.vals[index] = v
h.count += 1
h.dirty = true

sz = length(h.keys)
# Rehash now if necessary
Expand Down Expand Up @@ -614,8 +618,17 @@ function get!{K,V}(default::Callable, h::Dict{K,V}, key0)

index > 0 && return h.vals[index]

h.dirty = false
v = convert(V, default())
_setindex!(h, v, key, -index)
if h.dirty
index = ht_keyindex2(h, key)
end
if index > 0
h.keys[index] = key
h.vals[index] = v
else
_setindex!(h, v, key, -index)
end
return v
end

Expand Down Expand Up @@ -684,6 +697,7 @@ function _delete!(h::Dict, index)
ccall(:jl_arrayunset, Void, (Any, UInt), h.vals, index-1)
h.ndel += 1
h.count -= 1
h.dirty = true
h
end

Expand Down

0 comments on commit f064838

Please sign in to comment.