Skip to content

Add VertexDataGraph and EdgeDataGraph as concrete subtypes of AbstractVertexOrEdgeDataGraph#121

Open
jack-dunham wants to merge 23 commits into
mainfrom
jd/vertex-edge-datagraph
Open

Add VertexDataGraph and EdgeDataGraph as concrete subtypes of AbstractVertexOrEdgeDataGraph#121
jack-dunham wants to merge 23 commits into
mainfrom
jd/vertex-edge-datagraph

Conversation

@jack-dunham
Copy link
Copy Markdown
Contributor

@jack-dunham jack-dunham commented May 15, 2026

This point of this abstract interface is to allow the partial implementation of the Dictionaries.jl interface, on these graph types.

  1. Adds VertexDataGraph and EdgeDataGraph as concrete subtypes of AbstractVertexOrEdgeDataGraph
  2. Also adds AbstractVertexDataGraph and AbstractEdgeDataGraph interfaces.
  3. A new interface function insert_vertex_data that should be overloaded if a given AbstractVertexDataGraph graph isinsertable. See below as to why the analogous interface function doesn't exist for AbstractEdgeDataGraph.

A subtype of AbstractVertexOrEdgeDataGraph implements a stricter indexing interface, inline with the one used by Dictionaries.jl, that is setindex! strictly sets existing indices (doesn't add a vertex/edge that isn't already in the graph). One should use insert! to strictly add a new vertex/edge with data, and set! to perform an upsert (previous behavior of setindex!.

Eventually, this interface will be applied to AbstractDataGraph, but to avoid breaking changes this is deferred until a later date.

Subtleties

Difference in setindex! for vertex and edge data

The setindex! function on an AbstractEdgeDataGraph should add an edge if doesn't exist already. This is unlike setindex! for an AbstractVertexDataGraph, which errors if there vertex is not present. This is in analogy to SparseArrays:

In [36]: rn = sprand(4,4,0.25)
Out[36]: 4×4 SparseMatrixCSC{Float64, Int64} with 5 stored entries:
 0.859026  0.421836      0.719378
                         
          0.105066        
          0.181513        

In [37]: rn_dst = similar(rn, axes(rn))
Out[37]: 4×4 SparseMatrixCSC{Float64, Int64} with 0 stored entries:
               
               
               
               

In [38]: copyto!(rn_dst, rn)
Out[38]: 4×4 SparseMatrixCSC{Float64, Int64} with 5 stored entries:
 0.859026  0.421836      0.719378
                         
          0.105066        
          0.181513        

For an edge data graph, setindex! will only error if the vertices associated to an edge aren't present (irrespective of the existence of an edge).

Difference in insert! and delete! for vertex and edge data

For a vertex data graph, the function insert! inserts a vertex with data, erroring if it already exits. For an edge data graph, insert! also inserts the required vertices and then adds the edge with data, erroring if both vertices are already present. That is, insert! errors where setindex! would not error. The function delete! deletes the edge and data only, leaving the data untouched.

Interface differences

For a settable and insertable vertex data graph, one must define:

set_vertex_data!(graph, vertex, data) # set the vertex data (assuming the vertex exists)
insert_vertex_data!(graph, vertex, data) # insert the vertex data (assuming the vertex _does not_ exist)

An edge data graph only needs:

set_edge_data!(graph, edge, data) # set the edge data (assuming the required vertices exists)

As insert! is defined in terms of add_vertex! and set! (which can create edges).

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

❌ Patch coverage is 82.21477% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.35%. Comparing base (69a86af) to head (fae5876).

Files with missing lines Patch % Lines
src/abstractedgeorvertexdatagraph.jl 75.16% 37 Missing ⚠️
src/abstractdatagraph.jl 59.25% 11 Missing ⚠️
src/vertexdatagraph.jl 92.85% 4 Missing ⚠️
src/edgedatagraph.jl 98.43% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #121      +/-   ##
==========================================
+ Coverage   59.89%   66.35%   +6.46%     
==========================================
  Files          10       13       +3     
  Lines         566      853     +287     
==========================================
+ Hits          339      566     +227     
- Misses        227      287      +60     
Flag Coverage Δ
docs 0.00% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/edgedatagraph.jl Outdated
Comment thread src/vertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/edgedatagraph.jl Outdated
Comment thread src/abstractdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractdatagraph.jl Outdated
Comment thread src/edgedatagraph.jl Outdated
Comment thread src/vertexdatagraph.jl Outdated
Comment thread src/vertexdatagraph.jl Outdated
Comment thread src/abstractdatagraph.jl
Comment on lines +455 to +458
function GraphsExtensions.forest_cover_edge_sequence(graph::AbstractDataGraph; kwargs...)
dummy_graph = add_edges!(NamedGraph(vertices(graph)), edges(graph))
return GraphsExtensions.forest_cover_edge_sequence(dummy_graph; kwargs...)
end
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this needed? Shouldn't the generic definition "just work"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No because it's going to try and remove edges and that might not be defined. It is easier to just construct a dummy named graph as all this function does is return a list of edges.

Really it should return a list of edges of the same type as the input graph, though so maybe this needs to be rethought.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see. Probably that means that function should be rewritten to "just work" even for AbstractDataGraph, i.e. at worst it could first call add_edges!(NamedGraph(vertices(graph)), edges(graph)) and then run the rest of the function.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

To be honest I accidentally introduced an infinite method dispatch loop w.r.t this function in NamedGraphs so I need to make another PR anyway...

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