Skip to content

Commit

Permalink
Add model graph
Browse files Browse the repository at this point in the history
  • Loading branch information
oanatmaria committed Oct 11, 2023
1 parent 12aee9c commit 9933df7
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
69 changes: 69 additions & 0 deletions graph/graph.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package graph

type Graph struct {
nodes []string
adjMatrix [][]string
}

func NewGraph() *Graph {
return &Graph{
nodes: make([]string, 0),
adjMatrix: make([][]string, 0),
}
}

func (g *Graph) AddNode(nodeName string) {
for _, vertexName := range g.nodes {
if nodeName == vertexName {
return
}
}
g.nodes = append(g.nodes, nodeName)
g.adjMatrix = append(g.adjMatrix, make([]string, 0))
}

func (g *Graph) AddEdge(source, dest, edgeName string) {
sourceIndex := g.findVertexIndexByName(source)
destIndex := g.findVertexIndexByName(dest)
if destIndex == -1 || sourceIndex == -1 {
return
}

if len(g.adjMatrix[sourceIndex]) == 0 {
g.adjMatrix[sourceIndex] = make([]string, len(g.nodes))
}

g.adjMatrix[sourceIndex][destIndex] = edgeName
}

func (g *Graph) dFS(source int, visited []bool, traversal []string) []string {
visited[source] = true
traversal = append(traversal, g.nodes[source])
for i := 0; i < len(g.nodes); i++ {
if len(g.adjMatrix[source]) != 0 && g.adjMatrix[source][i] != "" && !visited[i] {
traversal = append(traversal, g.adjMatrix[source][i])
traversal = g.dFS(i, visited, traversal)
}
}
return traversal
}

func (g *Graph) TraverseGraph(startVertex string) []string {
visited := make([]bool, len(g.nodes))
traversal := make([]string, 0)
startIndex := g.findVertexIndexByName(startVertex)
if startIndex == -1 {
return traversal
}

return g.dFS(startIndex, visited, traversal)
}

func (g *Graph) findVertexIndexByName(name string) int {
for index, vertexName := range g.nodes {
if vertexName == name {
return index
}
}
return -1
}
22 changes: 22 additions & 0 deletions model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"encoding/json"
"io"
"time"

"github.com/aserto-dev/azm/graph"
)

const ModelVersion int = 1
Expand Down Expand Up @@ -77,6 +79,26 @@ func New(r io.Reader) (*Model, error) {
return &m, nil
}

func (m *Model) GetGraph() *graph.Graph {
grph := graph.NewGraph()
for objectName := range m.Objects {
grph.AddNode(string(objectName))
}
for objectName, obj := range m.Objects {
for relName, rel := range obj.Relations {
for _, rl := range rel {
if string(rl.Direct) != "" {
grph.AddEdge(string(objectName), string(rl.Direct), string(relName))
} else if rl.Subject != nil {
grph.AddEdge(string(objectName), string(rl.Subject.Object), string(relName))
}
}
}
}

return grph
}

func (m *Model) Reader() (io.Reader, error) {
b := bytes.Buffer{}
enc := json.NewEncoder(&b)
Expand Down
10 changes: 10 additions & 0 deletions model/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,13 @@ func TestDiff(t *testing.T) {
require.Equal(t, len(diffm1m3.Removed.Relations), 1)
require.Equal(t, diffm1m3.Removed.Relations["document"], []model.RelationName{"parent_folder"})
}

func TestGraph(t *testing.T) {
graph := m1.GetGraph()

traversal := graph.TraverseGraph("document")
require.Equal(t, len(traversal), 5)
traversal = graph.TraverseGraph("group")
require.Equal(t, len(traversal), 3)
require.Equal(t, traversal, []string{"group", "member", "user"})
}

0 comments on commit 9933df7

Please sign in to comment.