Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Phodal
Coca
提交
e1d0f108
C
Coca
项目概览
Phodal
/
Coca
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Coca
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
e1d0f108
编写于
7月 20, 2020
作者:
P
Phodal Huang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: use trie for render
上级
8a19030f
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
157 addition
and
33 deletion
+157
-33
pkg/application/arch/tequila/incl_viz.go
pkg/application/arch/tequila/incl_viz.go
+14
-20
pkg/application/arch/tequila/incl_viz_test.go
pkg/application/arch/tequila/incl_viz_test.go
+14
-13
pkg/application/arch/tequila/trie/common.go
pkg/application/arch/tequila/trie/common.go
+53
-0
pkg/application/arch/tequila/trie/path_trie.go
pkg/application/arch/tequila/trie/path_trie.go
+76
-0
未找到文件。
pkg/application/arch/tequila/incl_viz.go
浏览文件 @
e1d0f108
...
...
@@ -2,7 +2,7 @@ package tequila
import
(
"github.com/awalterschulze/gographviz"
"github.com/
dghubble
/trie"
"github.com/
phodal/coca/pkg/application/arch/tequila
/trie"
"sort"
"strconv"
"strings"
...
...
@@ -153,7 +153,7 @@ func (fullGraph *FullGraph) ToDot(split string, include func(string) bool) *gogr
return
graph
}
func
(
fullGraph
*
FullGraph
)
ToMapDot
(
node
*
GraphNod
e
)
*
gographviz
.
Graph
{
func
(
fullGraph
*
FullGraph
)
ToMapDot
(
trie
*
trie
.
PathTri
e
)
*
gographviz
.
Graph
{
graph
:=
gographviz
.
NewGraph
()
_
=
graph
.
SetName
(
"G"
)
...
...
@@ -161,7 +161,9 @@ func (fullGraph *FullGraph) ToMapDot(node *GraphNode) *gographviz.Graph {
fullGraph
.
layerIndex
=
1
fullGraph
.
nodeIndex
=
1
fullGraph
.
buildGraphNode
(
"G"
,
node
,
graph
,
nodes
)
for
_
,
child
:=
range
trie
.
Children
{
fullGraph
.
buildGraphNode
(
"G"
,
child
,
graph
,
nodes
)
}
for
key
:=
range
fullGraph
.
RelationList
{
relation
:=
fullGraph
.
RelationList
[
key
]
...
...
@@ -179,18 +181,18 @@ func (fullGraph *FullGraph) ToMapDot(node *GraphNode) *gographviz.Graph {
return
graph
}
func
(
fullGraph
*
FullGraph
)
buildGraphNode
(
subgraph
string
,
current
*
GraphNod
e
,
graph
*
gographviz
.
Graph
,
nodes
map
[
string
]
string
)
{
layerAttr
,
layerName
:=
buildLayerAttr
(
current
.
text
,
fullGraph
.
layerIndex
)
func
(
fullGraph
*
FullGraph
)
buildGraphNode
(
subgraph
string
,
current
*
trie
.
PathTri
e
,
graph
*
gographviz
.
Graph
,
nodes
map
[
string
]
string
)
{
layerAttr
,
layerName
:=
buildLayerAttr
(
current
.
Value
,
fullGraph
.
layerIndex
)
_
=
graph
.
AddSubGraph
(
subgraph
,
layerName
,
layerAttr
)
fullGraph
.
layerIndex
++
if
len
(
current
.
c
hildren
)
>
0
{
for
_
,
child
:=
range
current
.
c
hildren
{
if
len
(
current
.
C
hildren
)
>
0
{
for
_
,
child
:=
range
current
.
C
hildren
{
fullGraph
.
buildGraphNode
(
layerName
,
child
,
graph
,
nodes
)
}
}
else
{
_
=
graph
.
AddNode
(
subgraph
,
"node"
+
strconv
.
Itoa
(
fullGraph
.
nodeIndex
),
fullGraph
.
buildRelationAttr
(
current
.
text
))
nodes
[
current
.
text
]
=
"node"
+
strconv
.
Itoa
(
fullGraph
.
nodeIndex
)
_
=
graph
.
AddNode
(
subgraph
,
"node"
+
strconv
.
Itoa
(
fullGraph
.
nodeIndex
),
fullGraph
.
buildRelationAttr
(
current
.
Value
))
nodes
[
current
.
Value
]
=
"node"
+
strconv
.
Itoa
(
fullGraph
.
nodeIndex
)
fullGraph
.
nodeIndex
++
}
}
...
...
@@ -200,21 +202,13 @@ type GraphNode struct {
children
[]
*
GraphNode
}
func
(
fullGraph
*
FullGraph
)
BuildMapTree
(
split
string
,
include
func
(
key
string
)
bool
)
*
GraphNode
{
graphNode
:=
&
GraphNode
{}
func
(
fullGraph
*
FullGraph
)
BuildMapTree
(
include
func
(
key
string
)
bool
)
*
trie
.
PathTrie
{
pkgTrie
:=
trie
.
NewPathTrie
()
for
nodeKey
:=
range
fullGraph
.
NodeList
{
pkgTrie
.
Put
(
strings
.
ReplaceAll
(
nodeKey
,
"."
,
"/"
),
0
)
}
for
nodeKey
:=
range
fullGraph
.
NodeList
{
tmp
:=
strings
.
Split
(
nodeKey
,
split
)
graphNode
.
text
=
tmp
[
0
]
graphNode
=
buildNode
(
tmp
[
1
:
],
graphNode
)
pkgTrie
.
Put
(
strings
.
ReplaceAll
(
nodeKey
,
"."
,
"/"
))
}
return
graphNod
e
return
pkgTri
e
}
...
...
pkg/application/arch/tequila/incl_viz_test.go
浏览文件 @
e1d0f108
...
...
@@ -2,13 +2,15 @@ package tequila
import
(
.
"github.com/onsi/gomega"
"github.com/phodal/coca/cmd/cmd_util"
"github.com/phodal/coca/pkg/application/arch/tequila/trie"
"testing"
)
func
createBasicMap
()
(
*
GraphNod
e
,
*
FullGraph
)
{
func
createBasicMap
()
(
*
trie
.
PathTri
e
,
*
FullGraph
)
{
fullGraph
,
nodeFilter
:=
createGraph
()
node
:=
fullGraph
.
BuildMapTree
(
"."
,
nodeFilter
)
node
:=
fullGraph
.
BuildMapTree
(
nodeFilter
)
return
node
,
fullGraph
}
...
...
@@ -40,30 +42,29 @@ func Test_BuildGraphNode(t *testing.T) {
g
:=
NewGomegaWithT
(
t
)
node
,
_
:=
createBasicMap
()
g
.
Expect
(
node
.
text
)
.
To
(
Equal
(
"com"
))
children
:=
node
.
children
g
.
Expect
(
len
(
children
))
.
To
(
Equal
(
2
))
g
.
Expect
(
len
(
node
.
Children
[
"com"
]
.
Children
))
.
To
(
Equal
(
2
))
}
func
Test_ShouldMergeSameMap
(
t
*
testing
.
T
)
{
g
:=
NewGomegaWithT
(
t
)
fullGraph
,
nodeFilter
:=
createGraph
()
fullGraph
.
NodeList
[
"com.phodal.coca"
]
=
"com.phodal.coca"
node
:=
fullGraph
.
BuildMapTree
(
"."
,
nodeFilter
)
node
:=
fullGraph
.
BuildMapTree
(
nodeFilter
)
g
.
Expect
(
node
.
text
)
.
To
(
Equal
(
"com"
))
children
:=
node
.
children
g
.
Expect
(
len
(
children
))
.
To
(
Equal
(
3
))
g
.
Expect
(
len
(
node
.
Children
[
"com"
]
.
Children
))
.
To
(
Equal
(
2
))
}
func
Test_BuildNodeDot
(
t
*
testing
.
T
)
{
g
:=
NewGomegaWithT
(
t
)
node
,
graph
:=
createBasicMap
()
graph
,
nodeFilter
:=
createGraph
()
graph
.
NodeList
[
"com.phodal.coca"
]
=
"com.phodal.coca"
node
:=
graph
.
BuildMapTree
(
nodeFilter
)
dot
:=
graph
.
ToMapDot
(
node
)
//
result := dot.String()
//
cmd_util.WriteToCocaFile("demo.dot", result)
result
:=
dot
.
String
()
cmd_util
.
WriteToCocaFile
(
"demo.dot"
,
result
)
g
.
Expect
(
len
(
dot
.
SubGraphs
.
SubGraphs
))
.
To
(
Equal
(
5
))
g
.
Expect
(
len
(
dot
.
SubGraphs
.
SubGraphs
))
.
To
(
Equal
(
6
))
g
.
Expect
(
len
(
dot
.
Nodes
.
Nodes
))
.
To
(
Equal
(
2
))
}
pkg/application/arch/tequila/trie/common.go
0 → 100644
浏览文件 @
e1d0f108
// https://github.com/dghubble/trie
//The MIT License (MIT)
//
//Copyright (c) 2014 Dalton Hubble
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package
trie
import
(
"strings"
)
// WalkFunc defines some action to take on the given key and Value during
// a Trie Walk. Returning a non-nil error will terminate the Walk.
type
WalkFunc
func
(
key
string
,
value
interface
{})
error
// StringSegmenter takes a string key with a starting index and returns
// the first segment after the start and the ending index. When the end is
// reached, the returned nextIndex should be -1.
// Implementations should NOT allocate heap memory as Trie Segmenters are
// called upon Gets. See PathSegmenter.
type
StringSegmenter
func
(
key
string
,
start
int
)
(
segment
string
,
nextIndex
int
)
// PathSegmenter segments string key paths by slash separators. For example,
// "/a/b/c" -> ("/a", 2), ("/b", 4), ("/c", -1) in successive calls. It does
// not allocate any heap memory.
func
PathSegmenter
(
path
string
,
start
int
)
(
segment
string
,
next
int
)
{
if
len
(
path
)
==
0
||
start
<
0
||
start
>
len
(
path
)
-
1
{
return
""
,
-
1
}
end
:=
strings
.
IndexRune
(
path
[
start
+
1
:
],
'/'
)
// next '/' after 0th rune
if
end
==
-
1
{
return
path
[
start
:
],
-
1
}
return
path
[
start
:
start
+
end
+
1
],
start
+
end
+
1
}
pkg/application/arch/tequila/trie/path_trie.go
0 → 100644
浏览文件 @
e1d0f108
// https://github.com/dghubble/trie
//The MIT License (MIT)
//
//Copyright (c) 2014 Dalton Hubble
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package
trie
import
"strings"
type
PathTrie
struct
{
segmenter
StringSegmenter
// key segmenter, must not cause heap allocs
Value
string
Children
map
[
string
]
*
PathTrie
}
// PathTrieConfig for building a path trie with different segmenter
type
PathTrieConfig
struct
{
Segmenter
StringSegmenter
}
// NewPathTrie allocates and returns a new *PathTrie.
func
NewPathTrie
()
*
PathTrie
{
return
&
PathTrie
{
segmenter
:
PathSegmenter
,
}
}
// NewPathTrieWithConfig allocates and returns a new *PathTrie with the given *PathTrieConfig
func
NewPathTrieWithConfig
(
config
*
PathTrieConfig
)
*
PathTrie
{
segmenter
:=
PathSegmenter
if
config
!=
nil
&&
config
.
Segmenter
!=
nil
{
segmenter
=
config
.
Segmenter
}
return
&
PathTrie
{
segmenter
:
segmenter
,
}
}
func
(
trie
*
PathTrie
)
Put
(
key
string
)
{
node
:=
trie
for
part
,
i
:=
trie
.
segmenter
(
key
,
0
);
part
!=
""
;
part
,
i
=
trie
.
segmenter
(
key
,
i
)
{
child
,
_
:=
node
.
Children
[
part
]
if
child
==
nil
{
if
node
.
Children
==
nil
{
node
.
Children
=
map
[
string
]
*
PathTrie
{}
}
child
=
NewPathTrie
()
node
.
Children
[
part
]
=
child
}
child
.
Value
=
strings
.
ReplaceAll
(
part
,
"/"
,
""
)
node
=
child
}
// does node have an existing Value?
//isNewVal := node.Value == nil
//return isNewVal
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录