streamly-0.8.0: Dataflow programming and declarative concurrency
Copyright(c) 2019 Composewell Technologies
LicenseBSD3
Maintainerstreamly@composewell.com
Stabilityexperimental
PortabilityGHC
Safe HaskellNone
LanguageHaskell2010

Streamly.Internal.Ring.Foreign

Description

 
Synopsis

Documentation

data Ring a Source #

A ring buffer is a mutable array of fixed size. Initially the array is empty, with ringStart pointing at the start of allocated memory. We call the next location to be written in the ring as ringHead. Initially ringHead == ringStart. When the first item is added, ringHead points to ringStart + sizeof item. When the buffer becomes full ringHead would wrap around to ringStart. When the buffer is full, ringHead always points at the oldest item in the ring and the newest item added always overwrites the oldest item.

When using it we should keep in mind that a ringBuffer is a mutable data structure. We should not leak out references to it for immutable use.

Constructors

Ring 

Fields

Construction

new :: forall a. Storable a => Int -> IO (Ring a, Ptr a) Source #

Create a new ringbuffer and return the ring buffer and the ringHead. Returns the ring and the ringHead, the ringHead is same as ringStart.

advance :: forall a. Storable a => Ring a -> Ptr a -> Ptr a Source #

Advance the ringHead by 1 item, wrap around if we hit the end of the array.

moveBy :: forall a. Storable a => Int -> Ring a -> Ptr a -> Ptr a Source #

Move the ringHead by n items. The direction depends on the sign on whether n is positive or negative. Wrap around if we hit the beginning or end of the array.

startOf :: Ring a -> Ptr a Source #

Get the first address of the ring as a pointer.

Modification

unsafeInsert :: Storable a => Ring a -> Ptr a -> a -> IO (Ptr a) Source #

Insert an item at the head of the ring, when the ring is full this replaces the oldest item in the ring with the new item. This is unsafe beause ringHead supplied is not verified to be within the Ring. Also, the ringStart foreignPtr must be guaranteed to be alive by the caller.

Folds

unsafeFoldRing :: forall a b. Storable a => Ptr a -> (b -> a -> b) -> b -> Ring a -> b Source #

Fold the buffer starting from ringStart up to the given Ptr using a pure step function. This is useful to fold the items in the ring when the ring is not full. The supplied pointer is usually the end of the ring.

Unsafe because the supplied Ptr is not checked to be in range.

unsafeFoldRingM :: forall m a b. (MonadIO m, Storable a) => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b Source #

Like unsafeFoldRing but with a monadic step function.

unsafeFoldRingFullM :: forall m a b. (MonadIO m, Storable a) => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b Source #

Fold the entire length of a ring buffer starting at the supplied ringHead pointer. Assuming the supplied ringHead pointer points to the oldest item, this would fold the ring starting from the oldest item to the newest item in the ring.

Note, this will crash on ring of 0 size.

unsafeFoldRingNM :: forall m a b. (MonadIO m, Storable a) => Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b Source #

Fold Int items in the ring starting at Ptr a. Won't fold more than the length of the ring.

Note, this will crash on ring of 0 size.

Fast Byte Comparisons

unsafeEqArray :: Ring a -> Ptr a -> Array a -> Bool Source #

Byte compare the entire length of ringBuffer with the given array, starting at the supplied ringHead pointer. Returns true if the Array and the ringBuffer have identical contents.

This is unsafe because the ringHead Ptr is not checked to be in range. The supplied array must be equal to or bigger than the ringBuffer, ARRAY BOUNDS ARE NOT CHECKED.

unsafeEqArrayN :: Ring a -> Ptr a -> Array a -> Int -> Bool Source #

Like unsafeEqArray but compares only N bytes instead of entire length of the ring buffer. This is unsafe because the ringHead Ptr is not checked to be in range.