{-# LANGUAGE Rank2Types #-}
module Data.StorableVector.Lazy.Builder (
Builder,
toLazyStorableVector,
put,
flush,
) where
import qualified Data.StorableVector as SV
import qualified Data.StorableVector.Lazy as SVL
import qualified Data.StorableVector.ST.Strict as STV
import Data.StorableVector.Lazy (ChunkSize, )
import Control.Monad (liftM2, )
import Control.Monad.ST.Strict (ST, runST, )
import Data.Monoid (Monoid(mempty, mappend), )
import Data.Semigroup (Semigroup((<>)), )
import Foreign.Storable (Storable, )
import qualified System.Unsafe as Unsafe
newtype Builder a =
Builder {forall a.
Builder a
-> forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a]) -> Buffer s a -> ST s [Vector a]
run :: forall s.
ChunkSize ->
(Buffer s a -> ST s [SV.Vector a]) ->
(Buffer s a -> ST s [SV.Vector a])
}
type Buffer s a = (STV.Vector s a, Int)
instance Storable a => Semigroup (Builder a) where
{-# INLINE (<>) #-}
Builder a
x <> :: Builder a -> Builder a -> Builder a
<> Builder a
y = forall a.
(forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a])
-> Buffer s a
-> ST s [Vector a])
-> Builder a
Builder (\ChunkSize
cs -> forall a.
Builder a
-> forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a]) -> Buffer s a -> ST s [Vector a]
run Builder a
x ChunkSize
cs forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
Builder a
-> forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a]) -> Buffer s a -> ST s [Vector a]
run Builder a
y ChunkSize
cs)
instance Storable a => Monoid (Builder a) where
{-# INLINE mempty #-}
{-# INLINE mappend #-}
mempty :: Builder a
mempty = forall a.
(forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a])
-> Buffer s a
-> ST s [Vector a])
-> Builder a
Builder (\ChunkSize
_ -> forall a. a -> a
id)
mappend :: Builder a -> Builder a -> Builder a
mappend = forall a. Semigroup a => a -> a -> a
(<>)
{-# INLINE toLazyStorableVector #-}
toLazyStorableVector :: Storable a =>
ChunkSize -> Builder a -> SVL.Vector a
toLazyStorableVector :: forall a. Storable a => ChunkSize -> Builder a -> Vector a
toLazyStorableVector ChunkSize
cs Builder a
bld =
forall a. Storable a => [Vector a] -> Vector a
SVL.fromChunks forall a b. (a -> b) -> a -> b
$
forall a. (forall s. ST s a) -> a
runST (forall a.
Builder a
-> forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a]) -> Buffer s a -> ST s [Vector a]
run Builder a
bld ChunkSize
cs (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. a -> [a] -> [a]
:[]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a s. Storable a => Buffer s a -> ST s (Vector a)
fixVector) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a s. Storable a => ChunkSize -> ST s (Buffer s a)
newChunk ChunkSize
cs)
{-# INLINE put #-}
put :: Storable a => a -> Builder a
put :: forall a. Storable a => a -> Builder a
put a
a =
forall a.
(forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a])
-> Buffer s a
-> ST s [Vector a])
-> Builder a
Builder (\ChunkSize
cs Buffer s a -> ST s [Vector a]
cont (Vector s a
v0,Int
i0) ->
do forall e s. Storable e => Vector s e -> Int -> e -> ST s ()
STV.unsafeWrite Vector s a
v0 Int
i0 a
a
let i1 :: Int
i1 = forall a. Enum a => a -> a
succ Int
i0
if Int
i1 forall a. Ord a => a -> a -> Bool
< forall s e. Vector s e -> Int
STV.length Vector s a
v0
then
Buffer s a -> ST s [Vector a]
cont (Vector s a
v0, Int
i1)
else
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:)
(forall e s. Storable e => Vector s e -> ST s (Vector e)
STV.unsafeFreeze Vector s a
v0)
(forall s a. ST s a -> ST s a
Unsafe.interleaveST forall a b. (a -> b) -> a -> b
$
Buffer s a -> ST s [Vector a]
cont forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a s. Storable a => ChunkSize -> ST s (Buffer s a)
newChunk ChunkSize
cs)
)
{-# INLINE flush #-}
flush :: Storable a => Builder a
flush :: forall a. Storable a => Builder a
flush =
forall a.
(forall s.
ChunkSize
-> (Buffer s a -> ST s [Vector a])
-> Buffer s a
-> ST s [Vector a])
-> Builder a
Builder (\ChunkSize
cs Buffer s a -> ST s [Vector a]
cont Buffer s a
vi0 ->
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:)
(forall a s. Storable a => Buffer s a -> ST s (Vector a)
fixVector Buffer s a
vi0)
(forall s a. ST s a -> ST s a
Unsafe.interleaveST forall a b. (a -> b) -> a -> b
$ Buffer s a -> ST s [Vector a]
cont forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a s. Storable a => ChunkSize -> ST s (Buffer s a)
newChunk ChunkSize
cs)
)
{-# INLINE newChunk #-}
newChunk :: (Storable a) =>
ChunkSize -> ST s (Buffer s a)
newChunk :: forall a s. Storable a => ChunkSize -> ST s (Buffer s a)
newChunk (SVL.ChunkSize Int
size) =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b c. (a -> b -> c) -> b -> a -> c
flip (,) Int
0) forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Int -> ST s (Vector s e)
STV.new_ Int
size
{-# INLINE fixVector #-}
fixVector :: (Storable a) =>
Buffer s a -> ST s (SV.Vector a)
fixVector :: forall a s. Storable a => Buffer s a -> ST s (Vector a)
fixVector ~(Vector s a
v1,Int
i1) =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Storable a => Int -> Vector a -> Vector a
SV.take Int
i1) forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Vector s e -> ST s (Vector e)
STV.unsafeFreeze Vector s a
v1