@@ -132,7 +132,7 @@ module Streamly.Internal.Data.MutArray.Generic
132 -- multidimensional array representations.
132 -- multidimensional array representations.
134 -- ** Construct from streams
134 -- ** Construct from streams
135− -- , chunksOf
135+ , chunksOf
136 -- , arrayStreamKFromStreamD
136 -- , arrayStreamKFromStreamD
137 -- , writeChunks
137 -- , writeChunks
@@ -182,6 +182,7 @@ import Streamly.Internal.Data.Fold.Type (Fold(..))
182import Streamly.Internal.Data.Producer.Type (Producer (..))
182import Streamly.Internal.Data.Producer.Type (Producer (..))
183import Streamly.Internal.Data.Unfold.Type (Unfold(..))
183import Streamly.Internal.Data.Unfold.Type (Unfold(..))
184import Streamly.Internal.Data.Stream.StreamD.Type (Stream)
184import Streamly.Internal.Data.Stream.StreamD.Type (Stream)
185+import Streamly.Internal.Data.SVar.Type (adaptState)
186import qualified Streamly.Internal.Data.Fold.Type as FL
187import qualified Streamly.Internal.Data.Fold.Type as FL
187import qualified Streamly.Internal.Data.Producer as Producer
188import qualified Streamly.Internal.Data.Producer as Producer
@@ -263,6 +264,21 @@ nil = new 0
263-- Random writes
264-- Random writes
264-------------------------------------------------------------------------------
265-------------------------------------------------------------------------------
267+-- | Write the given element to the given index of the 'MutableArray#'. Does not
268+-- check if the index is out of bounds of the array.
271+{-# INLINE putIndexUnsafeWith #-}
272+putIndexUnsafeWith :: MonadIO m => Int -> MutableArray# RealWorld a -> a -> m ()
273+putIndexUnsafeWith n _arrContents# x =
279+ let s1# = writeArray# _arrContents# n# x s#
266-- | Write the given element to the given index of the array. Does not check if
282-- | Write the given element to the given index of the array. Does not check if
267-- the index is out of bounds of the array.
283-- the index is out of bounds of the array.
@@ -271,13 +287,7 @@ nil = new 0
271putIndexUnsafe :: forall m a. MonadIO m => Int -> MutArray a -> a -> m ()
287putIndexUnsafe :: forall m a. MonadIO m => Int -> MutArray a -> a -> m ()
272putIndexUnsafe i MutArray {..} x =
288putIndexUnsafe i MutArray {..} x =
273 assert (i >= 0 && i < arrLen)
289 assert (i >= 0 && i < arrLen)
274− (liftIO
290+ putIndexUnsafeWith (i + arrStart) arrContents# x
277− case i + arrStart of
279− let s1# = writeArray# arrContents# n# x s#
282invalidIndex :: String -> Int -> a
292invalidIndex :: String -> Int -> a
283invalidIndex label i =
293invalidIndex label i =
@@ -666,6 +676,75 @@ fromPureStream :: MonadIO m => Stream Identity a -> m (MutArray a)
666fromPureStream xs =
676fromPureStream xs =
667 liftIO $ D.fold write $ D.morphInner (return . runIdentity) xs
677 liftIO $ D.fold write $ D.morphInner (return . runIdentity) xs
679+-------------------------------------------------------------------------------
681+-------------------------------------------------------------------------------
683+data GroupState s a start end bound
685+ | GroupBuffer s (MutableArray# RealWorld a) start end bound
687+ (MutableArray# RealWorld a)
691+ (GroupState s a start end bound)
694+-- | @chunksOf n stream@ groups the input stream into a stream of
697+-- @chunksOf n = foldMany (MutArray.writeN n)@
700+{-# INLINE_NORMAL chunksOf #-}
701+chunksOf :: forall m a. MonadIO m
702+ => Int -> D.Stream m a -> D.Stream m (MutArray a)
703+-- XXX the idiomatic implementation leads to large regression in the D.reverse'
704+-- benchmark. It seems it has difficulty producing optimized code when
705+-- converting to StreamK. Investigate GHC optimizations.
706+-- chunksOf n = D.foldMany (writeN n)
707+chunksOf n (D.Stream step state) =
708+ D.Stream step' (GroupStart state)
712+ -- start is always 0
713+ -- end and len are always equal
715+ {-# INLINE_LATE step' #-}
716+ step' _ (GroupStart st) = do
718+ -- XXX we can pass the module string from the higher level API
719+ error $ "Streamly.Internal.Data.Array.Generic.Mut.Type.chunksOf: "
720+ ++ "the size of arrays [" ++ show n
721+ ++ "] must be a natural number"
722+ (MutArray contents start end bound :: MutArray a) <- new n
723+ return $ D.Skip (GroupBuffer st contents start end bound)
725+ step' gst (GroupBuffer st contents start end bound) = do
726+ r <- step (adaptState gst) st
729+ putIndexUnsafeWith end contents x
735+ contents start end1 bound (GroupStart s))
736+ else D.Skip (GroupBuffer s contents start end1 bound)
738+ return $ D.Skip (GroupBuffer s contents start end bound)
741+ $ D.Skip (GroupYield contents start end bound GroupFinish)
743+ step' _ (GroupYield contents start end bound next) =
744+ return $ D.Yield (MutArray contents start end bound) next
746+ step' _ GroupFinish = return D.Stop
669-------------------------------------------------------------------------------
748-------------------------------------------------------------------------------
670-- Unfolds
749-- Unfolds
671-------------------------------------------------------------------------------
750-------------------------------------------------------------------------------