Skip to content

Hashing and equality of SimpleGraphs.SimpleEdgeIter #504

@mxhbl

Description

@mxhbl

SimpleGraphs.SimpleEdgeIter implements ==, but does not have a custom Base.hash implementation, meaning that equal SimpleEdgeIters have differing hashes:

julia> using Graphs

julia> g1 = Graph(0);

julia> g2 = Graph(0);

julia> edges(g1) == edges(g2)
true

julia> hash(edges(g1)) == hash(edges(g2))
false

This breaks an important property of the == function and may lead to incorrect behavior of Dicts and Sets.

A straightforward way to fix this would be to implement something like this:

function Base.hash(edgeiter::Graphs.SimpleGraphs.SimpleEdgeIter, h::UInt)
    for edge in edgeiter
        h = hash(edge, h)
    end
    return h
end

But the problem with this is that ==(e1::SimpleEdgeIter, e2::AbstractVector{SimpleEdge}) is also defined, and the hash of a AbstractVector{SimpleEdge}, being an array, depends on the array hash seed and other Julia internals. Moreover, ==(e1::Set{SimpleEdge}, e2::SimpleEdgeIter is also defined and would imply that the value of hash(edgeiter) cannot depend on the order of the edges.

I guess the chance of this actually leading to problematic behavior is quite low, so maybe fixing this is not worth the effort. But in that case maybe the documentation of edges should warn against constructing Sets and Dicts of the returned edge iterator?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions