Skip to content

Commit f1e5817

Browse files
committed
vim-patch:8.0.1774: reading very long lines can be slow
Problem: Reading very long lines can be slow. Solution: Read up to 1 Mbyte at a time to avoid a lot of copying. Add a check for going over the column limit. vim/vim@13d3b05
1 parent 0bfff60 commit f1e5817

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/nvim/fileio.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ readfile(
300300
int skip_read = false;
301301
context_sha256_T sha_ctx;
302302
int read_undo_file = false;
303+
int split = 0; // number of split lines
303304
linenr_T linecnt;
304305
int error = FALSE; /* errors encountered */
305306
int ff_error = EOL_UNKNOWN; /* file format with errors */
@@ -1013,8 +1014,21 @@ readfile(
10131014
*/
10141015
{
10151016
if (!skip_read) {
1016-
size = 0x10000L; /* use buffer >= 64K */
1017+
// Use buffer >= 64K. Add linerest to double the size if the
1018+
// line gets very long, to avoid a lot of copying. But don't
1019+
// read more than 1 Mbyte at a time, so we can be interrupted.
1020+
size = 0x10000L + linerest;
1021+
if (size > 0x100000L) {
1022+
size = 0x100000L;
1023+
}
1024+
}
10171025

1026+
// Protect against the argument of lalloc() going negative.
1027+
if (size < 0 || size + linerest + 1 < 0 || linerest >= MAXCOL) {
1028+
split++;
1029+
*ptr = NL; // split line by inserting a NL
1030+
size = 1;
1031+
} else if (!skip_read) {
10181032
for (; size >= 10; size /= 2) {
10191033
new_buffer = verbose_try_malloc((size_t)size + (size_t)linerest + 1);
10201034
if (new_buffer) {
@@ -1862,6 +1876,10 @@ readfile(
18621876
STRCAT(IObuff, _("[CR missing]"));
18631877
c = TRUE;
18641878
}
1879+
if (split) {
1880+
STRCAT(IObuff, _("[long lines split]"));
1881+
c = true;
1882+
}
18651883
if (notconverted) {
18661884
STRCAT(IObuff, _("[NOT converted]"));
18671885
c = TRUE;

0 commit comments

Comments
 (0)