Multigraphs via an edge index and edge properties/metadata #81
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Starting work to implement #18 as well as #54 for some of my own use cases. Looks like some planning work went into these in the past so not sure if there's a more preferred approach.
Ran into a performance use case for multigraphs where to minimize enumeration on traversals for I wanted an index of edge label sets to trade some space for time.
Current approach
A map
edge_index: %{edge_index_key => MapSet.t()}
to store the sets of of edge keys:edge_key :: {vertex_id, vertex_id}
.Since the trade-off of space for time shouldn't be assumed by default it's optional with
Graph.new(multigraph: true)
where an override-ableedge_indexer: (Edge.t() -> edge_index_key)
is invoked during edge addition but only whenmultigraph
istrue
. The default indexer builds sets ofedge_keys
by thelabel
. This lets the sets be built off of theweight
or other edge properties.For metadata / edge properties changing the edge value from
%{label => edge_weight}
toas well as adding the
properties
map to the%Edge{}
struct.Finally to use the index - reflection / traversal APIs can be extended for predicates such as
Graph.out_edges(graph, :a, :foo)
wheremultigraph: true
it returns the subset of edges in the index by the key:foo
. Not 100% on the API - something more explicit likeGraph.out_edges(graph, :a, label: :foo)
might be preferred so it can be used without multigraphs or where a function to filter the edges by can be passed in.Todos:
fn %{label: label} -> label end
to return the key