on master help sign in
Rename ArrayStream fold/parse operations

Add comments about implementing fold in terms of foldArr

commit107bebd771e13384e73ca33981778dc5a4449cfe authorHarendra Kumar <harendra@composewell.com> dateTue 17 May 2022, 17:51 (4 years ago) parentf1c5e5c
3 files changed+69−44
benchmark/Streamly/Benchmark/Data/Array/Stream/Foreign.hs+10−10 core/src/Streamly/Internal/Data/Array/Stream/Fold/Foreign.hs+3−1 src/Streamly/Internal/Data/Array/Stream/Foreign.hs+56−33
benchmark/Streamly/Benchmark/Data/Array/Stream/Foreign.hs+10−10
@@ -25,7 +25,7 @@ module Main
2525
2626import Control.DeepSeq (NFData(..))
2727import Control.Monad (void)
28−import Control.Monad.Catch (MonadThrow)
28+import Control.Monad.Catch (MonadCatch)
2929import Data.Functor.Identity (runIdentity)
3030import Data.Word (Word8)
3131import System.IO (Handle)
@@ -36,7 +36,7 @@ import qualified Streamly.Prelude as Stream
3636import qualified Streamly.Internal.Data.Array.Foreign as Array
3737import qualified Streamly.Internal.Data.Array.Stream.Foreign as ArrayStream
3838import qualified Streamly.Internal.Data.Fold as Fold
39−import qualified Streamly.Internal.Data.Parser.ParserD as ParserD
39+import qualified Streamly.Internal.Data.Parser as Parser
4040import qualified Streamly.Internal.Data.Stream.IsStream as Stream (arraysOf)
4141import qualified Streamly.Internal.FileSystem.Handle as Handle
4242import qualified Streamly.Internal.Unicode.Stream as Unicode
@@ -218,8 +218,8 @@ o_1_space_copy_toChunks_group_ungroup env =
218218-------------------------------------------------------------------------------
219219
220220{-# INLINE drainWhile #-}
221−drainWhile :: MonadThrow m => (a -> Bool) -> ParserD.Parser m a ()
222−drainWhile p = ParserD.takeWhile p Fold.drain
221+drainWhile :: MonadCatch m => (a -> Bool) -> Parser.Parser m a ()
222+drainWhile p = Parser.takeWhile p Fold.drain
223223
224224-------------------------------------------------------------------------------
225225-- Folds and parsers
@@ -227,11 +227,11 @@ drainWhile p = ParserD.takeWhile p Fold.drain
227227
228228{-# INLINE fold #-}
229229fold :: SerialT IO (Array.Array Int) -> IO ()
230−fold s = void $ ArrayStream.fold Fold.drain s
230+fold s = void $ ArrayStream.foldBreak Fold.drain s
231231
232−{-# INLINE parseArray #-}
233−parseArray :: Int -> SerialT IO (Array.Array Int) -> IO ()
234−parseArray value s = void $ ArrayStream.parse (drainWhile (< value)) s
232+{-# INLINE parse #-}
233+parse :: Int -> SerialT IO (Array.Array Int) -> IO ()
234+parse value s = void $ ArrayStream.parseBreak (drainWhile (< value)) s
235235
236236o_1_space_serial_array ::
237237 Int -> [Array.Array Int] -> [Array.Array Int] -> [Benchmark]
@@ -239,9 +239,9 @@ o_1_space_serial_array bound arraysSmall arraysBig =
239239 [ benchIO "fold (of 100)" (\_ -> Stream.fromList arraysSmall) fold
240240 , benchIO "fold (single)" (\_ -> Stream.fromList arraysBig) fold
241241 , benchIO "parse (of 100)" (\_ -> Stream.fromList arraysSmall)
242− $ parseArray bound
242+ $ parse bound
243243 , benchIO "parse (single)" (\_ -> Stream.fromList arraysBig)
244− $ parseArray bound
244+ $ parse bound
245245 ]
246246
247247-------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Array/Stream/Fold/Foreign.hs+3−1
@@ -23,7 +23,9 @@
2323-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (arraysOf)
2424-- >>> import qualified Streamly.Prelude as Stream
2525--
26−-- >>> ArrayStream.foldArr (ArrayFold.fromFold (Fold.take 7 Fold.toList)) $ Stream.arraysOf 5 $ Stream.fromList "hello world"
26+-- >>> f = ArrayFold.fromFold (Fold.take 7 Fold.toList)
27+-- >>> s = Stream.arraysOf 5 $ Stream.fromList "hello world"
28+-- >>> ArrayStream.runArrayFold f s
2729-- "hello w"
2830--
2931module Streamly.Internal.Data.Array.Stream.Fold.Foreign
src/Streamly/Internal/Data/Array/Stream/Foreign.hs+56−33
@@ -23,16 +23,16 @@ module Streamly.Internal.Data.Array.Stream.Foreign
2323
2424 -- * Elimination
2525 -- ** Element Folds
26− , fold
27− , parse
28− , parseD
26+ , foldBreak
27+ , parseBreak
28+ , parseBreakD
2929
3030 -- ** Array Folds
31− , foldArr
32− , foldArr_
31+ , runArrayFold
32+ , runArrayFoldBreak
3333 -- , parseArr
34− , parseArrD
35− , foldArrMany
34+ , runArrayParserDBreak
35+ , runArrayFoldMany
3636
3737 , toArray
3838
@@ -82,6 +82,8 @@ import Streamly.Internal.Data.Array.Foreign.Mut.Type
8282
8383import qualified Streamly.Internal.Data.Array.Foreign as A
8484import qualified Streamly.Internal.Data.Array.Foreign as Array
85+-- import qualified Streamly.Internal.Data.Array.Stream.Fold.Foreign
86+-- as ArrayFold
8587import qualified Streamly.Internal.Data.Array.Foreign.Type as A
8688import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
8789import qualified Streamly.Internal.Data.Array.Stream.Mut.Foreign as AS
@@ -359,15 +361,20 @@ foldD (Fold fstep initial extract) stream@(D.Stream step state) = do
359361-- | Fold an array stream using the supplied 'Fold'. Returns the fold result
360362-- and the unconsumed stream.
361363--
364+-- > foldBreak f = runArrayFoldBreak (ArrayFold.fromFold f)
365+--
362366-- /Internal/
363367--
364−{-# INLINE_NORMAL fold #-}
365−fold ::
368+{-# INLINE_NORMAL foldBreak #-}
369+foldBreak ::
366370 (MonadIO m, Storable a)
367371 => FL.Fold m a b
368372 -> SerialT m (A.Array a)
369373 -> m (b, SerialT m (A.Array a))
370−fold f s = fmap fromStreamD <$> foldD f (toStreamD s)
374+foldBreak f s = fmap fromStreamD <$> foldD f (toStreamD s)
375+-- If fold performs better than runArrayFoldBreak we can rewrite runArrayFoldBreak to
376+-- fold.
377+-- fold f = runArrayFoldBreak (ArrayFold.fromFold f)
371378
372379-------------------------------------------------------------------------------
373380-- Fold to a single Array
@@ -524,13 +531,15 @@ newtype List a = List {getList :: [a]}
524531--
525532-- XXX This should be written using CPS (as parseK) if we want it to scale wrt
526533-- to the number of times it can be called on the same stream.
527−{-# INLINE_NORMAL parseD #-}
528−parseD ::
534+{-# INLINE_NORMAL parseBreakD #-}
535+parseBreakD ::
529536 forall m a b. (MonadIO m, MonadThrow m, Storable a)
530537 => PRD.Parser m a b
531538 -> D.Stream m (Array.Array a)
532539 -> m (b, D.Stream m (Array.Array a))
533−parseD (PRD.Parser pstep initial extract) stream@(D.Stream step state) = do
540+parseBreakD
541+ (PRD.Parser pstep initial extract) stream@(D.Stream step state) = do
542+
534543 res <- initial
535544 case res of
536545 PRD.IPartial s -> go SPEC state (List []) s
@@ -608,25 +617,36 @@ parseD (PRD.Parser pstep initial extract) stream@(D.Stream step state) = do
608617--
609618-- /Internal/
610619--
611−{-# INLINE_NORMAL parse #-}
612−parse ::
620+{-# INLINE_NORMAL parseBreak #-}
621+parseBreak ::
613622 (MonadIO m, MonadThrow m, Storable a)
614623 => PR.Parser m a b
615624 -> SerialT m (A.Array a)
616625 -> m (b, SerialT m (A.Array a))
617−parse p s = fmap fromStreamD <$> parseD (PRD.fromParserK p) (toStreamD s)
626+parseBreak p s =
627+ fmap fromStreamD <$> parseBreakD (PRD.fromParserK p) (toStreamD s)
618628
619629-------------------------------------------------------------------------------
620630-- Elimination - Running Array Folds and parsers
621631-------------------------------------------------------------------------------
622632
623−{-# INLINE_NORMAL parseArrD #-}
624−parseArrD ::
633+-- | Note that this is not the same as using a @Parser m (Array a) b@ with the
634+-- regular "Streamly.Internal.Data.IsStream.parse" function. The regular parse
635+-- would consume the input arrays as single unit. This parser parses in the way
636+-- as described in the ArrayFold module. The input arrays are treated as @n@
637+-- element units and can be consumed partially. The remaining elements are
638+-- inserted in the source stream as an array.
639+--
640+{-# INLINE_NORMAL runArrayParserDBreak #-}
641+runArrayParserDBreak ::
625642 forall m a b. (MonadIO m, MonadThrow m, Storable a)
626643 => PRD.Parser m (Array a) b
627644 -> D.Stream m (Array.Array a)
628645 -> m (b, D.Stream m (Array.Array a))
629−parseArrD (PRD.Parser pstep initial extract) stream@(D.Stream step state) = do
646+runArrayParserDBreak
647+ (PRD.Parser pstep initial extract)
648+ stream@(D.Stream step state) = do
649+
630650 res <- initial
631651 case res of
632652 PRD.IPartial s -> go SPEC state (List []) s
@@ -695,26 +715,27 @@ parseArr ::
695715 => ASF.Parser m a b
696716 -> SerialT m (A.Array a)
697717 -> m (b, SerialT m (A.Array a))
698−parseArr p s = fmap fromStreamD <$> parseD p (toStreamD s)
718+parseArr p s = fmap fromStreamD <$> parseBreakD p (toStreamD s)
699719-}
700720
701721-- | Fold an array stream using the supplied array stream 'Fold'.
702722--
703723-- /Pre-release/
704724--
705−{-# INLINE foldArr #-}
706−foldArr :: (MonadIO m, MonadThrow m, Storable a) =>
725+{-# INLINE runArrayFold #-}
726+runArrayFold :: (MonadIO m, MonadThrow m, Storable a) =>
707727 ArrayFold m a b -> SerialT m (A.Array a) -> m b
708−foldArr (ArrayFold p) s = fst <$> parseArrD p (toStreamD s)
728+runArrayFold (ArrayFold p) s = fst <$> runArrayParserDBreak p (toStreamD s)
709729
710730-- | Like 'fold' but also returns the remaining stream.
711731--
712732-- /Pre-release/
713733--
714−{-# INLINE foldArr_ #-}
715−foldArr_ :: (MonadIO m, MonadThrow m, Storable a) =>
734+{-# INLINE runArrayFoldBreak #-}
735+runArrayFoldBreak :: (MonadIO m, MonadThrow m, Storable a) =>
716736 ArrayFold m a b -> SerialT m (A.Array a) -> m (b, SerialT m (A.Array a))
717−foldArr_ (ArrayFold p) s = second fromStreamD <$> parseArrD p (toStreamD s)
737+runArrayFoldBreak (ArrayFold p) s =
738+ second fromStreamD <$> runArrayParserDBreak p (toStreamD s)
718739
719740{-# ANN type ParseChunksState Fuse #-}
720741data ParseChunksState x inpBuf st pst =
@@ -724,13 +745,15 @@ data ParseChunksState x inpBuf st pst =
724745 | ParseChunksBuf inpBuf st inpBuf !pst
725746 | ParseChunksYield x (ParseChunksState x inpBuf st pst)
726747
727−{-# INLINE_NORMAL foldArrManyD #-}
728−foldArrManyD
748+{-# INLINE_NORMAL runArrayFoldManyD #-}
749+runArrayFoldManyD
729750 :: (MonadThrow m, Storable a)
730751 => ArrayFold m a b
731752 -> D.Stream m (Array a)
732753 -> D.Stream m b
733−foldArrManyD (ArrayFold (PRD.Parser pstep initial extract)) (D.Stream step state) =
754+runArrayFoldManyD
755+ (ArrayFold (PRD.Parser pstep initial extract)) (D.Stream step state) =
756+
734757 D.Stream stepOuter (ParseChunksInit [] state)
735758
736759 where
@@ -844,16 +867,16 @@ foldArrManyD (ArrayFold (PRD.Parser pstep initial extract)) (D.Stream step state
844867
845868 stepOuter _ (ParseChunksYield a next) = return $ D.Yield a next
846869
847−-- | Apply an array stream 'Fold' repeatedly on an array stream and emit the
870+-- | Apply an 'ArrayFold' repeatedly on an array stream and emit the
848871-- fold outputs in the output stream.
849872--
850873-- See "Streamly.Prelude.foldMany" for more details.
851874--
852875-- /Pre-release/
853−{-# INLINE foldArrMany #-}
854−foldArrMany
876+{-# INLINE runArrayFoldMany #-}
877+runArrayFoldMany
855878 :: (IsStream t, MonadThrow m, Storable a)
856879 => ArrayFold m a b
857880 -> t m (Array a)
858881 -> t m b
859−foldArrMany p m = fromStreamD $ foldArrManyD p (toStreamD m)
882+runArrayFoldMany p m = fromStreamD $ runArrayFoldManyD p (toStreamD m)