Skip to content

Conversation

@jack-dunham
Copy link

@jack-dunham jack-dunham commented Nov 24, 2025

This PR introduces a change to the DataGraphs interface. The following functions must now be overloaded for a graph to behave like a data graph:

underlying_graph(::AbstractDataGraph) = not_implemented()

has_vertex_data(::AbstractDataGraph, vertex) = not_implemented()
has_edge_data(::AbstractDataGraph, edge) = not_implemented()

get_vertex_data(::AbstractDataGraph, vertex) = not_implemented()
get_edge_data(::AbstractDataGraph, edge) = not_implemented()

set_vertex_data!(::AbstractDataGraph, data, vertex) = not_implemented()
set_edge_data!(::AbstractDataGraph, data, edge) = not_implemented()

unset_vertex_data!(::AbstractDataGraph, vertex) = not_implemented()
unset_edge_data!(::AbstractDataGraph, edge) = not_implemented()

The functions getindex , setindex! get! etc are all defined in terms of those. It is a bit more verbose than just having a function vertex_data etc that returns a mutable dictionary, but I think it is ultimately more generic. The return value of vertex_data etc is now constructed on the fly, so doing setindex!(vertex_data(g), val, vertex) will not modify the underlying graph.

The benefit of this change is that one no longer require the data on the vertices and edges to be stored as a mutable field; it can be generated on the fly. This then results in constant behavior when defining views of vertex/edge data. One can still use a mutable dictionary to store the data for a given concrete AbstractDataGraph subtype.

Other Changes

  • AbstractDataGraph now subtypes AbstractNamedGraph. This greatly reduces required method overloads.
  • Added VertexDataView and EdgeDataView objects that behave like dictionaries with respect to the graph data.
  • Added a library extension for the PartitionedGraphs package.

@jack-dunham jack-dunham marked this pull request as draft November 24, 2025 23:03
…btype `AbstractNamedGraph`

- Interface now no longer assumes vertex and edge date stored as mutable
field. Instead, requires overloading setters and getters.
- Subtyping `AbstractNamedGraph` cuts down on the method forwarding
almost entirely.
…Graph`

Tests have been adjusted accordingly.
… `getindex`

This now correctly mirrors `DataGraphs` interface.
This is in anticipation of making this change in `DataGraphs`
These are defined on the abstract type
@jack-dunham jack-dunham changed the title PartitionedGraphs extension for DataGraphs. PartitionedGraphs extension for DataGraphs and interface overhaul. Jan 9, 2026
@jack-dunham jack-dunham marked this pull request as ready for review January 9, 2026 21:34
@mtfishman mtfishman closed this Jan 12, 2026
@mtfishman mtfishman reopened this Jan 12, 2026
@mtfishman
Copy link
Member

(I closed and reopened the PR to trigger the tests since NamedGraphs.jl v0.9 is now registered.)

@mtfishman
Copy link
Member

@jack-dunham it looks like quotient_index needs to get updated to to_quotient_index.

src/dataview.jl Outdated
Comment on lines 68 to 80
function Base.copyto!(dest::VertexDataView, bc::Base.Broadcast.Broadcasted)
for (i, vertex) in enumerate(vertices(dest.graph))
dest[vertex] = bc[i]
end
return dest
end

function Base.copyto!(dest::EdgeDataView, bc::Base.Broadcast.Broadcasted)
for (i, edge) in enumerate(edges(dest.graph))
dest[edge] = bc[i]
end
return dest
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these definitions aren't quite right. I think the issue is that the ordering of the data on the vertices and edges are an implementation detail, so if you do:

g = DataGraph(["x", "y"])
# Or:
g = DataGraph(["y", "x"])
VertexDataView(g) .= [1, 2]

the results will be different from each other, i.e. the result is sensitive to the vertex ordering.

I think we should follow the example of Dictionaries.jl and only support the following:

VertexDataView(g) .= 1 # Ok since the ordering doesn't matter
VertexDataView(g) .= Dictionary(["x", "y"], [1, 2]) # Specify the ordering
VertexDataView(g)[Vertices(["x", "y"])] .= [1, 2] # Alternative to the above

which is comparable to the behavior of Dictionaries.jl:

julia> d = Dictionary(["x", "y"], [1, 2])
2-element Dictionary{String, Int64}:
 "x"1
 "y"2

julia> d .= 3
2-element Dictionary{String, Int64}:
 "x"3
 "y"3

julia> d .= Dictionary(["x", "y"], [4, 5])
2-element Dictionary{String, Int64}:
 "x"4
 "y"5

julia> d .= [4, 5] # Errors

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something slightly unfortunate about Dictionaries.jl broadcasting is that it doesn't support cases where the indices aren't ordered in the same way or where the indices being set are a subset of the dictionary that is being assigned:

julia> d = Dictionary(["x", "y"], [1, 2])
2-element Dictionary{String, Int64}:
 "x"1
 "y"2

julia> d .= Dictionary(["y", "x"], [4, 3])
ERROR: IndexError("Indices do not match")

julia> d .= Dictionary(["x"], [3])
ERROR: IndexError("Indices do not match")

so maybe we can mostly use the Dictionaries.jl broadcasting implementation (https://github.com/andyferris/Dictionaries.jl/blob/master/src/broadcast.jl) but then have a custom overload of Base.copyto!(out::VertexDataView, d::BroadcastedDictionary) that allows for those two cases.

@jack-dunham jack-dunham marked this pull request as draft January 27, 2026 15:38

# ======================== DataGraphs interface for QuotientView ========================= #

function NamedGraphs.get_graph_index(qv::QuotientView{V, <:AbstractDataGraph}, ind) where {V}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function NamedGraphs.get_graph_index(qv::QuotientView{V, <:AbstractDataGraph}, ind) where {V}
function NamedGraphs.get_graph_index(qv::QuotientView{<:Any, <:AbstractDataGraph}, ind)

Just a style thing since I don't see V used.

@jack-dunham
Copy link
Author

Seems tests are breaking; I'll check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants