Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
徽霖
Vscode
提交
6f8ab5f7
V
Vscode
项目概览
徽霖
/
Vscode
通知
9
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
Vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6f8ab5f7
编写于
3月 28, 2018
作者:
P
Peng Lyu
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'rebornix/fix-long-changebuffer'
上级
5075e9a2
fe6b1682
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
113 addition
and
15 deletion
+113
-15
src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts
.../editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts
+74
-15
src/vs/editor/test/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.test.ts
...mon/model/pieceTreeTextBuffer/pieceTreeTextBuffer.test.ts
+39
-0
未找到文件。
src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts
浏览文件 @
6f8ab5f7
...
...
@@ -13,6 +13,7 @@ import { SearchData, isValidMatch, Searcher, createFindMatch } from 'vs/editor/c
import
{
FindMatch
}
from
'
vs/editor/common/model
'
;
// const lfRegex = new RegExp(/\r\n|\r|\n/g);
export
const
AverageBufferSize
=
65535
;
export
function
createUintArray
(
arr
:
number
[]):
Uint32Array
|
Uint16Array
{
let
r
;
...
...
@@ -311,7 +312,7 @@ export class PieceTreeBase {
}
normalizeEOL
(
eol
:
'
\r\n
'
|
'
\n
'
)
{
let
averageBufferSize
=
65536
;
let
averageBufferSize
=
AverageBufferSize
;
let
min
=
averageBufferSize
-
Math
.
floor
(
averageBufferSize
/
3
);
let
max
=
min
*
2
;
...
...
@@ -712,7 +713,8 @@ export class PieceTreeBase {
if
(
node
.
piece
.
bufferIndex
===
0
&&
piece
.
end
.
line
===
this
.
_lastChangeBufferPos
.
line
&&
piece
.
end
.
column
===
this
.
_lastChangeBufferPos
.
column
&&
(
nodeStartOffset
+
piece
.
length
===
offset
)
(
nodeStartOffset
+
piece
.
length
===
offset
)
&&
value
.
length
<
AverageBufferSize
)
{
// changed buffer
this
.
appendToNode
(
node
,
value
);
...
...
@@ -769,19 +771,27 @@ export class PieceTreeBase {
this
.
deleteNodeTail
(
node
,
insertPosInBuffer
);
}
let
newPiece
=
this
.
createNewPiece
(
value
);
let
newPiece
s
=
this
.
createNewPieces
(
value
);
if
(
newRightPiece
.
length
>
0
)
{
this
.
rbInsertRight
(
node
,
newRightPiece
);
}
this
.
rbInsertRight
(
node
,
newPiece
);
let
tmpNode
=
node
;
for
(
let
k
=
0
;
k
<
newPieces
.
length
;
k
++
)
{
tmpNode
=
this
.
rbInsertRight
(
tmpNode
,
newPieces
[
k
]);
}
this
.
deleteNodes
(
nodesToDel
);
}
else
{
this
.
insertContentToNodeRight
(
value
,
node
);
}
}
else
{
// insert new node
let
piece
=
this
.
createNewPiece
(
value
);
this
.
rbInsertLeft
(
null
,
piece
);
let
pieces
=
this
.
createNewPieces
(
value
);
let
node
=
this
.
rbInsertLeft
(
null
,
pieces
[
0
]);
for
(
let
k
=
1
;
k
<
pieces
.
length
;
k
++
)
{
node
=
this
.
rbInsertRight
(
node
,
pieces
[
k
]);
}
}
// todo, this is too brutal. Total line feed count should be updated the same way as lf_left.
...
...
@@ -887,8 +897,11 @@ export class PieceTreeBase {
}
}
let
newPiece
=
this
.
createNewPiece
(
value
);
let
newNode
=
this
.
rbInsertLeft
(
node
,
newPiece
);
let
newPieces
=
this
.
createNewPieces
(
value
);
let
newNode
=
this
.
rbInsertLeft
(
node
,
newPieces
[
newPieces
.
length
-
1
]);
for
(
let
k
=
newPieces
.
length
-
2
;
k
>=
0
;
k
--
)
{
newNode
=
this
.
rbInsertLeft
(
newNode
,
newPieces
[
k
]);
}
this
.
validateCRLFWithPrevNode
(
newNode
);
this
.
deleteNodes
(
nodesToDel
);
}
...
...
@@ -900,8 +913,14 @@ export class PieceTreeBase {
value
+=
'
\n
'
;
}
let
newPiece
=
this
.
createNewPiece
(
value
);
let
newNode
=
this
.
rbInsertRight
(
node
,
newPiece
);
let
newPieces
=
this
.
createNewPieces
(
value
);
let
newNode
=
this
.
rbInsertRight
(
node
,
newPieces
[
0
]);
let
tmpNode
=
newNode
;
for
(
let
k
=
1
;
k
<
newPieces
.
length
;
k
++
)
{
tmpNode
=
this
.
rbInsertRight
(
tmpNode
,
newPieces
[
k
]);
}
this
.
validateCRLFWithPrevNode
(
newNode
);
}
...
...
@@ -994,7 +1013,47 @@ export class PieceTreeBase {
}
}
createNewPiece
(
text
:
string
):
Piece
{
createNewPieces
(
text
:
string
):
Piece
[]
{
if
(
text
.
length
>
AverageBufferSize
)
{
// the content is large, operations like substring, charCode becomes slow
// so here we split it into smaller chunks, just like what we did for CR/LF normalization
let
newPieces
=
[];
while
(
text
.
length
>
AverageBufferSize
)
{
const
lastChar
=
text
.
charCodeAt
(
AverageBufferSize
-
1
);
let
splitText
;
if
(
lastChar
===
CharCode
.
CarriageReturn
||
(
lastChar
>=
0xd800
&&
lastChar
<=
0xdbff
))
{
// last character is \r or a high surrogate => keep it back
splitText
=
text
.
substring
(
0
,
AverageBufferSize
-
1
);
text
=
text
.
substring
(
AverageBufferSize
-
1
);
}
else
{
splitText
=
text
.
substring
(
0
,
AverageBufferSize
);
text
=
text
.
substring
(
AverageBufferSize
);
}
let
lineStarts
=
createLineStartsFast
(
splitText
);
newPieces
.
push
(
new
Piece
(
this
.
_buffers
.
length
,
/* buffer index */
{
line
:
0
,
column
:
0
},
{
line
:
lineStarts
.
length
-
1
,
column
:
splitText
.
length
-
lineStarts
[
lineStarts
.
length
-
1
]
},
lineStarts
.
length
-
1
,
splitText
.
length
));
this
.
_buffers
.
push
(
new
StringBuffer
(
splitText
,
lineStarts
));
}
let
lineStarts
=
createLineStartsFast
(
text
);
newPieces
.
push
(
new
Piece
(
this
.
_buffers
.
length
,
/* buffer index */
{
line
:
0
,
column
:
0
},
{
line
:
lineStarts
.
length
-
1
,
column
:
text
.
length
-
lineStarts
[
lineStarts
.
length
-
1
]
},
lineStarts
.
length
-
1
,
text
.
length
));
this
.
_buffers
.
push
(
new
StringBuffer
(
text
,
lineStarts
));
return
newPieces
;
}
let
startOffset
=
this
.
_buffers
[
0
].
buffer
.
length
;
const
lineStarts
=
createLineStartsFast
(
text
,
false
);
...
...
@@ -1029,14 +1088,14 @@ export class PieceTreeBase {
let
endColumn
=
endOffset
-
this
.
_buffers
[
0
].
lineStarts
[
endIndex
];
let
endPos
=
{
line
:
endIndex
,
column
:
endColumn
};
let
newPiece
=
new
Piece
(
0
,
0
,
/** todo */
start
,
endPos
,
this
.
getLineFeedCnt
(
0
,
start
,
endPos
),
endOffset
-
startOffset
);
this
.
_lastChangeBufferPos
=
endPos
;
return
newPiece
;
return
[
newPiece
]
;
}
getLinesRawContent
():
string
{
...
...
@@ -1519,8 +1578,8 @@ export class PieceTreeBase {
}
// create new piece which contains \r\n
let
piece
=
this
.
createNewPiece
(
'
\r\n
'
);
this
.
rbInsertRight
(
prev
,
piece
);
let
piece
s
=
this
.
createNewPieces
(
'
\r\n
'
);
this
.
rbInsertRight
(
prev
,
piece
s
[
0
]
);
// delete empty nodes
for
(
let
i
=
0
;
i
<
nodesToDel
.
length
;
i
++
)
{
...
...
src/vs/editor/test/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.test.ts
浏览文件 @
6f8ab5f7
...
...
@@ -1445,11 +1445,44 @@ suite('centralized lineStarts with CRLF', () => {
});
suite
(
'
random is unsupervised
'
,
()
=>
{
test
(
'
splitting large change buffer
'
,
function
()
{
let
pieceTable
=
createTextBuffer
([
''
],
false
);
let
str
=
''
;
pieceTable
.
insert
(
0
,
'
WUZ
\n
XVZY
\n
'
);
str
=
str
.
substring
(
0
,
0
)
+
'
WUZ
\n
XVZY
\n
'
+
str
.
substring
(
0
);
pieceTable
.
insert
(
8
,
'
\r\r\n
ZXUWVW
'
);
str
=
str
.
substring
(
0
,
8
)
+
'
\r\r\n
ZXUWVW
'
+
str
.
substring
(
8
);
pieceTable
.
delete
(
10
,
7
);
str
=
str
.
substring
(
0
,
10
)
+
str
.
substring
(
10
+
7
);
pieceTable
.
delete
(
10
,
1
);
str
=
str
.
substring
(
0
,
10
)
+
str
.
substring
(
10
+
1
);
pieceTable
.
insert
(
4
,
'
VX
\r\r\n
WZVZ
'
);
str
=
str
.
substring
(
0
,
4
)
+
'
VX
\r\r\n
WZVZ
'
+
str
.
substring
(
4
);
pieceTable
.
delete
(
11
,
3
);
str
=
str
.
substring
(
0
,
11
)
+
str
.
substring
(
11
+
3
);
pieceTable
.
delete
(
12
,
4
);
str
=
str
.
substring
(
0
,
12
)
+
str
.
substring
(
12
+
4
);
pieceTable
.
delete
(
8
,
0
);
str
=
str
.
substring
(
0
,
8
)
+
str
.
substring
(
8
+
0
);
pieceTable
.
delete
(
10
,
2
);
str
=
str
.
substring
(
0
,
10
)
+
str
.
substring
(
10
+
2
);
pieceTable
.
insert
(
0
,
'
VZXXZYZX
\r
'
);
str
=
str
.
substring
(
0
,
0
)
+
'
VZXXZYZX
\r
'
+
str
.
substring
(
0
);
assert
.
equal
(
pieceTable
.
getLinesRawContent
(),
str
);
testLineStarts
(
str
,
pieceTable
);
testLinesContent
(
str
,
pieceTable
);
assertTreeInvariants
(
pieceTable
);
});
test
(
'
random insert delete
'
,
function
()
{
this
.
timeout
(
500000
);
let
str
=
''
;
let
pieceTable
=
createTextBuffer
([
str
],
false
);
// let output = '';
for
(
let
i
=
0
;
i
<
1000
;
i
++
)
{
if
(
Math
.
random
()
<
0.6
)
{
// insert
...
...
@@ -1457,6 +1490,8 @@ suite('random is unsupervised', () => {
let
pos
=
randomInt
(
str
.
length
+
1
);
pieceTable
.
insert
(
pos
,
text
);
str
=
str
.
substring
(
0
,
pos
)
+
text
+
str
.
substring
(
pos
);
// output += `pieceTable.insert(${pos}, '${text.replace(/\n/g, '\\n').replace(/\r/g, '\\r')}');\n`;
// output += `str = str.substring(0, ${pos}) + '${text.replace(/\n/g, '\\n').replace(/\r/g, '\\r')}' + str.substring(${pos});\n`;
}
else
{
// delete
let
pos
=
randomInt
(
str
.
length
);
...
...
@@ -1466,8 +1501,12 @@ suite('random is unsupervised', () => {
);
pieceTable
.
delete
(
pos
,
length
);
str
=
str
.
substring
(
0
,
pos
)
+
str
.
substring
(
pos
+
length
);
// output += `pieceTable.delete(${pos}, ${length});\n`;
// output += `str = str.substring(0, ${pos}) + str.substring(${pos} + ${length});\n`
}
}
// console.log(output);
assert
.
equal
(
pieceTable
.
getLinesRawContent
(),
str
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录