Skip to content

Commit b01a850

Browse files
committed
node的fetch顺序优化
1 parent 2f58ac6 commit b01a850

File tree

2 files changed

+63
-55
lines changed

2 files changed

+63
-55
lines changed

cmd/z_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func TestTotal(t *testing.T) {
155155

156156
}
157157

158-
// TestRefOnRef 暂不可用, 需要分析树节点中处理依赖节点被依赖时的优先级 //todo
158+
// TestRefOnRef
159159
func TestRefOnRef(t *testing.T) {
160160
req := `
161161
{

query/query.go

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"github.com/glennliao/apijson-go/config"
7+
"github.com/gogf/gf/v2/errors/gerror"
78
"github.com/gogf/gf/v2/frame/g"
89
"github.com/gogf/gf/v2/util/gconv"
910
"time"
@@ -62,80 +63,83 @@ func printNode(n *Node, deep int) {
6263

6364
}
6465

65-
func analysisRef(p *Node, fetchNodeQueue *[]*Node, fetchNodeQueueWithRef *[]*Node, fetchNodeQueueRefNode *[]*Node) {
66+
func analysisOrder(prerequisites [][]string) ([]string, error) {
6667

67-
// 分析依赖关系, 让无依赖的先执行, 然后在执行后续的
68-
// 需优化调整 更通用的 (目前问题点在于依赖的节点也有依赖时的优先顺序问题)
69-
for _, node := range p.children {
70-
if node.Type == NodeTypeQuery && len(node.refKeyMap) == 0 {
71-
*fetchNodeQueue = append(*fetchNodeQueue, node)
72-
} else {
73-
if node.Type == NodeTypeRef {
74-
*fetchNodeQueueRefNode = append(*fetchNodeQueueRefNode, node)
75-
} else {
76-
*fetchNodeQueueWithRef = append(*fetchNodeQueueWithRef, node)
77-
}
78-
}
79-
//if node.primaryTableKey != "" {
80-
//
81-
//} else {
82-
//
83-
//}
84-
analysisRef(node, fetchNodeQueue, fetchNodeQueueWithRef, fetchNodeQueueRefNode)
68+
var pointMap = make(map[string]bool)
69+
for _, prerequisite := range prerequisites {
70+
pointMap[prerequisite[0]] = true
71+
pointMap[prerequisite[1]] = true
8572
}
8673

87-
}
88-
89-
func (q *Query) fetch() {
90-
// 分析依赖关系
91-
92-
var fetchNodeQueue []*Node
93-
var fetchNodeQueueWithRef []*Node
94-
var fetchNodeQueueRefNode []*Node
74+
var pointNum = len(pointMap)
75+
var edgesMap = make(map[string][]string)
76+
var indeg = make(map[string]int)
77+
var result []string
9578

96-
analysisRef(q.rootNode, &fetchNodeQueue, &fetchNodeQueueWithRef, &fetchNodeQueueRefNode)
79+
for _, prerequisite := range prerequisites {
80+
edgesMap[prerequisite[1]] = append(edgesMap[prerequisite[1]], prerequisite[0])
81+
indeg[prerequisite[0]]++
82+
}
9783

98-
//fetchNodeQueue = lo.Reverse(fetchNodeQueue)
99-
//fetchNodeQueueWithRef = lo.Reverse(fetchNodeQueueWithRef)
84+
var queue []string
10085

101-
//for _, node := range fetchNodeQueueWithRef {
102-
// fmt.Printf("%s\n", node.Path)
103-
// for k, refPath := range node.refKeyMap {
104-
// fmt.Printf("%s -> %s\n", k, refPath)
105-
// }
106-
// fmt.Println("---------------------")
107-
//}
86+
for point, _ := range pointMap {
87+
if indeg[point] == 0 {
88+
queue = append(queue, point)
89+
}
90+
}
10891

109-
fmt.Println("fetch queue")
110-
for _, node := range append(fetchNodeQueue) {
111-
fmt.Printf(" 【%s】 > ", node.Path)
92+
for len(queue) > 0 {
93+
var first string
94+
first, queue = queue[0], queue[1:]
95+
result = append(result, first)
96+
for _, point := range edgesMap[first] {
97+
indeg[point]--
98+
if indeg[point] == 0 {
99+
queue = append(queue, point)
100+
}
101+
}
112102
}
113-
fmt.Println("")
114103

115-
for _, node := range append(fetchNodeQueueWithRef) {
116-
fmt.Printf(" 【%s】 > ", node.Path)
104+
if len(result) != pointNum {
105+
return nil, gerror.New("依赖循环, 请检查请求")
117106
}
118107

119-
fmt.Println("")
108+
return result, nil
120109

121-
for _, node := range append(fetchNodeQueueRefNode) {
122-
fmt.Printf(" 【%s】 > ", node.Path)
123-
}
110+
}
124111

125-
fmt.Println("")
112+
func analysisRef(p *Node, prerequisites *[][]string) {
126113

127-
for _, node := range fetchNodeQueue {
128-
node.fetch()
114+
// 分析依赖关系, 让无依赖的先执行, 然后在执行后续的
115+
for _, node := range p.children {
116+
for _, refNode := range node.refKeyMap {
117+
*prerequisites = append(*prerequisites, []string{node.Path, refNode.node.Path})
118+
}
119+
analysisRef(node, prerequisites)
129120
}
130121

131-
for _, node := range fetchNodeQueueWithRef {
132-
node.fetch()
122+
}
123+
124+
func (q *Query) fetch() {
125+
// 分析依赖关系
126+
127+
var prerequisites [][]string
128+
analysisRef(q.rootNode, &prerequisites)
129+
fetchQueue, err := analysisOrder(prerequisites)
130+
131+
if err != nil {
132+
q.err = err
133133
}
134134

135-
for _, node := range fetchNodeQueueRefNode {
136-
node.fetch()
135+
fmt.Println("fetch queue")
136+
for _, path := range fetchQueue {
137+
fmt.Printf(" 【%s】 > ", path)
137138
}
138139

140+
for _, path := range fetchQueue {
141+
q.pathNodes[path].fetch()
142+
}
139143
}
140144

141145
func (q *Query) Result() (g.Map, error) {
@@ -163,6 +167,10 @@ func (q *Query) Result() (g.Map, error) {
163167

164168
q.fetch()
165169

170+
if q.err != nil {
171+
return nil, err
172+
}
173+
166174
resultMap, err := q.rootNode.Result()
167175

168176
if err != nil {

0 commit comments

Comments
 (0)