On Thursday, July 16, 2015 at 12:19:25 PM UTC-4, milktrader wrote:Also, back to the OP question, is the correct solution to simply defineBase.hash(f::Foo) = f.xNo, I'd define Base.hash(f::Foo) = hash(f.x, 0x64c74221932dea5b), where I chose the constant by rand(UInt). This way it won't collide with other types. I really need to spend a bit more time with my interfaces chapter and add this info there.
const _foo_seed = UInt === UInt64 ? 0x64c74221932dea5b : 0x80783eb4
Base.hash(f::Foo) = hash(f.x, _foo_seed)On Thursday, July 16, 2015 at 12:19:25 PM UTC-4, milktrader wrote:Also, back to the OP question, is the correct solution to simply defineBase.hash(f::Foo) = f.xNo, I'd define Base.hash(f::Foo) = hash(f.x, 0x64c74221932dea5b), where I chose the constant by rand(UInt). This way it won't collide with other types. I really need to spend a bit more time with my interfaces chapter and add this info there.
immutable Foo{T}
x::T
y::T
end
Base.hash(f::Foo) = hash(hash(f.x, f.y), 0x64c74221932dea5b)const _foo_seed = UInt === UInt64 ? 0x64c74221932dea5b : 0x80783eb4
Base.hash(f::Foo, h::UInt) = hash(f.x, h += _foo_seed)
type Foo{T}
x::T
y::T
end
Base.hash(f::Foo) = hash(f.x, hash(f.y, pair_seed))type Mutablex::IntendBase.hash(m::Mutable, h::UInt) = hash(m.x, h + (0x17d88030d571c6e3 % UInt))==(m1::Mutable, m2::Mutable) = m1.x == m2.xjulia> m = Mutable(0)Mutable(0)julia> d = Dict()Dict{Any,Any} with 0 entriesjulia> d[m] = "here""here"julia> m.x = 11julia> d[m]ERROR: KeyError: Mutable(1) not foundin getindex at dict.jl:695julia> dDict{Any,Any} with 1 entry:Mutable(1) => "here"
On Thursday, July 16, 2015 at 12:19:25 PM UTC-4, milktrader wrote:Also, back to the OP question, is the correct solution to simply defineBase.hash(f::Foo) = f.xNo, I'd define Base.hash(f::Foo) = hash(f.x, 0x64c74221932dea5b), where I chose the constant by rand(UInt). This way it won't collide with other types. I really need to spend a bit more time with my interfaces chapter and add this info there.
On Thursday, July 16, 2015 at 12:07:50 PM UTC-4, Seth wrote:If I'm reading between the lines correctly, the default/existing hash function is based on the last byte of the ID? Is there a reason we don't make the table wider to reduce the chances of collisions (or would this have bad effects on memory utilization)?It's not really a hash collision, but rather a hashtable index collision. A new dict only has 16 slots for its keys, and the index for an element is simply chosen by the last 8 bits of its hash. If those last 8 bits match the hash of an object already in the table, there's a collision, and the Dict checks to see if the existing element `isequal` to the new one (and doesn't look at the hash again). So the hashes are different, but isequal says the objects are the same. This is why things are wonky.
I wonder if this is something the linter could detect.