Buffering for output streams based on bytestring builders.
Buffering an output stream can often improve throughput by reducing
the number of system calls made through the file descriptor. The
bytestring package provides an efficient monoidal datatype
used for serializing values directly to an output buffer, called a
Builder, originally implemented in the
blaze-builder
package by Simon Meier. When compiling with
bytestring
versions older than 0.10.4, (i.e. GHC <= 7.6) users must depend on
the
bytestring-builder library to get the new builder
implementation. Since we try to maintain compatibility with the last
three GHC versions, the dependency on
bytestring-builder can
be dropped after the release of GHC 7.12.
Using this module
Given an
OutputStream taking
ByteString:
someOutputStream :: OutputStream ByteString
You create a new output stream wrapping the original one that accepts
Builder values:
do
newStream <- Streams.builderStream someOutputStream
Streams.write (Just $ byteString "hello") newStream
....
You can flush the output buffer using
flush:
....
Streams.write (Just flush) newStream
....
As a convention,
builderStream will write the empty string to
the wrapped
OutputStream upon a builder buffer flush. Output
streams which receive
ByteString should either ignore the empty
string or interpret it as a signal to flush their own buffers, as the
handleToOutputStream and
System.IO.Streams.Zlib
functions do.
Example
example :: IO [ByteString]
example = do
let l1 = intersperse " " ["the", "quick", "brown", "fox"]
let l2 = intersperse " " ["jumped", "over", "the"]
let l = map byteString l1 ++ [flush] ++ map byteString l2
is <- Streams.fromList l
(os0, grab) <- Streams.listOutputStream
os <- Streams.builderStream os0
Streams.connect is os >> grab
ghci> example
["the quick brown fox","","jumped over the"]