Commit 393f705f authored by Nadeem Vawda's avatar Nadeem Vawda

Issue #13159: Replace FileIO's quadratic-time buffer growth algorithm with a linear-time one.

Also fix the builtin file class and the bz2 module, which used the same algorithm.
parent 0992a60d
......@@ -229,6 +229,9 @@ Library
Extension Modules
-----------------
- Issue #13159: FileIO, BZ2File, and the built-in file class now use a
linear-time buffer growth strategy instead of a quadratic one.
- Issue #13070: Fix a crash when a TextIOWrapper caught in a reference cycle
would be finalized after the reference to its underlying BufferedRWPair's
writer got cleared by the GC.
......
......@@ -42,12 +42,6 @@
#define SMALLCHUNK BUFSIZ
#endif
#if SIZEOF_INT < 4
#define BIGCHUNK (512 * 32)
#else
#define BIGCHUNK (512 * 1024)
#endif
typedef struct {
PyObject_HEAD
int fd;
......@@ -528,15 +522,10 @@ new_buffersize(fileio *self, size_t currentsize)
}
}
#endif
if (currentsize > SMALLCHUNK) {
/* Keep doubling until we reach BIGCHUNK;
then keep adding BIGCHUNK. */
if (currentsize <= BIGCHUNK)
return currentsize + currentsize;
else
return currentsize + BIGCHUNK;
}
return currentsize + SMALLCHUNK;
/* Expand the buffer by an amount proportional to the current size,
giving us amortized linear-time behavior. Use a less-than-double
growth factor to avoid excessive allocation. */
return currentsize + (currentsize >> 3) + 6;
}
static PyObject *
......
......@@ -224,25 +224,14 @@ Util_CatchBZ2Error(int bzerror)
#define SMALLCHUNK BUFSIZ
#endif
#if SIZEOF_INT < 4
#define BIGCHUNK (512 * 32)
#else
#define BIGCHUNK (512 * 1024)
#endif
/* This is a hacked version of Python's fileobject.c:new_buffersize(). */
static size_t
Util_NewBufferSize(size_t currentsize)
{
if (currentsize > SMALLCHUNK) {
/* Keep doubling until we reach BIGCHUNK;
then keep adding BIGCHUNK. */
if (currentsize <= BIGCHUNK)
return currentsize + currentsize;
else
return currentsize + BIGCHUNK;
}
return currentsize + SMALLCHUNK;
/* Expand the buffer by an amount proportional to the current size,
giving us amortized linear-time behavior. Use a less-than-double
growth factor to avoid excessive allocation. */
return currentsize + (currentsize >> 3) + 6;
}
/* This is a hacked version of Python's fileobject.c:get_line(). */
......
......@@ -992,12 +992,6 @@ file_isatty(PyFileObject *f)
#define SMALLCHUNK BUFSIZ
#endif
#if SIZEOF_INT < 4
#define BIGCHUNK (512 * 32)
#else
#define BIGCHUNK (512 * 1024)
#endif
static size_t
new_buffersize(PyFileObject *f, size_t currentsize)
{
......@@ -1026,15 +1020,10 @@ new_buffersize(PyFileObject *f, size_t currentsize)
/* Add 1 so if the file were to grow we'd notice. */
}
#endif
if (currentsize > SMALLCHUNK) {
/* Keep doubling until we reach BIGCHUNK;
then keep adding BIGCHUNK. */
if (currentsize <= BIGCHUNK)
return currentsize + currentsize;
else
return currentsize + BIGCHUNK;
}
return currentsize + SMALLCHUNK;
/* Expand the buffer by an amount proportional to the current size,
giving us amortized linear-time behavior. Use a less-than-double
growth factor to avoid excessive allocation. */
return currentsize + (currentsize >> 3) + 6;
}
#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment