Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
80859dd7
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
80859dd7
编写于
10月 13, 2017
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
IntervalNode implements IModelDecoration
上级
479958b2
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
91 addition
and
22 deletion
+91
-22
src/vs/editor/common/model/intervalTree.ts
src/vs/editor/common/model/intervalTree.ts
+85
-15
src/vs/editor/test/common/model/intervalTree.test.ts
src/vs/editor/test/common/model/intervalTree.test.ts
+6
-7
未找到文件。
src/vs/editor/common/model/intervalTree.ts
浏览文件 @
80859dd7
...
...
@@ -4,10 +4,21 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
ModelDecorationOptions
}
from
'
vs/editor/common/model/textModelWithDecorations
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
IModelDecoration
}
from
'
vs/editor/common/editorCommon
'
;
//
// The red-black tree is based on the "Introduction to Algorithms" by Cormen, Leiserson and Rivest.
//
// TODO@interval!!!
export
const
ClassName
=
{
EditorInfoDecoration
:
'
infosquiggly
'
,
EditorWarningDecoration
:
'
warningsquiggly
'
,
EditorErrorDecoration
:
'
errorsquiggly
'
};
export
class
Interval
{
_intervalBrand
:
void
;
...
...
@@ -25,11 +36,11 @@ export const enum NodeColor {
Black
}
export
class
IntervalNode
{
export
class
IntervalNode
implements
IModelDecoration
{
public
parent
:
IntervalNode
;
public
left
:
IntervalNode
;
public
right
:
IntervalNode
;
public
parent
:
IntervalNode
;
public
color
:
NodeColor
;
public
start
:
number
;
...
...
@@ -37,9 +48,17 @@ export class IntervalNode {
public
delta
:
number
;
public
maxEnd
:
number
;
public
absoluteInterval
:
Interval
;
public
id
:
string
;
public
ownerId
:
number
;
public
options
:
ModelDecorationOptions
;
public
isForValidation
:
boolean
;
constructor
(
start
:
number
,
end
:
number
)
{
public
cachedVersionId
:
number
;
public
cachedAbsoluteStart
:
number
;
public
cachedAbsoluteEnd
:
number
;
public
range
:
Range
;
constructor
(
id
:
string
,
start
:
number
,
end
:
number
)
{
this
.
parent
=
null
;
this
.
left
=
null
;
this
.
right
=
null
;
...
...
@@ -50,7 +69,34 @@ export class IntervalNode {
this
.
delta
=
start
;
this
.
maxEnd
=
end
;
this
.
absoluteInterval
=
new
Interval
(
0
,
0
);
this
.
id
=
id
;
this
.
ownerId
=
0
;
this
.
options
=
null
;
this
.
isForValidation
=
false
;
this
.
cachedVersionId
=
0
;
this
.
cachedAbsoluteStart
=
start
;
this
.
cachedAbsoluteEnd
=
end
;
this
.
range
=
null
;
}
public
setOptions
(
options
:
ModelDecorationOptions
)
{
this
.
options
=
options
;
this
.
isForValidation
=
(
this
.
options
.
className
===
ClassName
.
EditorErrorDecoration
||
this
.
options
.
className
===
ClassName
.
EditorWarningDecoration
);
}
public
setCachedOffsets
(
absoluteStart
:
number
,
absoluteEnd
:
number
,
cachedVersionId
:
number
):
void
{
this
.
cachedVersionId
=
cachedVersionId
;
if
(
this
.
cachedAbsoluteStart
===
absoluteStart
&&
this
.
cachedAbsoluteEnd
===
absoluteEnd
)
{
// no change
return
;
}
this
.
cachedAbsoluteStart
=
absoluteStart
;
this
.
cachedAbsoluteEnd
=
absoluteEnd
;
this
.
range
=
null
;
}
public
detach
():
void
{
...
...
@@ -60,7 +106,7 @@ export class IntervalNode {
}
}
const
SENTINEL
:
IntervalNode
=
new
IntervalNode
(
0
,
0
);
const
SENTINEL
:
IntervalNode
=
new
IntervalNode
(
null
,
0
,
0
);
SENTINEL
.
parent
=
SENTINEL
;
SENTINEL
.
left
=
SENTINEL
;
SENTINEL
.
right
=
SENTINEL
;
...
...
@@ -74,12 +120,12 @@ export class IntervalTree {
this
.
root
=
SENTINEL
;
}
public
intervalSearch
(
interval
:
Interval
):
IntervalNode
[]
{
public
intervalSearch
(
interval
:
Interval
,
filterOwnerId
:
number
,
filterOutValidation
:
boolean
,
cachedVersionId
:
number
):
IntervalNode
[]
{
if
(
this
.
root
===
SENTINEL
)
{
return
[];
}
let
result
:
IntervalNode
[]
=
[];
intervalSearchRecursive
(
this
.
root
,
0
,
interval
.
start
,
interval
.
end
,
result
);
intervalSearchRecursive
(
this
.
root
,
0
,
interval
.
start
,
interval
.
end
,
filterOwnerId
,
filterOutValidation
,
cachedVersionId
,
result
);
return
result
;
}
...
...
@@ -87,10 +133,24 @@ export class IntervalTree {
rbTreeInsert
(
this
,
node
);
}
public
delete
(
node
:
IntervalNode
)
{
public
delete
(
node
:
IntervalNode
)
:
void
{
rbTreeDelete
(
this
,
node
);
}
public
resolveNode
(
node
:
IntervalNode
,
cachedVersionId
:
number
):
void
{
let
delta
=
0
;
while
(
node
!==
this
.
root
)
{
if
(
node
===
node
.
parent
.
right
)
{
delta
+=
node
.
parent
.
delta
;
}
node
=
node
.
parent
;
}
const
nodeStart
=
node
.
start
+
delta
;
const
nodeEnd
=
node
.
end
+
delta
;
node
.
setCachedOffsets
(
nodeStart
,
nodeEnd
,
cachedVersionId
);
}
public
assertInvariants
():
void
{
assert
(
SENTINEL
.
color
===
NodeColor
.
Black
);
assert
(
SENTINEL
.
parent
===
SENTINEL
);
...
...
@@ -150,7 +210,7 @@ export class IntervalTree {
}
//#region Searching
function
intervalSearchRecursive
(
node
:
IntervalNode
,
delta
:
number
,
intervalStart
:
number
,
intervalEnd
:
number
,
result
:
IntervalNode
[]):
void
{
function
intervalSearchRecursive
(
node
:
IntervalNode
,
delta
:
number
,
intervalStart
:
number
,
intervalEnd
:
number
,
filterOwnerId
:
number
,
filterOutValidation
:
boolean
,
cachedVersionId
:
number
,
result
:
IntervalNode
[]):
void
{
// https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
// Now, it is known that two intervals A and B overlap only when both
// A.low <= B.high and A.high >= B.low. When searching the trees for
...
...
@@ -165,7 +225,7 @@ function intervalSearchRecursive(node: IntervalNode, delta: number, intervalStar
}
if
(
node
.
left
!==
SENTINEL
)
{
intervalSearchRecursive
(
node
.
left
,
delta
,
intervalStart
,
intervalEnd
,
result
);
intervalSearchRecursive
(
node
.
left
,
delta
,
intervalStart
,
intervalEnd
,
filterOwnerId
,
filterOutValidation
,
cachedVersionId
,
result
);
}
const
nodeStart
=
delta
+
node
.
start
;
...
...
@@ -178,13 +238,23 @@ function intervalSearchRecursive(node: IntervalNode, delta: number, intervalStar
const
nodeEnd
=
delta
+
node
.
end
;
if
(
nodeEnd
>=
intervalStart
)
{
// There is overlap
node
.
absoluteInterval
.
start
=
nodeStart
;
node
.
absoluteInterval
.
end
=
nodeEnd
;
result
.
push
(
node
);
node
.
setCachedOffsets
(
nodeStart
,
nodeEnd
,
cachedVersionId
);
let
include
=
true
;
if
(
filterOwnerId
&&
node
.
ownerId
&&
node
.
ownerId
!==
filterOwnerId
)
{
include
=
false
;
}
if
(
filterOutValidation
&&
node
.
isForValidation
)
{
include
=
false
;
}
if
(
include
)
{
result
.
push
(
node
);
}
}
if
(
node
.
right
!==
SENTINEL
)
{
intervalSearchRecursive
(
node
.
right
,
delta
+
node
.
delta
,
intervalStart
,
intervalEnd
,
result
);
intervalSearchRecursive
(
node
.
right
,
delta
+
node
.
delta
,
intervalStart
,
intervalEnd
,
filterOwnerId
,
filterOutValidation
,
cachedVersionId
,
result
);
}
}
//#endregion
...
...
src/vs/editor/test/common/model/intervalTree.test.ts
浏览文件 @
80859dd7
...
...
@@ -65,13 +65,12 @@ suite('IntervalTree', () => {
public
acceptOp
(
op
:
IOperation
):
void
{
if
(
op
.
type
===
'
insert
'
)
{
if
(
PRINT_TREE
)
{
console
.
log
(
`insert: {
${
JSON
.
stringify
(
new
Interval
(
op
.
begin
,
op
.
end
))}
}`
);
}
let
nodeId
=
(
++
this
.
_lastNodeId
);
this
.
_treeNodes
[
nodeId
]
=
new
IntervalNode
(
op
.
begin
,
op
.
end
);
this
.
_treeNodes
[
nodeId
]
=
new
IntervalNode
(
null
,
op
.
begin
,
op
.
end
);
this
.
_tree
.
insert
(
this
.
_treeNodes
[
nodeId
]);
this
.
_oracleNodes
[
nodeId
]
=
this
.
_oracle
.
insert
(
new
Interval
(
op
.
begin
,
op
.
end
));
}
else
if
(
op
.
type
===
'
delete
'
)
{
...
...
@@ -84,8 +83,8 @@ suite('IntervalTree', () => {
this
.
_treeNodes
[
op
.
id
]
=
null
;
this
.
_oracleNodes
[
op
.
id
]
=
null
;
}
else
{
let
actualNodes
=
this
.
_tree
.
intervalSearch
(
new
Interval
(
op
.
begin
,
op
.
end
));
let
actual
=
actualNodes
.
map
(
n
=>
n
.
absoluteInterval
);
let
actualNodes
=
this
.
_tree
.
intervalSearch
(
new
Interval
(
op
.
begin
,
op
.
end
)
,
0
,
false
,
0
);
let
actual
=
actualNodes
.
map
(
n
=>
n
ew
Interval
(
n
.
cachedAbsoluteStart
,
n
.
cachedAbsoluteEnd
)
);
let
expected
=
this
.
_oracle
.
search
(
new
Interval
(
op
.
begin
,
op
.
end
));
assert
.
deepEqual
(
actual
,
expected
);
return
;
...
...
@@ -418,7 +417,7 @@ suite('IntervalTree', () => {
[
19
,
20
]
];
data
.
forEach
((
int
)
=>
{
let
node
=
new
IntervalNode
(
int
[
0
],
int
[
1
]);
let
node
=
new
IntervalNode
(
null
,
int
[
0
],
int
[
1
]);
r
.
insert
(
node
);
});
return
r
;
...
...
@@ -427,8 +426,8 @@ suite('IntervalTree', () => {
const
T
=
createCormenTree
();
function
assertIntervalSearch
(
start
:
number
,
end
:
number
,
expected
:
[
number
,
number
][]):
void
{
let
actualNodes
=
T
.
intervalSearch
(
new
Interval
(
start
,
end
));
let
actual
=
actualNodes
.
map
((
n
)
=>
<
[
number
,
number
]
>
[
n
.
absoluteInterval
.
start
,
n
.
absoluteInterval
.
e
nd
]);
let
actualNodes
=
T
.
intervalSearch
(
new
Interval
(
start
,
end
)
,
0
,
false
,
0
);
let
actual
=
actualNodes
.
map
((
n
)
=>
<
[
number
,
number
]
>
[
n
.
cachedAbsoluteStart
,
n
.
cachedAbsoluteE
nd
]);
assert
.
deepEqual
(
actual
,
expected
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录