From b4e6dd77812bdba5bc83f5b5d4e9be452afeb0cb Mon Sep 17 00:00:00 2001 From: Dominik Tomasi Date: Tue, 20 Feb 2024 18:31:29 +0100 Subject: [PATCH] feat: add method that returns all vertices Signed-off-by: Dominik Tomasi --- directed.go | 4 ++++ graph.go | 3 +++ store.go | 18 ++++++++++++++++-- undirected.go | 4 ++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/directed.go b/directed.go index a044194c..1481fa64 100644 --- a/directed.go +++ b/directed.go @@ -75,6 +75,10 @@ func (d *directed[K, T]) RemoveVertex(hash K) error { return d.store.RemoveVertex(hash) } +func (d *directed[K, T]) Vertices() map[K]T { + return d.store.AllVertices() +} + func (d *directed[K, T]) AddEdge(sourceHash, targetHash K, options ...func(*EdgeProperties)) error { _, _, err := d.store.Vertex(sourceHash) if err != nil { diff --git a/graph.go b/graph.go index 9376eb5f..7609c39b 100644 --- a/graph.go +++ b/graph.go @@ -99,6 +99,9 @@ type Graph[K comparable, T any] interface { // be returned. If the vertex doesn't exist, ErrVertexNotFound is returned. RemoveVertex(hash K) error + // Vertices returns a copy of all vertices as map + Vertices() map[K]T + // AddEdge creates an edge between the source and the target vertex. // // If either vertex cannot be found, ErrVertexNotFound will be returned. If diff --git a/store.go b/store.go index e41a7506..0792c98b 100644 --- a/store.go +++ b/store.go @@ -2,6 +2,7 @@ package graph import ( "fmt" + "maps" "sync" ) @@ -25,6 +26,9 @@ type Store[K comparable, T any] interface { // ErrVertexHasEdges should be returned. RemoveVertex(hash K) error + // AllVertices returns a map, containing all vertices + AllVertices() map[K]T + // ListVertices should return all vertices in the graph in a slice. ListVertices() ([]K, error) @@ -75,8 +79,8 @@ type memoryStore[K comparable, T any] struct { // outEdges and inEdges store all outgoing and ingoing edges for all vertices. For O(1) access, // these edges themselves are stored in maps whose keys are the hashes of the target vertices. - outEdges map[K]map[K]Edge[K] // source -> target - inEdges map[K]map[K]Edge[K] // target -> source + outEdges map[K]map[K]Edge[K] // source -> target + inEdges map[K]map[K]Edge[K] // target -> source edgeCount int } @@ -103,6 +107,16 @@ func (s *memoryStore[K, T]) AddVertex(k K, t T, p VertexProperties) error { return nil } +func (s *memoryStore[K, T]) AllVertices() map[K]T { + out := make(map[K]T, len(s.vertices)) + s.lock.RLock() + defer s.lock.RUnlock() + + maps.Copy(out, s.vertices) + + return out +} + func (s *memoryStore[K, T]) ListVertices() ([]K, error) { s.lock.RLock() defer s.lock.RUnlock() diff --git a/undirected.go b/undirected.go index 519526e8..80c35f0e 100644 --- a/undirected.go +++ b/undirected.go @@ -56,6 +56,10 @@ func (u *undirected[K, T]) RemoveVertex(hash K) error { return u.store.RemoveVertex(hash) } +func (u *undirected[K, T]) Vertices() map[K]T { + return u.store.AllVertices() +} + func (u *undirected[K, T]) AddEdge(sourceHash, targetHash K, options ...func(*EdgeProperties)) error { if _, _, err := u.store.Vertex(sourceHash); err != nil { return fmt.Errorf("could not find source vertex with hash %v: %w", sourceHash, err)