-
Notifications
You must be signed in to change notification settings - Fork 16
/
edge.go
130 lines (115 loc) · 2.63 KB
/
edge.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package graph
// Edge is a relationship between two nodes
type Edge interface {
// An edge implements Node because it has an Identifier and attributes
Node
// From returns the root node of the edge
From() Node
// To returns the target node of the edge
To() Node
}
type edge struct {
Node
from Node
to Node
}
func (e *edge) From() Node {
return e.from
}
func (e *edge) To() Node {
return e.to
}
// Edges is a map of edges. Edges are not concurrency safe.
type Edges map[string]map[string]Edge
func (e Edges) Types() []string {
var typs []string
for t, _ := range e {
typs = append(typs, t)
}
return typs
}
// RangeType executes the function over a list of edges with the given type. If the function returns false, the iteration stops.
func (e Edges) RangeType(typ string, fn func(e Edge) bool) {
if e[typ] == nil {
return
}
for _, e := range e[typ] {
if !fn(e) {
break
}
}
}
// Range executes the function over every edge. If the function returns false, the iteration stops.
func (e Edges) Range(fn func(e Edge) bool) {
for _, m := range e {
for _, e := range m {
if !fn(e) {
break
}
}
}
}
// Filter executes the function over every edge. If the function returns true, the edges will be added to the returned array of edges.
func (e Edges) Filter(fn func(e Edge) bool) []Edge {
var edges []Edge
for _, m := range e {
for _, e := range m {
if fn(e) {
edges = append(edges, e)
}
}
}
return edges
}
// FilterType executes the function over every edge of the given type. If the function returns true, the edges will be added to the returned array of edges.
func (e Edges) FilterType(typ string, fn func(e Edge) bool) []Edge {
var edges []Edge
if e[typ] == nil {
return edges
}
for _, e := range e[typ] {
if fn(e) {
edges = append(edges, e)
}
}
return edges
}
// DelEdge deletes the edge
func (e Edges) DelEdge(id ID) {
if _, ok := e[id.Type()]; !ok {
return
}
delete(e[id.Type()], id.ID())
}
// AddEdge adds the edge to the map
func (e Edges) AddEdge(edge Edge) {
if _, ok := e[edge.Type()]; !ok {
e[edge.Type()] = map[string]Edge{
edge.ID(): edge,
}
} else {
e[edge.Type()][edge.ID()] = edge
}
}
// HasEdge returns true if the edge exists
func (e Edges) HasEdge(id ID) bool {
_, ok := e.GetEdge(id)
return ok
}
// GetEdge gets an edge by id
func (e Edges) GetEdge(id ID) (Edge, bool) {
if _, ok := e[id.Type()]; !ok {
return nil, false
}
if e, ok := e[id.Type()][id.ID()]; ok {
return e, true
}
return nil, false
}
// Len returns the number of edges of the given type
func (e Edges) Len(typ string) int {
if rels, ok := e[typ]; ok {
return len(rels)
}
return 0
}