Skip to content

Commit

Permalink
Merge pull request #653 from eulerkochy/robin-fix-1
Browse files Browse the repository at this point in the history
Remove import statement from robin_dict.jl
  • Loading branch information
eulerkochy committed Aug 18, 2020
2 parents aca8a5e + c6d57cf commit e3c9c56
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 35 deletions.
3 changes: 2 additions & 1 deletion src/DataStructures.jl
Expand Up @@ -12,7 +12,8 @@ module DataStructures
isless, union, intersect, symdiff, setdiff, issubset,
searchsortedfirst, searchsortedlast, in,
eachindex, keytype, valtype, minimum, maximum, size,
zero, checkbounds
zero, checkbounds, filter!, isbitstype, isbitsunion,
isiterable, dict_with_eltype, KeySet, Callable, _tablesz


using Compat # Provides Base.Order.ReverseOrdering(). May remove this line with julia 1.4
Expand Down
24 changes: 5 additions & 19 deletions src/robin_dict.jl
@@ -1,8 +1,3 @@
import Base: setindex!, sizehint!, empty!, isempty, length, copy, empty,
getindex, getkey, haskey, iterate, @propagate_inbounds, merge,
pop!, delete!, get, get!, isbitstype, in, hashindex, isbitsunion,
isiterable, dict_with_eltype, KeySet, Callable, _tablesz, filter!

# the load factor after which the dictionary `rehash` happens
const ROBIN_DICT_LOAD_FACTOR = 0.70

Expand Down Expand Up @@ -237,8 +232,8 @@ function sizehint!(d::RobinDict, newsz)
rehash!(d, newsz)
end

@propagate_inbounds isslotfilled(h::RobinDict, index) = (h.hashes[index] != 0)
@propagate_inbounds isslotempty(h::RobinDict, index) = (h.hashes[index] == 0)
Base.@propagate_inbounds isslotfilled(h::RobinDict, index) = (h.hashes[index] != 0)
Base.@propagate_inbounds isslotempty(h::RobinDict, index) = (h.hashes[index] == 0)


function setindex!(h::RobinDict{K,V}, v0, key0) where {K, V}
Expand Down Expand Up @@ -579,15 +574,6 @@ function delete!(h::RobinDict{K, V}, key0) where {K, V}
return h
end

function get_idxfloor(h::RobinDict)
@inbounds for i = 1:length(h.keys)
if isslotfilled(h, i)
return i
end
end
return 0
end

function get_next_filled(h::RobinDict, i)
L = length(h.keys)
(1 <= i <= L) || return 0
Expand All @@ -599,11 +585,11 @@ function get_next_filled(h::RobinDict, i)
return 0
end

@propagate_inbounds _iterate(t::RobinDict{K,V}, i) where {K,V} = i == 0 ? nothing : (Pair{K,V}(t.keys[i],t.vals[i]), i == typemax(Int) ? 0 : get_next_filled(t, i+1))
@propagate_inbounds function iterate(t::RobinDict)
Base.@propagate_inbounds _iterate(t::RobinDict{K,V}, i) where {K,V} = i == 0 ? nothing : (Pair{K,V}(t.keys[i],t.vals[i]), i == typemax(Int) ? 0 : get_next_filled(t, i+1))
Base.@propagate_inbounds function iterate(t::RobinDict)
_iterate(t, t.idxfloor)
end
@propagate_inbounds iterate(t::RobinDict, i) = _iterate(t, get_next_filled(t, i))
Base.@propagate_inbounds iterate(t::RobinDict, i) = _iterate(t, get_next_filled(t, i))

filter!(f, d::RobinDict) = Base.filter_in_one_pass!(f, d)

Expand Down
50 changes: 35 additions & 15 deletions test/test_robin_dict.jl
@@ -1,5 +1,3 @@
include("../src/robin_dict.jl")

@testset "Constructors" begin
h1 = RobinDict()
@test length(h1) == 0
Expand Down Expand Up @@ -349,19 +347,6 @@ end
@test length(h) == 0
end

@testset "get_idxfloor" begin
h = RobinDict()
@test get_idxfloor(h) == 0

h["a"] = 1
h[2] = "b"
@test h.idxfloor == get_idxfloor(h)
pop!(h)
@test h.idxfloor == get_idxfloor(h)
pop!(h)
@test h.idxfloor == get_idxfloor(h) == 0
end

@testset "merge" begin
h1 = RobinDict("a" => 1, "b" => 2)
h2 = RobinDict("c" => 3, "d" => 4)
Expand All @@ -385,6 +370,28 @@ end
end

@testset "invariants" begin
# Functions which are not exported, but are required for checking invariants
hash_key(key) = (hash(key)%UInt32) | 0x80000000
desired_index(hash, sz) = (hash & (sz - 1)) + 1
isslotfilled(h::RobinDict, index) = (h.hashes[index] != 0)
isslotempty(h::RobinDict, index) = (h.hashes[index] == 0)

function calculate_distance(h::RobinDict{K, V}, index) where {K, V}
@assert isslotfilled(h, index)
sz = length(h.keys)
@inbounds index_init = desired_index(h.hashes[index], sz)
return (index - index_init + sz) & (sz - 1)
end

function get_idxfloor(h::RobinDict)
@inbounds for i = 1:length(h.keys)
if isslotfilled(h, i)
return i
end
end
return 0
end

h1 = RobinDict{Int, Int}()
for i in 1:300
h1[i] = i
Expand Down Expand Up @@ -452,4 +459,17 @@ end
h[i] = i+1
end
check_invariants(h)

@testset "get_idxfloor" begin
h = RobinDict()
@test get_idxfloor(h) == 0

h["a"] = 1
h[2] = "b"
@test h.idxfloor == get_idxfloor(h)
pop!(h)
@test h.idxfloor == get_idxfloor(h)
pop!(h)
@test h.idxfloor == get_idxfloor(h) == 0
end
end

0 comments on commit e3c9c56

Please sign in to comment.