Started implementing the graph
This commit is contained in:
parent
c63fd27867
commit
1fd59e6156
7
main.go
7
main.go
|
@ -23,7 +23,7 @@ var (
|
|||
wsserverForNodes *websocketserver.Server
|
||||
respondDaemon *respond.Daemon
|
||||
nodes = models.NewNodes()
|
||||
aliases = models.NewNodes()
|
||||
//aliases = models.NewNodes()
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -35,10 +35,11 @@ func main() {
|
|||
saveInterval := time.Second * time.Duration(config.Nodes.SaveInterval)
|
||||
|
||||
if config.Nodes.Enable {
|
||||
go nodes.Saver(config.Nodes.NodesPath, saveInterval)
|
||||
go nodes.Saver(config.Nodes.NodesPath, config.Nodes.GraphsPath, saveInterval)
|
||||
}
|
||||
if config.Nodes.AliasesEnable {
|
||||
go aliases.Saver(config.Nodes.AliasesPath, saveInterval)
|
||||
// FIXME what does this do?
|
||||
//go aliases.Saver(config.Nodes.AliasesPath, saveInterval)
|
||||
}
|
||||
|
||||
if config.Webserver.Enable {
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Graph struct {
|
||||
Version int `json:"version"`
|
||||
Batadv struct {
|
||||
Links []*GraphLink `json:"links"`
|
||||
} `json:"batadv"`
|
||||
}
|
||||
|
||||
type GraphLink struct {
|
||||
Source string `json:"source"`
|
||||
Target string `json:"target"`
|
||||
VPN bool `json:"vpn"`
|
||||
TQ float32 `json:"tq"`
|
||||
Bidirect bool `json:"bidirect"`
|
||||
}
|
||||
|
||||
type GraphBuilder struct {
|
||||
macToID map[string]string // mapping from MAC address to node id
|
||||
links map[string]*GraphLink // mapping from $idA-$idB to existing link
|
||||
}
|
||||
|
||||
func (nodes *Nodes) BuildGraph() *Graph {
|
||||
builder := &GraphBuilder{
|
||||
macToID: make(map[string]string),
|
||||
links: make(map[string]*GraphLink),
|
||||
}
|
||||
|
||||
builder.readNodes(nodes.List)
|
||||
|
||||
graph := &Graph{Version: 2}
|
||||
graph.Batadv.Links = builder.Links()
|
||||
return graph
|
||||
}
|
||||
|
||||
func (builder *GraphBuilder) readNodes(nodes map[string]*Node) {
|
||||
// Fill mac->id map
|
||||
for sourceId, node := range nodes {
|
||||
if neighbours := node.Neighbours; neighbours != nil {
|
||||
for sourceAddress, _ := range neighbours.Batadv {
|
||||
builder.macToID[sourceAddress] = sourceId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add links
|
||||
for sourceId, node := range nodes {
|
||||
if neighbours := node.Neighbours; neighbours != nil {
|
||||
for _, batadvNeighbours := range neighbours.Batadv {
|
||||
for targetAddress, link := range batadvNeighbours.Neighbours {
|
||||
if targetId, found := builder.macToID[targetAddress]; found {
|
||||
builder.addLink(targetId, sourceId, link.Tq)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (builder *GraphBuilder) Links() []*GraphLink {
|
||||
i := 0
|
||||
links := make([]*GraphLink, len(builder.links))
|
||||
|
||||
for _, link := range builder.links {
|
||||
links[i] = link
|
||||
i += 1
|
||||
}
|
||||
return links
|
||||
}
|
||||
|
||||
func (builder *GraphBuilder) addLink(targetId string, sourceId string, linkTq int) {
|
||||
// Order IDs to get generate the key
|
||||
var key string
|
||||
if strings.Compare(sourceId, targetId) > 0 {
|
||||
key = fmt.Sprintf("%s-%s", sourceId, targetId)
|
||||
} else {
|
||||
key = fmt.Sprintf("%s-%s", targetId, sourceId)
|
||||
}
|
||||
|
||||
var tq float32
|
||||
if linkTq > 0 {
|
||||
tq = float32(1.0 / (float32(linkTq) / 255.0))
|
||||
}
|
||||
|
||||
if link, ok := builder.links[key]; !ok {
|
||||
builder.links[key] = &GraphLink{
|
||||
Source: sourceId,
|
||||
Target: targetId,
|
||||
TQ: tq,
|
||||
}
|
||||
} else {
|
||||
// Use lowest of both link qualities
|
||||
if tq < link.TQ {
|
||||
link.TQ = tq
|
||||
}
|
||||
link.Bidirect = true
|
||||
}
|
||||
}
|
|
@ -62,25 +62,25 @@ func (nodes *Nodes) Get(nodeID string) *Node {
|
|||
}
|
||||
|
||||
// Saves the cached DB to json file periodically
|
||||
func (nodes *Nodes) Saver(outputFile string, saveInterval time.Duration) {
|
||||
func (nodes *Nodes) Saver(nodesPath string, graphPath string, saveInterval time.Duration) {
|
||||
c := time.Tick(saveInterval)
|
||||
|
||||
for range c {
|
||||
nodes.save(outputFile)
|
||||
}
|
||||
}
|
||||
|
||||
func (nodes *Nodes) save(outputFile string) {
|
||||
log.Println("saving", len(nodes.List), "nodes")
|
||||
nodes.Timestamp = time.Now()
|
||||
|
||||
nodes.Lock()
|
||||
data, err := json.Marshal(nodes)
|
||||
save(nodes, nodesPath)
|
||||
save(nodes.BuildGraph(), graphPath)
|
||||
nodes.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func save(input interface{}, outputFile string) {
|
||||
data, err := json.Marshal(input)
|
||||
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
log.Println("saving", len(nodes.List), "nodes")
|
||||
|
||||
tmpFile := outputFile + ".tmp"
|
||||
|
||||
|
|
Loading…
Reference in New Issue