-
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathsimple_tree_grow_spreader.go
More file actions
105 lines (88 loc) · 2.74 KB
/
Copy pathsimple_tree_grow_spreader.go
File metadata and controls
105 lines (88 loc) · 2.74 KB
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
//go:build !tinywasm
package gtree
import (
"io"
)
func newGrowSpreaderSimple(
lastNodeFormat, intermedialNodeFormat *branchFormat,
) growSpreaderSimple {
return &defaultGrowSpreaderSimple{
defaultGrowerSimple: &defaultGrowerSimple{
lastNodeFormat: lastNodeFormat,
intermedialNodeFormat: intermedialNodeFormat,
enabledValidation: false,
},
}
}
type defaultGrowSpreaderSimple struct {
*defaultGrowerSimple
w io.Writer
}
func (dgs *defaultGrowSpreaderSimple) growAndSpread(w io.Writer, roots []*Node) error {
dgs.w = w
for _, root := range roots {
if err := dgs.assembleAndPrint(root); err != nil {
return err
}
}
return nil
}
func (dgs *defaultGrowSpreaderSimple) assembleAndPrint(current *Node) error {
if err := dgs.assembleBranch(current); err != nil {
return err
}
if current.isRoot() {
_, _ = io.WriteString(dgs.w, current.value)
_, _ = io.WriteString(dgs.w, "\n")
} else {
_, _ = io.WriteString(dgs.w, current.branch())
_, _ = io.WriteString(dgs.w, " ")
_, _ = io.WriteString(dgs.w, current.value)
_, _ = io.WriteString(dgs.w, "\n")
}
for _, child := range current.children {
if err := dgs.assembleAndPrint(child); err != nil {
return err
}
}
return nil
}
// 以降、simple_tree_grower.go の assembleBranch系メソッドとの違いは、setPathの有無
// こっちのメソッドはOutputFromRootからプログラム的に呼び出されるもので、パフォーマンスを気にする必要がある
// そして、Node.setPathの有無でベンチマークを取ると、ない方が圧倒的に改善がみられた
// setPathが必要なのはMkdir系関数なので、こちらのメソッドにはsetPath(と関連の処理)は不要なため落としている
func (dgs *defaultGrowSpreaderSimple) assembleBranch(current *Node) error {
current.clean()
dgs.assembleBranchDirectly(current)
// go back to the root to form a branch.
tmpParent := current.parent
if tmpParent != nil {
for ; !tmpParent.isRoot(); tmpParent = tmpParent.parent {
dgs.assembleBranchIndirectly(current, tmpParent)
}
}
return nil
}
func (dgs *defaultGrowSpreaderSimple) assembleBranchDirectly(current *Node) {
if current == nil || current.isRoot() {
return
}
if current.isLastOfHierarchy() {
current.appendBranch(dgs.lastNodeFormat.directly)
} else {
current.appendBranch(dgs.intermedialNodeFormat.directly)
}
}
func (dgs *defaultGrowSpreaderSimple) assembleBranchIndirectly(current, parent *Node) {
if current == nil || parent == nil || current.isRoot() {
return
}
if parent.isLastOfHierarchy() {
current.prependBranch(dgs.lastNodeFormat.indirectly)
} else {
current.prependBranch(dgs.intermedialNodeFormat.indirectly)
}
}
var (
_ growSpreaderSimple = (*defaultGrowSpreaderSimple)(nil)
)