-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathtree.go
89 lines (79 loc) · 1.8 KB
/
tree.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
package nestedset
type Tree struct {
Children []*TreeNode
data map[int64]*TreeNode
}
type TreeNode struct {
*nestedItem
Children []*TreeNode
}
func initTree(items []*nestedItem) *Tree {
tree := &Tree{
data: make(map[int64]*TreeNode),
Children: make([]*TreeNode, 0),
}
for _, item := range items {
node := &TreeNode{
nestedItem: item,
Children: make([]*TreeNode, 0),
}
tree.data[node.ID] = node
}
for _, item := range items {
node, _ := tree.getNode(item.ID)
parent, found := tree.getNode(item.ParentID.Int64)
if !found {
tree.Children = append(tree.Children, node)
} else {
parent.Children = append(parent.Children, node)
}
}
return tree
}
func (tree *Tree) getNode(id int64) (node *TreeNode, found bool) {
if id == 0 {
return nil, false
}
node, found = tree.data[id]
return
}
func (tree *Tree) addNestedItem(item *nestedItem) {
node := &TreeNode{
nestedItem: item,
Children: make([]*TreeNode, 0),
}
parent, found := tree.getNode(item.ParentID.Int64)
if !found {
tree.Children = append(tree.Children, node)
} else {
parent.Children = append(parent.Children, node)
}
}
func (tree *Tree) rebuild() *Tree {
count, depth := 0, 0
for _, node := range tree.Children {
count = travelNode(node, count, depth)
}
return tree
}
func travelNode(node *TreeNode, lft, depth int) int {
original := &nestedItem{
ID: node.ID,
ParentID: node.ParentID,
Depth: node.Depth,
Lft: node.Lft,
Rgt: node.Rgt,
ChildrenCount: node.ChildrenCount,
}
lft += 1
node.Lft = lft
node.ChildrenCount = len(node.Children)
node.Depth = depth
for _, childNode := range node.Children {
lft = travelNode(childNode, lft, depth+1)
}
lft += 1
node.Rgt = lft
node.IsChanged = node.nestedItem.IsPositionSame(original)
return lft
}