Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
eacf19dc
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
eacf19dc
编写于
12月 11, 2015
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use a flat contiguous array of characters for the BKTree instead of thousands of small char arrays.
上级
48589ea8
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
65 addition
and
32 deletion
+65
-32
src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs
...le/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs
+1
-1
src/Workspaces/Core/Portable/Utilities/ArraySlice.cs
src/Workspaces/Core/Portable/Utilities/ArraySlice.cs
+5
-0
src/Workspaces/Core/Portable/Utilities/BKTree.Builder.cs
src/Workspaces/Core/Portable/Utilities/BKTree.Builder.cs
+40
-21
src/Workspaces/Core/Portable/Utilities/BKTree.Node.cs
src/Workspaces/Core/Portable/Utilities/BKTree.Node.cs
+7
-5
src/Workspaces/Core/Portable/Utilities/BKTree.Serialization.cs
...orkspaces/Core/Portable/Utilities/BKTree.Serialization.cs
+4
-1
src/Workspaces/Core/Portable/Utilities/BKTree.cs
src/Workspaces/Core/Portable/Utilities/BKTree.cs
+8
-4
未找到文件。
src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs
浏览文件 @
eacf19dc
...
...
@@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols
internal
partial
class
SymbolTreeInfo
:
IObjectWritable
{
private
const
string
PrefixMetadataSymbolTreeInfo
=
"<MetadataSymbolTreeInfoPersistence>_"
;
private
const
string
SerializationFormat
=
"
5
"
;
private
const
string
SerializationFormat
=
"
6
"
;
/// <summary>
/// this is for a metadata reference in a solution
...
...
src/Workspaces/Core/Portable/Utilities/ArraySlice.cs
浏览文件 @
eacf19dc
...
...
@@ -4,6 +4,7 @@
using
System.Linq
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Text
;
namespace
Roslyn.Utilities
{
...
...
@@ -19,6 +20,10 @@ public ArraySlice(T[] array) : this(array, 0, array.Length)
{
}
public
ArraySlice
(
T
[]
array
,
TextSpan
span
)
:
this
(
array
,
span
.
Start
,
span
.
Length
)
{
}
public
ArraySlice
(
T
[]
array
,
int
start
,
int
length
)
:
this
()
{
_array
=
array
;
...
...
src/Workspaces/Core/Portable/Utilities/BKTree.Builder.cs
浏览文件 @
eacf19dc
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Diagnostics
;
using
System.Linq
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.Text
;
namespace
Roslyn.Utilities
{
...
...
@@ -13,7 +16,8 @@ private class Builder
{
private
const
int
CompactEdgeAllocationSize
=
4
;
private
readonly
char
[][]
_values
;
private
readonly
char
[]
_allLowerCaseCharacters
;
private
readonly
TextSpan
[]
_characterSpans
;
// Note: while building a BKTree we have to store children with parents, keyed by the
// edit distance between the two. Naive implementations might store a list or dictionary
...
...
@@ -73,21 +77,35 @@ private class Builder
public
Builder
(
IEnumerable
<
string
>
values
)
{
_values
=
values
.
Select
(
v
=>
v
.
ToLower
())
.
Distinct
()
.
Select
(
v
=>
v
.
ToCharArray
())
.
Where
(
a
=>
a
.
Length
>
0
).
ToArray
();
var
distinctValues
=
values
.
Where
(
v
=>
v
.
Length
>
0
).
Distinct
(
CaseInsensitiveComparison
.
Comparer
).
ToArray
();
var
charCount
=
Enumerable
.
Sum
<
string
>(
values
,(
Func
<
string
,
int
>)(
v
=>
(
int
)
v
.
Length
));
_allLowerCaseCharacters
=
new
char
[
charCount
];
_characterSpans
=
new
TextSpan
[
distinctValues
.
Length
];
var
characterIndex
=
0
;
for
(
int
i
=
0
;
i
<
distinctValues
.
Length
;
i
++)
{
var
value
=
distinctValues
[
i
];
_characterSpans
[
i
]
=
new
TextSpan
(
characterIndex
,
value
.
Length
);
foreach
(
var
ch
in
value
)
{
_allLowerCaseCharacters
[
characterIndex
]
=
char
.
ToLower
(
ch
);
characterIndex
++;
}
}
// We will have one node for each string value that we are adding.
_builderNodes
=
new
BuilderNode
[
_v
alues
.
Length
];
_compactEdges
=
new
Edge
[
_v
alues
.
Length
*
CompactEdgeAllocationSize
];
_builderNodes
=
new
BuilderNode
[
distinctV
alues
.
Length
];
_compactEdges
=
new
Edge
[
distinctV
alues
.
Length
*
CompactEdgeAllocationSize
];
}
internal
BKTree
Create
()
{
for
(
var
i
=
0
;
i
<
_
value
s
.
Length
;
i
++)
for
(
var
i
=
0
;
i
<
_
characterSpan
s
.
Length
;
i
++)
{
Add
(
_
value
s
[
i
],
insertionIndex
:
i
);
Add
(
_
characterSpan
s
[
i
],
insertionIndex
:
i
);
}
var
nodes
=
new
Node
[
_builderNodes
.
Length
];
...
...
@@ -98,7 +116,7 @@ internal BKTree Create()
BuildArrays
(
nodes
,
edges
);
return
new
BKTree
(
nodes
,
edges
);
return
new
BKTree
(
_allLowerCaseCharacters
,
nodes
,
edges
);
}
private
void
BuildArrays
(
Node
[]
nodes
,
Edge
[]
edges
)
...
...
@@ -109,8 +127,7 @@ private void BuildArrays(Node[] nodes, Edge[] edges)
var
builderNode
=
_builderNodes
[
i
];
var
edgeCount
=
builderNode
.
EdgeCount
;
nodes
[
i
]
=
new
Node
(
builderNode
.
LowerCaseCharacters
,
edgeCount
,
currentEdgeIndex
);
nodes
[
i
]
=
new
Node
(
builderNode
.
CharacterSpan
,
edgeCount
,
currentEdgeIndex
);
if
(
edgeCount
>
0
)
{
...
...
@@ -140,11 +157,11 @@ private void BuildArrays(Node[] nodes, Edge[] edges)
Debug
.
Assert
(
currentEdgeIndex
==
edges
.
Length
);
}
private
void
Add
(
char
[]
lowerCaseCharacters
,
int
insertionIndex
)
private
void
Add
(
TextSpan
characterSpan
,
int
insertionIndex
)
{
if
(
insertionIndex
==
0
)
{
_builderNodes
[
insertionIndex
]
=
new
BuilderNode
(
lowerCaseCharacters
);
_builderNodes
[
insertionIndex
]
=
new
BuilderNode
(
characterSpan
);
return
;
}
...
...
@@ -156,7 +173,9 @@ private void Add(char[] lowerCaseCharacters, int insertionIndex)
// Determine the edit distance between these two words. Note: we do not use
// a threshold here as we need the actual edit distance so we can actually
// determine what edge to make or walk.
var
editDistance
=
EditDistance
.
GetEditDistance
(
currentNode
.
LowerCaseCharacters
,
lowerCaseCharacters
);
var
editDistance
=
EditDistance
.
GetEditDistance
(
new
ArraySlice
<
char
>(
_allLowerCaseCharacters
,
currentNode
.
CharacterSpan
),
new
ArraySlice
<
char
>(
_allLowerCaseCharacters
,
characterSpan
));
if
(
editDistance
==
0
)
{
...
...
@@ -174,13 +193,13 @@ private void Add(char[] lowerCaseCharacters, int insertionIndex)
}
// found the node we want to add the child node to.
AddChildNode
(
lowerCaseCharacters
,
insertionIndex
,
currentNode
.
EdgeCount
,
currentNodeIndex
,
editDistance
);
AddChildNode
(
characterSpan
,
insertionIndex
,
currentNode
.
EdgeCount
,
currentNodeIndex
,
editDistance
);
return
;
}
}
private
void
AddChildNode
(
char
[]
lowerCaseCharacters
,
int
insertionIndex
,
int
currentNodeEdgeCount
,
int
currentNodeIndex
,
int
editDistance
)
TextSpan
characterSpan
,
int
insertionIndex
,
int
currentNodeEdgeCount
,
int
currentNodeIndex
,
int
editDistance
)
{
// Node doesn't have an edge with this edit distance. Three cases to handle:
// 1) there are less than 4 edges. We simply place the edge into the correct
...
...
@@ -215,7 +234,7 @@ private void Add(char[] lowerCaseCharacters, int insertionIndex)
}
_builderNodes
[
currentNodeIndex
].
EdgeCount
++;
_builderNodes
[
insertionIndex
]
=
new
BuilderNode
(
lowerCaseCharacters
);
_builderNodes
[
insertionIndex
]
=
new
BuilderNode
(
characterSpan
);
return
;
}
...
...
@@ -247,13 +266,13 @@ private bool TryGetChildIndex(BuilderNode currentNode, int currentNodeIndex, int
private
struct
BuilderNode
{
public
readonly
char
[]
LowerCaseCharacters
;
public
readonly
TextSpan
CharacterSpan
;
public
int
EdgeCount
;
public
Dictionary
<
int
,
int
>
SpilloverEdges
;
public
BuilderNode
(
char
[]
lowerCaseCharacters
)
:
this
()
public
BuilderNode
(
TextSpan
characterSpan
)
:
this
()
{
this
.
LowerCaseCharacters
=
lowerCaseCharacters
;
this
.
CharacterSpan
=
characterSpan
;
}
}
}
...
...
src/Workspaces/Core/Portable/Utilities/BKTree.Node.cs
浏览文件 @
eacf19dc
...
...
@@ -3,6 +3,7 @@
using
System.Linq
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Text
;
namespace
Roslyn.Utilities
{
...
...
@@ -12,7 +13,7 @@ private struct Node
{
// The string this node corresponds to. Stored in char[] format so we can easily compute
// edit distances on it.
public
readonly
char
[]
LowerCaseCharacters
;
public
readonly
TextSpan
CharacterSpan
;
// How many children/edges this node has.
public
readonly
int
EdgeCount
;
...
...
@@ -21,23 +22,24 @@ private struct Node
// _edges[FirstEdgeIndex, FirstEdgeIndex + EdgeCount)
public
readonly
int
FirstEdgeIndex
;
public
Node
(
char
[]
lowerCaseCharacters
,
int
edgeCount
,
int
firstEdgeIndex
)
public
Node
(
TextSpan
characterSpan
,
int
edgeCount
,
int
firstEdgeIndex
)
{
LowerCaseCharacters
=
lowerCaseCharacters
;
CharacterSpan
=
characterSpan
;
EdgeCount
=
edgeCount
;
FirstEdgeIndex
=
firstEdgeIndex
;
}
internal
void
WriteTo
(
ObjectWriter
writer
)
{
writer
.
WriteValue
(
LowerCaseCharacters
);
writer
.
WriteInt32
(
CharacterSpan
.
Start
);
writer
.
WriteInt32
(
CharacterSpan
.
Length
);
writer
.
WriteInt32
(
EdgeCount
);
writer
.
WriteInt32
(
FirstEdgeIndex
);
}
internal
static
Node
ReadFrom
(
ObjectReader
reader
)
{
return
new
Node
(
(
char
[])
reader
.
ReadValue
(
),
reader
.
ReadInt32
(),
reader
.
ReadInt32
());
return
new
Node
(
new
TextSpan
(
reader
.
ReadInt32
(),
reader
.
ReadInt32
()
),
reader
.
ReadInt32
(),
reader
.
ReadInt32
());
}
}
}
...
...
src/Workspaces/Core/Portable/Utilities/BKTree.Serialization.cs
浏览文件 @
eacf19dc
...
...
@@ -10,6 +10,8 @@ internal partial class BKTree
{
internal
void
WriteTo
(
ObjectWriter
writer
)
{
writer
.
WriteValue
(
_allLowerCaseCharacters
);
writer
.
WriteInt32
(
this
.
_nodes
.
Length
);
foreach
(
var
node
in
_nodes
)
{
...
...
@@ -25,6 +27,7 @@ internal void WriteTo(ObjectWriter writer)
internal
static
BKTree
ReadFrom
(
ObjectReader
reader
)
{
var
allLowerCaseCharacters
=
(
char
[])
reader
.
ReadValue
();
var
nodes
=
new
Node
[
reader
.
ReadInt32
()];
for
(
var
i
=
0
;
i
<
nodes
.
Length
;
i
++)
{
...
...
@@ -37,7 +40,7 @@ internal static BKTree ReadFrom(ObjectReader reader)
edges
[
i
]
=
Edge
.
ReadFrom
(
reader
);
}
return
new
BKTree
(
nodes
,
edges
);
return
new
BKTree
(
allLowerCaseCharacters
,
nodes
,
edges
);
}
}
}
src/Workspaces/Core/Portable/Utilities/BKTree.cs
浏览文件 @
eacf19dc
...
...
@@ -13,6 +13,7 @@ namespace Roslyn.Utilities
internal
partial
class
BKTree
{
public
static
readonly
BKTree
Empty
=
new
BKTree
(
SpecializedCollections
.
EmptyArray
<
char
>(),
SpecializedCollections
.
EmptyArray
<
Node
>(),
SpecializedCollections
.
EmptyArray
<
Edge
>());
...
...
@@ -28,12 +29,13 @@ internal partial class BKTree
// * of course '0' is only for the root case. All nodes state where in _edges
// their child edges range starts. So the children for any node are in _edges from
// [node.FirstEdgeIndex, node.FirstEdgeIndex + node.EdgeCount)
private
readonly
char
[]
_allLowerCaseCharacters
;
private
readonly
Node
[]
_nodes
;
private
readonly
Edge
[]
_edges
;
private
BKTree
(
Node
[]
nodes
,
Edge
[]
edges
)
private
BKTree
(
char
[]
allLowerCaseCharacters
,
Node
[]
nodes
,
Edge
[]
edges
)
{
_allLowerCaseCharacters
=
allLowerCaseCharacters
;
_nodes
=
nodes
;
_edges
=
edges
;
}
...
...
@@ -79,13 +81,15 @@ private void Lookup(Node currentNode, char[] queryCharacters, int queryLength, i
// We always want to compute the real edit distance (ignoring any thresholds). This is
// because we need that edit distance to appropriately determine which edges to walk
// in the tree.
var
characterSpan
=
currentNode
.
CharacterSpan
;
var
editDistance
=
EditDistance
.
GetEditDistance
(
new
ArraySlice
<
char
>(
currentNode
.
LowerCaseCharacters
),
new
ArraySlice
<
char
>(
queryCharacters
,
0
,
queryLength
));
new
ArraySlice
<
char
>(
_allLowerCaseCharacters
,
characterSpan
),
new
ArraySlice
<
char
>(
queryCharacters
,
0
,
queryLength
));
if
(
editDistance
<=
threshold
)
{
// Found a match.
result
.
Add
(
new
string
(
currentNode
.
LowerCaseCharacters
));
result
.
Add
(
new
string
(
_allLowerCaseCharacters
,
characterSpan
.
Start
,
characterSpan
.
Length
));
}
var
min
=
editDistance
-
threshold
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录