comparison src/fileio.c @ 13804:8a35543f5f97 v8.0.1774

patch 8.0.1774: reading very long lines can be slow commit https://github.com/vim/vim/commit/13d3b05ed2cf9a54b18b4e8236f0af2c5386200c Author: Bram Moolenaar <Bram@vim.org> Date: Sun Apr 29 13:34:47 2018 +0200 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.
author Christian Brabandt <cb@256bit.org>
date Sun, 29 Apr 2018 13:45:04 +0200
parents 9de2b25932eb
children cad480bac9e1
comparison
equal deleted inserted replaced
13803:d93f2231a72d 13804:8a35543f5f97
1207 * We allocate as much space for the file as we can get, plus 1207 * We allocate as much space for the file as we can get, plus
1208 * space for the old line plus room for one terminating NUL. 1208 * space for the old line plus room for one terminating NUL.
1209 * The amount is limited by the fact that read() only can read 1209 * The amount is limited by the fact that read() only can read
1210 * upto max_unsigned characters (and other things). 1210 * upto max_unsigned characters (and other things).
1211 */ 1211 */
1212 #if VIM_SIZEOF_INT <= 2 1212 if (!skip_read)
1213 if (linerest >= 0x7ff0) 1213 {
1214 {
1215 ++split;
1216 *ptr = NL; /* split line by inserting a NL */
1217 size = 1;
1218 }
1219 else
1220 #endif
1221 {
1222 if (!skip_read)
1223 {
1224 #if VIM_SIZEOF_INT > 2 1214 #if VIM_SIZEOF_INT > 2
1225 # if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L) 1215 # if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L)
1226 size = SSIZE_MAX; /* use max I/O size, 52K */ 1216 size = SSIZE_MAX; /* use max I/O size, 52K */
1227 # else 1217 # else
1228 size = 0x10000L; /* use buffer >= 64K */ 1218 /* Use buffer >= 64K. Add linerest to double the size if the
1219 * line gets very long, to avoid a lot of copying. But don't
1220 * read more than 1 Mbyte at a time, so we can be interrupted.
1221 */
1222 size = 0x10000L + linerest;
1223 if (size > 0x100000L)
1224 size = 0x100000L;
1229 # endif 1225 # endif
1230 #else 1226 #else
1231 size = 0x7ff0L - linerest; /* limit buffer to 32K */ 1227 size = 0x7ff0L - linerest; /* limit buffer to 32K */
1232 #endif 1228 #endif
1233 1229 }
1230
1231 /* Protect against the argument of lalloc() going negative. */
1232 if (
1233 #if VIM_SIZEOF_INT <= 2
1234 linerest >= 0x7ff0
1235 #else
1236 size < 0 || size + linerest + 1 < 0 || linerest >= MAXCOL
1237 #endif
1238 )
1239 {
1240 ++split;
1241 *ptr = NL; /* split line by inserting a NL */
1242 size = 1;
1243 }
1244 else
1245 {
1246 if (!skip_read)
1247 {
1234 for ( ; size >= 10; size = (long)((long_u)size >> 1)) 1248 for ( ; size >= 10; size = (long)((long_u)size >> 1))
1235 { 1249 {
1236 if ((new_buffer = lalloc((long_u)(size + linerest + 1), 1250 if ((new_buffer = lalloc((long_u)(size + linerest + 1),
1237 FALSE)) != NULL) 1251 FALSE)) != NULL)
1238 break; 1252 break;