Closed abonander closed 6 years ago
but if address space is at a premium in your application then this may be a concern.
I would add here that this concern is particularly relevant for 32-bit platforms where one "only" has 4 Gb of virtual memory.
Published as 0.7.0
This
0.7.0
release adds a major new feature, and some other significant changes:Ringbuffers and
slice-deque
At @gnzlbg's recommendation, I implemented support for ringbuffers using his
slice-deque
crate (exposed by a target-feature of the same name), which uses virtual-memory tricks to create a buffer that loops around on itself in memory, such that consuming data from the head simultaneously makes more room at the tail..make_room()
on buffered types subsequently becomes a no-op. However, this has some caveats:It is only available on target platforms with virtual memory support, namely fully fledged OSes such as Windows and Unix-derivative platforms like Linux, OS X, BSD variants, etc.
The default capacity varies based on platform, and custom capacities are rounded up to a multiple of their minimum size, typically the page size of the platform. Windows' minimum size is comparably quite large (64 KiB) due to some legacy reasons, so this may be less optimal than the default capacity for a normal buffer (8 KiB) for some use-cases.
Due to the nature of the virtual-memory trick, the virtual address space the buffer allocates will be double its capacity. This means that your program will appear to use more memory than it would if it was using a normal buffer of the same capacity. The physical memory usage will be the same in both cases, but if address space is at a premium in your application (32-bit targets) then this may be a concern.
Still, this may be beneficial with the new policies, like
MinBuffered
, that will read into the buffer and consume bytes from it without completely emptying it. Any buffered type can be made to utilize a ringbuffer simply by using the::new_ringbuf()
or::with_capacity_ringbuf()
constructors instead of::new()
orwith_capacity()
, respectively.Strategies Consolidated into Policies
The
ReadStrategy
andMoveStrategy
traits are now consolidated into theReaderPolicy
trait, and theFlushStrategy
trait is renamed toWriterPolicy
for consistency. The callbacks of these traits get a mutable reference to the internalBuffer
so they can make room or reserve space if necessary. These traits and some provided implementations are in the newpolicy
module.StdPolicy
is provided as the default implementation of bothReaderPolicy
andWriterPolicy
, which implements thestd::io
behaviors forBufReader
andBufWriter
, respectively.MinBuffered
is a newReaderPolicy
which ensures there is at least the given number of bytes in the buffer every time.fill_buf()
is called until the source reader is out of data. This is useful for parsing applications which require a certain amount of lookahead.The given
WriterPolicy
implementations are mostly unchanged in behavior from theirFlushStrategy
days, though some have been renamed.On top of all this, test coverage and documentation has been significantly improved.
closes #5