From fde7eead5c95156c33052c0d9c075ca97f4c3114 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Thu, 18 Aug 2022 16:17:43 +0200 Subject: [PATCH] Grow buffers exponentially, not one byte at a time (#121) * Grow buffers exponentially, not one byte at a time To check if a TranscodingStream is eof, it first checks if it has any unused bytes in its buffer. If not, it will attempt to fill the buffer, and only return true if no bytes were filled. If there is no margin in the buffer to fill, it will call `makemargin(buffer, 1)` to ensure at least 1 byte of space. In the happy case, this will remove used up bytes. Unfortunately, buffers do never move data pointed to by their mark. So, when no space is available due to the entire buffer being filled up with marked data, the buffer will grow one byte at a time in a loop until the data fills. This is unacceptable as megabytes of data can theoretically be marked. This commit changes the growth behaviour to request at least half the buffer's length in the margin. In most cases, this will do nothing. But in the unhappy case mentioned above, it will cause the buffer to grow expoentially, until a proper size is quickly reached. * Address suggestions --- src/noop.jl | 2 +- src/stream.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/noop.jl b/src/noop.jl index d5b511c7..1a3e65f4 100644 --- a/src/noop.jl +++ b/src/noop.jl @@ -167,7 +167,7 @@ function fillbuffer(stream::NoopStream; eager::Bool = false) end nfilled::Int = 0 while ((!eager && buffersize(buffer) == 0) || (eager && makemargin!(buffer, 0, eager = true) > 0)) && !eof(stream.stream) - makemargin!(buffer, 1) + makemargin!(buffer, max(1, div(length(buffer), 2))) nfilled += readdata!(stream.stream, buffer) end buffer.transcoded += nfilled diff --git a/src/stream.jl b/src/stream.jl index ade7a058..fb4bc88d 100644 --- a/src/stream.jl +++ b/src/stream.jl @@ -575,7 +575,7 @@ function fillbuffer(stream::TranscodingStream; eager::Bool = false) end callstartproc(stream, :read) end - makemargin!(buffer2, 1) + makemargin!(buffer2, max(1, div(length(buffer2), 2))) readdata!(stream.stream, buffer2) _, Δout = callprocess(stream, buffer2, buffer1) nfilled += Δout