Safe Haskell | None |
---|---|
Language | Haskell2010 |
This is an internal module; its interface is unstable.
Synopsis
- newtype Builder = Builder {
- unBuilder :: DataSink -> BuilderState -> BuilderState
- type BuilderState = (# Addr#, Addr#, State# RealWorld #)
- data DataSink
- = DynamicSink !(IORef DynamicSink)
- | GrowingBuffer !(IORef (ForeignPtr Word8))
- | HandleSink !Handle !Int !(IORef Queue)
- data DynamicSink
- = ThreadedSink !(MVar Request) !(MVar Response)
- | BoundedGrowingBuffer !(ForeignPtr Word8) !Int
- data Queue = Queue {
- queueBuffer :: !(ForeignPtr Word8)
- queueStart :: !Int
- queueTotal :: !Int
- data Request = Request !(Ptr Word8) !(Ptr Word8)
- data Response
- = Error SomeException
- | Done !(Ptr Word8)
- | MoreBuffer !(Ptr Word8) !Int
- | InsertByteString !(Ptr Word8) !ByteString
- data SuspendBuilderException = SuspendBuilderException !(MVar ())
- data ChunkOverflowException = ChunkOverflowException !ByteString !(MVar Request) !(MVar Response) !Int
- newtype BuildM a = BuildM {}
- mkBuilder :: BuildM () -> Builder
- useBuilder :: Builder -> BuildM ()
- getSink :: BuildM DataSink
- getCur :: BuildM (Ptr Word8)
- getEnd :: BuildM (Ptr Word8)
- setCur :: Ptr Word8 -> BuildM ()
- setEnd :: Ptr Word8 -> BuildM ()
- runBuilder :: Builder -> DataSink -> Ptr Word8 -> Ptr Word8 -> IO (Ptr Word8)
- toLazyByteString :: Builder -> ByteString
- toLazyByteStringWith :: Int -> Int -> Builder -> ByteString
- toStrictByteString :: Builder -> ByteString
- hPutBuilder :: Handle -> Builder -> IO ()
- hPutBuilderLen :: Handle -> Builder -> IO Int
- hPutBuilderWith :: Handle -> Int -> Int -> Builder -> IO Int
- primBounded :: BoundedPrim a -> a -> Builder
- primFixed :: FixedPrim a -> a -> Builder
- primMapListBounded :: BoundedPrim a -> [a] -> Builder
- primMapListFixed :: FixedPrim a -> [a] -> Builder
- byteString :: ByteString -> Builder
- byteStringThreshold :: Int -> ByteString -> Builder
- byteStringCopy :: ByteString -> Builder
- byteStringCopyNoCheck :: ByteString -> Builder
- byteStringInsert :: ByteString -> Builder
- unsafeCString :: CString -> Builder
- unsafeCStringLen :: CStringLen -> Builder
- ensureBytes :: Int -> Builder
- getBytes :: Int -> Builder
- rebuild :: Builder -> Builder
Builder and related types
Builder
is an auxiliary type for efficiently generating a long
ByteString
. It is isomorphic to lazy ByteString
, but offers
constant-time concatanation via <>
.
Use toLazyByteString
to turn a Builder
into a ByteString
Builder | |
|
type BuilderState = (# Addr#, Addr#, State# RealWorld #) Source #
The state of a builder. The components are:
- The "cur" pointer
- The "end" pointer
- The state token
Specifies where bytes generated by a builder go.
DynamicSink !(IORef DynamicSink) | The destination of data changes while the builder is running. |
GrowingBuffer !(IORef (ForeignPtr Word8)) | Bytes are accumulated in a contiguous buffer. |
HandleSink !Handle !Int !(IORef Queue) | Bytes are first accumulated in the |
data DynamicSink Source #
Variable-destination cases.
ThreadedSink !(MVar Request) !(MVar Response) | Bytes are sent to another thread. |
BoundedGrowingBuffer !(ForeignPtr Word8) !Int | Bytes are accumulated in a contiguous buffer until the
size limit is reached. After that, the destination switches
to a |
A mutable buffer.
Queue | |
|
A request from the driver thread to the builder thread.
A response from the builder thread to the driver thread.
Error SomeException | A synchronous exception was thrown by the builder |
Done !(Ptr Word8) | The builder thread has completed. |
MoreBuffer !(Ptr Word8) !Int | The builder thread has finished generating one chunk, and waits for another request with the specified minimum size. |
InsertByteString !(Ptr Word8) !ByteString | The builder thread has partially filled the current chunk, and wants to emit the bytestring to be included in the final output. |
Internally used exceptions
data SuspendBuilderException Source #
Used in the implementation of toLazyByteString
. This is a message sent
from the consumer thread to the builder thread, requesting the builder
thread to temporarily pause execution. Later, the consumer thread may
request resumption by filling the MVar
.
SuspendBuilderException !(MVar ()) |
Instances
data ChunkOverflowException Source #
Used in the implementation of toLazyByteString
. This is an exception
thrown by the consumer thread to itself when it has finished filling the
first chunk of the output. After this, a thread will be forked, and the
execution of the builder will be resumed in the new thread, using
ThreadedSink
.
Instances
Builder building blocks
An internal type for making it easier to define builders. A value of
can do everything a BuildM
aBuilder
can do, and in addition,
returns a value of type a
upon completion.
useBuilder :: Builder -> BuildM () Source #
Embed a builder in the BuildM context.
Running builders
runBuilder :: Builder -> DataSink -> Ptr Word8 -> Ptr Word8 -> IO (Ptr Word8) Source #
Run a builder.
toLazyByteString :: Builder -> ByteString Source #
Turn a Builder
into a lazy ByteString
.
Performance hint: when the resulting ByteString
does not fit
in one chunk, this function forks a thread. Due to this, the performance
degrades sharply if you use this function from a bound thread. Note in
particular that the main thread is a bound thread when you use ghc
-threaded
.
To avoid this problem, do one of these:
- Make sure the resulting
ByteString
is consumed in an unbound thread. Consider usingrunInUnboundThread
for this. - Use other function to run the
Builder
instead. Functions that don't return a lazyByteString
do not have this issue. - Link your program without
-threaded
.
toLazyByteStringWith :: Int -> Int -> Builder -> ByteString Source #
Like toLazyByteString
, but allows the user to specify the initial
and the subsequent desired buffer sizes.
toStrictByteString :: Builder -> ByteString Source #
Turn a Builder
into a strict ByteString
.
hPutBuilderWith :: Handle -> Int -> Int -> Builder -> IO Int Source #
Like hPutBuffer
, but allows the user to specify the initial
and the subsequent desired buffer sizes. This function may be useful for
setting large buffer when high throughput I/O is needed.
Basic builders
primBounded :: BoundedPrim a -> a -> Builder Source #
Turn a value of type a
into a Builder
, using the given BoundedPrim
.
primMapListBounded :: BoundedPrim a -> [a] -> Builder Source #
Turn a list of values of type a
into a Builder
, using the given
BoundedPrim
.
primMapListFixed :: FixedPrim a -> [a] -> Builder Source #
byteString :: ByteString -> Builder Source #
Turn a ByteString
to a Builder
.
byteStringThreshold :: Int -> ByteString -> Builder Source #
Turn a ByteString
to a Builder
. If the size of the ByteString
is larger than the given threshold, avoid copying it as much
as possible.
byteStringCopy :: ByteString -> Builder Source #
Turn a ByteString
to a Builder
. The ByteString
will be copied
to the buffer, regardless of the size.
byteStringCopyNoCheck :: ByteString -> Builder Source #
Like byteStringCopy
, but assumes that the current buffer is large enough.
byteStringInsert :: ByteString -> Builder Source #
Turn a ByteString
to a Builder
. When possible, the given
ByteString
will not be copied, and inserted directly into the output
instead.
unsafeCString :: CString -> Builder Source #
unsafeCStringLen :: CStringLen -> Builder Source #
Turn a CStringLen
into a Builder
. The behavior is undefined if the
given CStringLen
does not point to a constant memory block.
ensureBytes :: Int -> Builder Source #
ensures that at least ensureBytes
nn
bytes of free space is
available in the current buffer, by allocating a new buffer when
necessary.
Performance tuning
rebuild :: Builder -> Builder Source #
is equivalent to rebuild
bb
, but it allows GHC to assume
that b
will be run at most once. This can enable various
optimizations that greately improve performance.
There are two types of typical situations where a use of rebuild
is often a win:
- When constructing a builder using a recursive function. e.g.
rebuild $ foldr ...
. - When constructing a builder using a conditional expression. e.g.
rebuild $ case x of ...