diff --git a/base.go b/base.go index 583fdb3..48b335b 100644 --- a/base.go +++ b/base.go @@ -1,5 +1,7 @@ package gograph +import "sync/atomic" + // baseGraph represents a basic implementation of Graph interface. It // supports multiple types of graph. // @@ -16,6 +18,9 @@ type baseGraph[T comparable] struct { edges map[T]map[T]*Edge[T] properties GraphProperties + + verticesCount uint32 + edgesCount uint32 } func newBaseGraph[T comparable](properties GraphProperties) *baseGraph[T] { @@ -38,6 +43,7 @@ func (g *baseGraph[T]) addToEdgeMap(from, to *Vertex[T], options ...EdgeOptionFu g.edges[from.label][to.label] = edge } + atomic.AddUint32(&g.edgesCount, 1) return edge } @@ -133,6 +139,8 @@ func (g *baseGraph[T]) addVertex(v *Vertex[T]) *Vertex[T] { } g.vertices[v.label] = v + atomic.AddUint32(&g.verticesCount, 1) + return v } @@ -294,6 +302,7 @@ func (g *baseGraph[T]) removeEdge(edge *Edge[T]) { if len(destMap) == 0 { delete(g.edges, edge.source.label) } + atomic.AddUint32(&g.edgesCount, ^(uint32(1) - 1)) } } @@ -381,6 +390,7 @@ func (g *baseGraph[T]) removeVertex(in *Vertex[T]) { delete(g.edges, v.label) delete(g.vertices, v.label) + atomic.AddUint32(&g.verticesCount, ^(uint32(1) - 1)) } // ContainsEdge returns 'true' if and only if this graph contains an edge @@ -431,3 +441,13 @@ func (g *baseGraph[T]) AllEdges() []*Edge[T] { return out } + +// Order returns the number of vertices in the graph. +func (g *baseGraph[T]) Order() uint32 { + return atomic.LoadUint32(&g.verticesCount) +} + +// Size returns the number of edges in the graph +func (g *baseGraph[T]) Size() uint32 { + return atomic.LoadUint32(&g.edgesCount) +} diff --git a/base_test.go b/base_test.go index 08e5c5b..10e6bc1 100644 --- a/base_test.go +++ b/base_test.go @@ -149,6 +149,12 @@ func TestBaseGraph_AddEdgeAcyclic(t *testing.T) { g.AddVertex(v2) g.AddVertex(v3) + expectedVerticesCount := uint32(3) + actual := g.Order() + if actual != expectedVerticesCount { + t.Errorf("expected (%d) but got (%d)", expectedVerticesCount, actual) + } + // Add edges from 1 to 2 and from 2 to 3 _, err := g.AddEdge(v1, v2) if err != nil { @@ -165,6 +171,12 @@ func TestBaseGraph_AddEdgeAcyclic(t *testing.T) { if err == nil { t.Error("Expected error, but got none") } + + expectedEdgesCount := uint32(2) + actual = g.Size() + if actual != expectedEdgesCount { + t.Errorf("expected (%d) but got (%d)", expectedEdgesCount, actual) + } } func TestBaseGraph_AddEdgeWeighted(t *testing.T) { diff --git a/graph.go b/graph.go index 0a5fa9d..da46b07 100644 --- a/graph.go +++ b/graph.go @@ -113,6 +113,12 @@ type Graph[T comparable] interface { // // If the specified vertex is nil, returns 'false'. ContainsVertex(v *Vertex[T]) bool + + // Order returns the number of vertices in the graph. + Order() uint32 + + // Size returns the number of edges in the graph + Size() uint32 } // New creates a new instance of base graph that implemented the Graph interface.