fast-builder-0.1.4.0: Fast ByteString Builder
Safe HaskellNone
LanguageHaskell2010

Data.ByteString.FastBuilder.Internal

Description

This is an internal module; its interface is unstable.

Synopsis

Builder and related types

newtype Builder Source #

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

Constructors

Builder 

Instances

Instances details
IsString Builder Source #

fromString = stringUtf8

Instance details

Defined in Data.ByteString.FastBuilder.Internal

Methods

fromString :: String -> Builder #

Monoid Builder Source # 
Instance details

Defined in Data.ByteString.FastBuilder.Internal

Semigroup Builder Source # 
Instance details

Defined in Data.ByteString.FastBuilder.Internal

type BuilderState = (# Addr#, Addr#, State# RealWorld #) Source #

The state of a builder. The components are:

  • The "cur" pointer
  • The "end" pointer
  • The state token

data DataSink Source #

Specifies where bytes generated by a builder go.

Constructors

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 Queue, then flushed to the Handle.

data DynamicSink Source #

Variable-destination cases.

Constructors

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 ThreadedSink.

data Queue Source #

A mutable buffer.

Constructors

Queue 

Fields

data Request Source #

A request from the driver thread to the builder thread.

Constructors

Request !(Ptr Word8) !(Ptr Word8) 

data Response Source #

A response from the builder thread to the driver thread.

Constructors

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.

Instances

Instances details
Show Response Source # 
Instance details

Defined in Data.ByteString.FastBuilder.Internal

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.

Constructors

SuspendBuilderException !(MVar ()) 

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.

Builder building blocks

newtype BuildM a Source #

An internal type for making it easier to define builders. A value of BuildM a can do everything a Builder can do, and in addition, returns a value of type a upon completion.

Constructors

BuildM 

Fields

Instances

Instances details
Applicative BuildM Source # 
Instance details

Defined in Data.ByteString.FastBuilder.Internal

Methods

pure :: a -> BuildM a #

(<*>) :: BuildM (a -> b) -> BuildM a -> BuildM b #

liftA2 :: (a -> b -> c) -> BuildM a -> BuildM b -> BuildM c #

(*>) :: BuildM a -> BuildM b -> BuildM b #

(<*) :: BuildM a -> BuildM b -> BuildM a #

Functor BuildM Source # 
Instance details

Defined in Data.ByteString.FastBuilder.Internal

Methods

fmap :: (a -> b) -> BuildM a -> BuildM b #

(<$) :: a -> BuildM b -> BuildM a #

Monad BuildM Source # 
Instance details

Defined in Data.ByteString.FastBuilder.Internal

Methods

(>>=) :: BuildM a -> (a -> BuildM b) -> BuildM b #

(>>) :: BuildM a -> BuildM b -> BuildM b #

return :: a -> BuildM a #

mkBuilder :: BuildM () -> Builder Source #

Create a builder from a BuildM.

useBuilder :: Builder -> BuildM () Source #

Embed a builder in the BuildM context.

getCur :: BuildM (Ptr Word8) Source #

Get the current pointer.

getEnd :: BuildM (Ptr Word8) Source #

Get the end-of-buffer pointer.

setCur :: Ptr Word8 -> BuildM () Source #

Set the current pointer.

setEnd :: Ptr Word8 -> BuildM () Source #

Set the end-of-buffer pointer.

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 using runInUnboundThread for this.
  • Use other function to run the Builder instead. Functions that don't return a lazy ByteString 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.

hPutBuilder :: Handle -> Builder -> IO () Source #

Output a Builder to a Handle.

hPutBuilderLen :: Handle -> Builder -> IO Int Source #

Output a Builder to a Handle. Returns the number of bytes written.

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.

primFixed :: FixedPrim a -> a -> Builder Source #

Turn a value of type a into a Builder, using the given FixedPrim.

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 #

Turn a list of values of type a into a Builder, using the given FixedPrim.

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 #

Turn a C String into a Builder. The behavior is undefined if the given CString does not point to a constant null-terminated string.

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 #

ensureBytes n ensures that at least n bytes of free space is available in the current buffer, by allocating a new buffer when necessary.

getBytes :: Int -> Builder Source #

getBytes n allocates a new buffer, containing at least n bytes.

Performance tuning

rebuild :: Builder -> Builder Source #

rebuild b is equivalent to b, 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 ...