Commit d41a98bd 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 bz2 module, whose classes used the same algorithm.
parent f1ab47eb
...@@ -121,6 +121,9 @@ Tests ...@@ -121,6 +121,9 @@ Tests
Extension Modules Extension Modules
----------------- -----------------
- Issue #13159: FileIO and BZ2File now use a linear-time buffer growth
strategy instead of a quadratic-time one.
- Issue #13070: Fix a crash when a TextIOWrapper caught in a reference cycle - Issue #13070: Fix a crash when a TextIOWrapper caught in a reference cycle
would be finalized after the reference to its underlying BufferedRWPair's would be finalized after the reference to its underlying BufferedRWPair's
writer got cleared by the GC. writer got cleared by the GC.
......
...@@ -43,12 +43,6 @@ ...@@ -43,12 +43,6 @@
#define SMALLCHUNK BUFSIZ #define SMALLCHUNK BUFSIZ
#endif #endif
#if SIZEOF_INT < 4
#define BIGCHUNK (512 * 32)
#else
#define BIGCHUNK (512 * 1024)
#endif
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
int fd; int fd;
...@@ -565,15 +559,10 @@ new_buffersize(fileio *self, size_t currentsize) ...@@ -565,15 +559,10 @@ new_buffersize(fileio *self, size_t currentsize)
} }
} }
#endif #endif
if (currentsize > SMALLCHUNK) { /* Expand the buffer by an amount proportional to the current size,
/* Keep doubling until we reach BIGCHUNK; giving us amortized linear-time behavior. Use a less-than-double
then keep adding BIGCHUNK. */ growth factor to avoid excessive allocation. */
if (currentsize <= BIGCHUNK) return currentsize + (currentsize >> 3) + 6;
return currentsize + currentsize;
else
return currentsize + BIGCHUNK;
}
return currentsize + SMALLCHUNK;
} }
static PyObject * static PyObject *
......
...@@ -218,25 +218,14 @@ Util_CatchBZ2Error(int bzerror) ...@@ -218,25 +218,14 @@ Util_CatchBZ2Error(int bzerror)
#define SMALLCHUNK BUFSIZ #define SMALLCHUNK BUFSIZ
#endif #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(). */ /* This is a hacked version of Python's fileobject.c:new_buffersize(). */
static size_t static size_t
Util_NewBufferSize(size_t currentsize) Util_NewBufferSize(size_t currentsize)
{ {
if (currentsize > SMALLCHUNK) { /* Expand the buffer by an amount proportional to the current size,
/* Keep doubling until we reach BIGCHUNK; giving us amortized linear-time behavior. Use a less-than-double
then keep adding BIGCHUNK. */ growth factor to avoid excessive allocation. */
if (currentsize <= BIGCHUNK) return currentsize + (currentsize >> 3) + 6;
return currentsize + currentsize;
else
return currentsize + BIGCHUNK;
}
return currentsize + SMALLCHUNK;
} }
/* This is a hacked version of Python's fileobject.c:get_line(). */ /* This is a hacked version of Python's fileobject.c:get_line(). */
......
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