113 lines
2.0 KiB
Go
113 lines
2.0 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type graphBuilder struct {
|
||
|
refs Refs
|
||
|
nodeMap NodeMap
|
||
|
nodes []Node
|
||
|
edges []Edge
|
||
|
}
|
||
|
|
||
|
type NodeMap map[string]int
|
||
|
|
||
|
func NewGraphBuilder(mp PagesRepository) (*graphBuilder, error) {
|
||
|
refs := make(Refs)
|
||
|
|
||
|
f, err := os.Open(filepath.Join(mp.(*FilePages).dirname, "backrefs.json"))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
defer f.Close()
|
||
|
|
||
|
err = json.NewDecoder(f).Decode(&refs)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
nodeMap := prepareNodeMap(refs)
|
||
|
return &graphBuilder{
|
||
|
refs: refs,
|
||
|
nodeMap: nodeMap,
|
||
|
nodes: nil,
|
||
|
edges: nil,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (gb *graphBuilder) prepareGraph() error {
|
||
|
gb.nodes = prepareNodes(gb.nodeMap)
|
||
|
gb.edges = prepareEdges(gb.refs, gb.nodeMap)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (gb *graphBuilder) RemoveNode(name string) {
|
||
|
delete(gb.nodeMap, name)
|
||
|
}
|
||
|
|
||
|
func (gb *graphBuilder) RemoveNodeWithSuffix(suffix string) {
|
||
|
for k, _ := range gb.nodeMap {
|
||
|
if strings.HasSuffix(k, suffix) {
|
||
|
delete(gb.nodeMap, k)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func prepareEdges(refs Refs, nodeMap NodeMap) []Edge {
|
||
|
var edges []Edge
|
||
|
edgeSet := make(map[Edge]bool)
|
||
|
for key, references := range refs {
|
||
|
if toID, e := nodeMap[key]; e {
|
||
|
for _, item := range references {
|
||
|
if fromID, e := nodeMap[item.Name]; e {
|
||
|
edge := Edge{
|
||
|
From: fromID,
|
||
|
To: toID,
|
||
|
}
|
||
|
if _, e := edgeSet[edge]; !e {
|
||
|
edgeSet[edge] = true
|
||
|
edges = append(edges, edge)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return edges
|
||
|
}
|
||
|
|
||
|
func prepareNodes(nodeMap NodeMap) []Node {
|
||
|
var nodes []Node
|
||
|
for name, id := range nodeMap {
|
||
|
nodes = append(nodes, Node{
|
||
|
Id: id,
|
||
|
Label: name,
|
||
|
})
|
||
|
}
|
||
|
return nodes
|
||
|
}
|
||
|
|
||
|
func prepareNodeMap(refs Refs) NodeMap {
|
||
|
nodeCount := 1
|
||
|
nodeMap := make(NodeMap)
|
||
|
|
||
|
for key, references := range refs {
|
||
|
if _, e := nodeMap[key]; !e {
|
||
|
nodeMap[key] = nodeCount
|
||
|
nodeCount += 1
|
||
|
}
|
||
|
for _, item := range references {
|
||
|
if _, e := nodeMap[item.Name]; !e {
|
||
|
nodeMap[item.Name] = nodeCount
|
||
|
nodeCount += 1
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nodeMap
|
||
|
}
|