diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-04-29 13:34:47 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-04-29 13:34:47 +0200 |
commit | 13d3b05ed2cf9a54b18b4e8236f0af2c5386200c (patch) | |
tree | 6651b5e9b7aa1efbb966fda9a7dde82c6d60216b | |
parent | c36651b4b946333dce0a916326d821d2562cf39d (diff) | |
download | vim-13d3b05ed2cf9a54b18b4e8236f0af2c5386200c.zip |
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.
-rw-r--r-- | src/fileio.c | 38 | ||||
-rw-r--r-- | src/version.c | 2 |
2 files changed, 28 insertions, 12 deletions
diff --git a/src/fileio.c b/src/fileio.c index 35f4fd2c2..6b48c39d3 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1209,28 +1209,42 @@ retry: * The amount is limited by the fact that read() only can read * upto max_unsigned characters (and other things). */ -#if VIM_SIZEOF_INT <= 2 - if (linerest >= 0x7ff0) + if (!skip_read) { - ++split; - *ptr = NL; /* split line by inserting a NL */ - size = 1; - } - else -#endif - { - if (!skip_read) - { #if VIM_SIZEOF_INT > 2 # if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L) size = SSIZE_MAX; /* use max I/O size, 52K */ # else - size = 0x10000L; /* use buffer >= 64K */ + /* Use buffer >= 64K. Add linerest to double the size if the + * line gets very long, to avoid a lot of copying. But don't + * read more than 1 Mbyte at a time, so we can be interrupted. + */ + size = 0x10000L + linerest; + if (size > 0x100000L) + size = 0x100000L; # endif #else size = 0x7ff0L - linerest; /* limit buffer to 32K */ #endif + } + /* Protect against the argument of lalloc() going negative. */ + if ( +#if VIM_SIZEOF_INT <= 2 + linerest >= 0x7ff0 +#else + size < 0 || size + linerest + 1 < 0 || linerest >= MAXCOL +#endif + ) + { + ++split; + *ptr = NL; /* split line by inserting a NL */ + size = 1; + } + else + { + if (!skip_read) + { for ( ; size >= 10; size = (long)((long_u)size >> 1)) { if ((new_buffer = lalloc((long_u)(size + linerest + 1), diff --git a/src/version.c b/src/version.c index 5d75dabf5..10e446a69 100644 --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1774, +/**/ 1773, /**/ 1772, |