diff --git a/lib/graph/graph.go b/lib/graph/graph.go new file mode 100644 index 0000000..92f287f --- /dev/null +++ b/lib/graph/graph.go @@ -0,0 +1,85 @@ +package graph + +//Node a graph node which can contain Connections to other nodes +type Node struct { + Value string + Incoming []*Node + Outgoing []*Node +} + +//SetPointTo sets this Node to point towards the given Node +func (n *Node) SetPointTo(otherNode *Node) { + if n.IsPointingTo(otherNode) == false { + n.Outgoing = append(n.Outgoing, otherNode) + } +} + +//RemovePointerTo removes pointer to a node (a "child") +func (n *Node) RemovePointerTo(otherNode *Node) int { + i := n.GetIndexOfOut(otherNode) + if i != -1 { + n.Outgoing = append(n.Outgoing[:i], n.Outgoing[i+1:]...) + return i + } + return -1 +} + +//IsPointingTo returns true if this node is pointing to the given argument +func (n *Node) IsPointingTo(otherNode *Node) bool { + if n.GetIndexOfOut(otherNode) != -1 { + return true + } + return false +} + +//Disconnect disconnects two nodes by removing pointers for BOTH +func (n *Node) Disconnect(otherNode *Node) int { + i := n.GetIndexOfOut(otherNode) + j := otherNode.GetIndexOfOut(n) + if i != -1 && j != -1 { + //if n is pointing to otherNode + //remove othernode from n.Outgoing, and remove n from otherNode.Outgoing + n.Outgoing = append(n.Outgoing[:i], n.Outgoing[i+1:]...) + otherNode.Outgoing = append(otherNode.Outgoing[:j], otherNode.Outgoing[j+1:]...) + return 1 + } + i = n.GetIndexOfIn(otherNode) + j = otherNode.GetIndexOfIn(n) + if i!= -1 && j != -1 { + //else if otherNode point to n + // remove otherNode from n.Incoming, and remove n from otherNode.Incoming + n.Incoming = append(n.Incoming[:i], n.Incoming[i+1:]...) + otherNode.Incoming = append(otherNode.Incoming[:j], otherNode.Incoming[j+1:]...) + return 1 + } + return -1 +} + +//DisconnectAll removes all pointer from and to this Node +func (n *Node) DisconnectAll() { + for _, v := range n.Outgoing { + n.Disconnect(v) + } +} + + +//GetIndexOfOut gets the index of the specified node that this node points to +//May alternatively be used to check if n is pointing to otherNode +func (n *Node) GetIndexOfOut(otherNode *Node) int { + for i, v := range n.Outgoing { + if v == otherNode { //addresses are compared + return i + } + } + return -1 +} + +//GetIndexOfIn gets the index of the specified node which points to this node +func (n *Node) GetIndexOfIn(otherNode *Node) int { + for i, v := range n.Incoming { + if v == otherNode { //addresses are compared + return i + } + } + return -1 +}