Skip to content

dagger is a fast, concurrency safe, mutable, in-memory directed graph library with zero dependencies

License

Notifications You must be signed in to change notification settings

hbhoyar-uber/dagger

 
 

Repository files navigation

dagger GoDoc

dag

dagger is a blazing fast, concurrency safe, mutable, in-memory directed graph implementation with zero dependencies

import "github.com/autom8ter/dagger"

Features

  • native graph objects(nodes/edges)
  • concurrency safe
  • namespaced graph objects(ex: user/pet)
  • labelled nodes & edges
  • depth first search
  • breadth first search
  • topological sort
  • import/export
  • visualization

Example

Setting Nodes

    var g = dagger.NewGraph()
	vm1 := g.SetNode(dagger.Path{
		XID:   "virtual_machine_1",
		XType: "infra",
	}, map[string]interface{}{})
	vm2 := g.SetNode(dagger.Path{
		XID:   "virtual_machine_2",
		XType: "infra",
	}, map[string]interface{}{})
	k8s := g.SetNode(dagger.Path{
		XID:   "kubernetes",
		XType: "infra",
	}, map[string]interface{}{})
	redis := g.SetNode(dagger.Path{
		XID:   "redis",
		XType: "infra",
	}, map[string]interface{}{
		"port": "6379",
	})
	mongo := g.SetNode(dagger.Path{
		XID:   "mongo",
		XType: "infra",
	}, map[string]interface{}{
		"port": "5568",
	})
	httpServer := g.SetNode(dagger.Path{
		XID:   "http",
		XType: "infra",
	}, map[string]interface{}{
		"port": "8080",
	})
	g.RangeNodes("*", func(n dagger.Node) bool {
		t.Logf("found node in graph: %s.%s\n", n.XType, n.XID)
		return true
	})

Ranging Over Nodes

    // iterate over nodes of type user
    g.RangeNodes("users", func(n dagger.Node) bool {
		t.Logf("found user node in graph: %s.%s\n", n.XType, n.XID)
		return true
	})

Setting Edges

    _, err := g.SetEdge(k8s.Path, vm1.Path, dagger.Node{
		Path: dagger.Path{
			XType: "depends_on",
		},
		Attributes: map[string]interface{}{},
	})
	if err != nil {
		t.Fatal(err)
	}
	_, err = g.SetEdge(k8s.Path, vm2.Path, dagger.Node{
		Path: dagger.Path{
			XType: "depends_on",
		},
		Attributes: map[string]interface{}{},
	})
	if err != nil {
		t.Fatal(err)
	}
	_, err = g.SetEdge(mongo.Path, redis.Path, dagger.Node{
		Path: dagger.Path{
			XType: "depends_on",
		},
		Attributes: map[string]interface{}{},
	})
	if err != nil {
		t.Fatal(err)
	}
	_, err = g.SetEdge(httpServer.Path, k8s.Path, dagger.Node{
		Path: dagger.Path{
			XType: "depends_on",
		},
		Attributes: map[string]interface{}{},
	})
	if err != nil {
		t.Fatal(err)
	}

Iterating over Edges

    g.RangeEdgesFrom("*", httpServer.Path, func(e dagger.Edge) bool {
        t.Logf("found edge in graph: %s.%s\n", e.XType, n.XID)
        return true
    })

Iterating over Edges in Reverse

    g.RangeEdgesTo("*", httpServer.Path, func(e dagger.Edge) bool {
        t.Logf("found edge in graph: %s.%s\n", e.XType, n.XID)
		return true
	})

Depth First Search

    // iterate over nodes that depend the httpServer depends on
    g.DFS("depends_on", httpServer.Path, func(node dagger.Node) bool {
		i++
		t.Logf("(%v) Reverse DFS: %s", i, node.String())
		return true
	})

Breadth First Search

    g.BFS("depends_on", httpServer.Path, func(node dagger.Node) bool {
		i++
		t.Logf("(%v) Reverse DFS: %s", i, node.String())
		return true
	})

About

dagger is a fast, concurrency safe, mutable, in-memory directed graph library with zero dependencies

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 98.3%
  • Makefile 1.7%