on master help sign in
Deprecate MutArray/Stream module, move funcs to MutArray module

Move the mut array compaction funcs from MutArray.Stream to MutArray module.

commit2417874bed53d5f599070367a46427eb97f9a50c authorHarendra Kumar <harendra@composewell.com> dateSun 31 Dec 2023, 10:33 (3 years ago) parent0137a71
3 files changed+292−200
core/src/Streamly/Internal/Data/MutArray.hs+13 core/src/Streamly/Internal/Data/MutArray/Stream.hs+11−195 core/src/Streamly/Internal/Data/MutArray/Type.hs+268−5
core/src/Streamly/Internal/Data/MutArray.hs+13
@@ -13,6 +13,7 @@ module Streamly.Internal.Data.MutArray
1313 -- * MutArray module
1414 , sliceIndexerFromLen
1515 , slicerFromLen
16+ , compactChunksLE
1617 -- * Unboxed IORef
1718 , module Streamly.Internal.Data.IORef.Unboxed
1819
@@ -24,9 +25,13 @@ where
2425
2526#include "inline.hs"
2627
28+import Control.Monad.IO.Class (MonadIO(..))
29+import Streamly.Internal.Data.Stream.Type (Stream)
2730import Streamly.Internal.Data.Unbox (Unbox)
2831import Streamly.Internal.Data.Unfold.Type (Unfold(..))
2932
33+-- import qualified Streamly.Internal.Data.Stream.Nesting as Stream
34+-- import qualified Streamly.Internal.Data.Stream.Transform as Stream
3035import qualified Streamly.Internal.Data.Unfold as Unfold
3136
3237import Prelude hiding (foldr, length, read, splitAt)
@@ -77,3 +82,11 @@ getSlicesFromLen :: forall m a. (Monad m, Unbox a)
7782 -> Int -- ^ length of the slice
7883 -> Unfold m (MutArray a) (MutArray a)
7984getSlicesFromLen = slicerFromLen
85+
86+-- | Scan @compactChunksLE n@ coalesces adjacent arrays in the input stream
87+-- only if the combined size would be less than or equal to n.
88+{-# INLINE compactChunksLE #-}
89+compactChunksLE :: (MonadIO m, Unbox a) =>
90+ Int -> Stream m (MutArray a) -> Stream m (MutArray a)
91+-- compactLE n = Stream.catRights . Stream.parseManyD (pCompactChunksLE n)
92+compactChunksLE = rCompactChunksLE
core/src/Streamly/Internal/Data/MutArray/Stream.hs+11−195
@@ -12,6 +12,7 @@
1212-- keep this as a separate module and release it.
1313--
1414module Streamly.Internal.Data.MutArray.Stream
15+{-# DEPRECATED "Please use \"Streamly.Internal.Data.MutArray\" instead." #-}
1516 (
1617 -- * Generation
1718 MArray.chunksOf
@@ -21,7 +22,7 @@ module Streamly.Internal.Data.MutArray.Stream
2122
2223 -- * Compaction
2324 , packArraysChunksOf
24− , SpliceState (..)
25+ , MArray.SpliceState (..)
2526 , lpackArraysChunksOf
2627 , compact -- chunksCompact
2728 , compactLE
@@ -35,19 +36,12 @@ module Streamly.Internal.Data.MutArray.Stream
3536 )
3637where
3738
38−#include "inline.hs"
39−#include "ArrayMacros.h"
40−
4139import Control.Monad.IO.Class (MonadIO(..))
42−import Control.Monad (when)
43−import Data.Bifunctor (first)
44−import Data.Proxy (Proxy(..))
45−import Streamly.Internal.Data.Unbox (Unbox, sizeOf)
40+import Streamly.Internal.Data.Unbox (Unbox)
4641import Streamly.Internal.Data.MutArray.Type (MutArray(..))
4742import Streamly.Internal.Data.Fold.Type (Fold(..))
4843import Streamly.Internal.Data.Parser (ParseError)
4944import Streamly.Internal.Data.Stream.Type (Stream)
50−import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
5145
5246import qualified Streamly.Internal.Data.MutArray as MArray
5347import qualified Streamly.Internal.Data.Fold.Type as FL
@@ -58,12 +52,6 @@ import qualified Streamly.Internal.Data.Stream as D
5852-- Compact
5953-------------------------------------------------------------------------------
6054
61−data SpliceState s arr
62− = SpliceInitial s
63− | SpliceBuffering s arr
64− | SpliceYielding arr (SpliceState s arr)
65− | SpliceFinish
66−
6755-- XXX This can be removed once compactLEFold/compactLE are implemented.
6856--
6957-- | This mutates the first array (if it has space) to append values from the
@@ -78,117 +66,18 @@ data SpliceState s arr
7866-- actual array size may be less than the specified chunk size.
7967--
8068-- @since 0.7.0
81−{-# INLINE_NORMAL packArraysChunksOf #-}
69+{-# INLINE packArraysChunksOf #-}
8270packArraysChunksOf :: (MonadIO m, Unbox a)
8371 => Int -> D.Stream m (MutArray a) -> D.Stream m (MutArray a)
84−packArraysChunksOf n (D.Stream step state) =
85− D.Stream step' (SpliceInitial state)
86−
87− where
88−
89− {-# INLINE_LATE step' #-}
90− step' gst (SpliceInitial st) = do
91− when (n <= 0) $
92− -- XXX we can pass the module string from the higher level API
93− error $ "Streamly.Internal.Data.MutArray.Type.packArraysChunksOf: the size of "
94− ++ "arrays [" ++ show n ++ "] must be a natural number"
95− r <- step gst st
96− case r of
97− D.Yield arr s -> return $
98− let len = MArray.byteLength arr
99− in if len >= n
100− then D.Skip (SpliceYielding arr (SpliceInitial s))
101− else D.Skip (SpliceBuffering s arr)
102− D.Skip s -> return $ D.Skip (SpliceInitial s)
103− D.Stop -> return D.Stop
104−
105− step' gst (SpliceBuffering st buf) = do
106− r <- step gst st
107− case r of
108− D.Yield arr s -> do
109− let len = MArray.byteLength buf + MArray.byteLength arr
110− if len > n
111− then return $
112− D.Skip (SpliceYielding buf (SpliceBuffering s arr))
113− else do
114− buf' <- if MArray.byteCapacity buf < n
115− then liftIO $ MArray.realloc n buf
116− else return buf
117− buf'' <- MArray.spliceUnsafe buf' arr
118− return $ D.Skip (SpliceBuffering s buf'')
119− D.Skip s -> return $ D.Skip (SpliceBuffering s buf)
120− D.Stop -> return $ D.Skip (SpliceYielding buf SpliceFinish)
121−
122− step' _ SpliceFinish = return D.Stop
123−
124− step' _ (SpliceYielding arr next) = return $ D.Yield arr next
72+packArraysChunksOf = MArray.compactChunksLE
12573
12674-- XXX Remove this once compactLEFold is implemented
12775-- lpackArraysChunksOf = Fold.many compactLEFold
12876--
129−{-# INLINE_NORMAL lpackArraysChunksOf #-}
77+{-# INLINE lpackArraysChunksOf #-}
13078lpackArraysChunksOf :: (MonadIO m, Unbox a)
13179 => Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
132−lpackArraysChunksOf n (Fold step1 initial1 _ final1) =
133− Fold step initial extract final
134−
135− where
136−
137− initial = do
138− when (n <= 0) $
139− -- XXX we can pass the module string from the higher level API
140− error $ "Streamly.Internal.Data.MutArray.Type.packArraysChunksOf: the size of "
141− ++ "arrays [" ++ show n ++ "] must be a natural number"
142−
143− r <- initial1
144− return $ first (Tuple' Nothing) r
145−
146− step (Tuple' Nothing r1) arr =
147− let len = MArray.byteLength arr
148− in if len >= n
149− then do
150− r <- step1 r1 arr
151− case r of
152− FL.Done _ -> return $ FL.Done ()
153− FL.Partial s -> do
154− _ <- final1 s
155− res <- initial1
156− return $ first (Tuple' Nothing) res
157− else return $ FL.Partial $ Tuple' (Just arr) r1
158−
159− step (Tuple' (Just buf) r1) arr = do
160− let len = MArray.byteLength buf + MArray.byteLength arr
161− buf' <- if MArray.byteCapacity buf < len
162− then liftIO $ MArray.realloc (max n len) buf
163− else return buf
164− buf'' <- MArray.spliceUnsafe buf' arr
165−
166− -- XXX this is common in both the equations of step
167− if len >= n
168− then do
169− r <- step1 r1 buf''
170− case r of
171− FL.Done _ -> return $ FL.Done ()
172− FL.Partial s -> do
173− _ <- final1 s
174− res <- initial1
175− return $ first (Tuple' Nothing) res
176− else return $ FL.Partial $ Tuple' (Just buf'') r1
177−
178− -- XXX Several folds do extract >=> final, therefore, we need to make final
179− -- return "m b" rather than using extract post it if we want extract to be
180− -- partial.
181− --
182− -- extract forces the pending buffer to be sent to the fold which is not
183− -- what we want.
184− extract _ = error "lpackArraysChunksOf: not designed for scanning"
185−
186− final (Tuple' Nothing r1) = final1 r1
187− final (Tuple' (Just buf) r1) = do
188− r <- step1 r1 buf
189− case r of
190− FL.Partial rr -> final1 rr
191− FL.Done _ -> return ()
80+lpackArraysChunksOf = MArray.lCompactChunksGE
19281
19382-- XXX Same as compactLE, to be removed once that is implemented.
19483--
@@ -208,48 +97,11 @@ compact = packArraysChunksOf
20897-- actual array size may be less than the specified chunk size.
20998--
21099-- /Internal/
211−{-# INLINE_NORMAL compactLEParserD #-}
100+{-# INLINE compactLEParserD #-}
212101compactLEParserD ::
213102 forall m a. (MonadIO m, Unbox a)
214103 => Int -> ParserD.Parser (MutArray a) m (MutArray a)
215−compactLEParserD n = ParserD.Parser step initial extract
216−
217− where
218−
219− nBytes = n * SIZE_OF(a)
220−
221− initial =
222− return
223− $ if n <= 0
224− then error
225− $ functionPath
226− ++ ": the size of arrays ["
227− ++ show n ++ "] must be a natural number"
228− else ParserD.IPartial Nothing
229−
230− step Nothing arr =
231− return
232− $ let len = MArray.byteLength arr
233− in if len >= nBytes
234− then ParserD.Done 0 arr
235− else ParserD.Partial 0 (Just arr)
236− step (Just buf) arr =
237− let len = MArray.byteLength buf + MArray.byteLength arr
238− in if len > nBytes
239− then return $ ParserD.Done 1 buf
240− else do
241− buf1 <-
242− if MArray.byteCapacity buf < nBytes
243− then liftIO $ MArray.realloc nBytes buf
244− else return buf
245− buf2 <- MArray.spliceUnsafe buf1 arr
246− return $ ParserD.Partial 0 (Just buf2)
247−
248− extract Nothing = return $ ParserD.Done 0 MArray.nil
249− extract (Just buf) = return $ ParserD.Done 0 buf
250−
251− functionPath =
252− "Streamly.Internal.Data.Stream.MutChunked.compactLEParserD"
104+compactLEParserD = MArray.pCompactChunksLE
253105
254106-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
255107-- minimum specified size. Note that if all the arrays in the stream together
@@ -258,47 +110,11 @@ compactLEParserD n = ParserD.Parser step initial extract
258110-- the specified size we stop coalescing further.
259111--
260112-- /Internal/
261−{-# INLINE_NORMAL compactGEFold #-}
113+{-# INLINE compactGEFold #-}
262114compactGEFold ::
263115 forall m a. (MonadIO m, Unbox a)
264116 => Int -> FL.Fold m (MutArray a) (MutArray a)
265−compactGEFold n = Fold step initial extract extract
266−
267− where
268−
269− nBytes = n * SIZE_OF(a)
270−
271− initial =
272− return
273− $ if n < 0
274− then error
275− $ functionPath
276− ++ ": the size of arrays ["
277− ++ show n ++ "] must be a natural number"
278− else FL.Partial Nothing
279−
280− step Nothing arr =
281− return
282− $ let len = MArray.byteLength arr
283− in if len >= nBytes
284− then FL.Done arr
285− else FL.Partial (Just arr)
286− step (Just buf) arr = do
287− let len = MArray.byteLength buf + MArray.byteLength arr
288− buf1 <-
289− if MArray.byteCapacity buf < len
290− then liftIO $ MArray.realloc (max len nBytes) buf
291− else return buf
292− buf2 <- MArray.spliceUnsafe buf1 arr
293− if len >= n
294− then return $ FL.Done buf2
295− else return $ FL.Partial (Just buf2)
296−
297− extract Nothing = return MArray.nil
298− extract (Just buf) = return buf
299−
300− functionPath =
301− "Streamly.Internal.Data.Stream.MutChunked.compactGEFold"
117+compactGEFold = MArray.fCompactChunksGE
302118
303119-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
304120-- maximum specified size in bytes.
core/src/Streamly/Internal/Data/MutArray/Type.hs+268−5
@@ -216,15 +216,24 @@ module Streamly.Internal.Data.MutArray.Type
216216 , pinnedChunksOf
217217 , buildChunks
218218
219− -- *** Flatten a stream of arrays
220− , concatChunks
221− , concatChunksRev
222−
223219 -- *** Split an array into slices
224220 -- , getSlicesFromLenN
225221 , splitOn
226222 -- , slicesOf
227223
224+ -- *** Flatten a stream of arrays
225+ , concatChunks
226+ , concatChunksRev
227+
228+ -- *** Compaction
229+ , SpliceState (..)
230+ , pCompactChunksLE
231+ , rCompactChunksLE
232+ , fCompactChunksGE
233+ , lCompactChunksGE
234+ , compactChunksGE
235+ , compactChunksEQ
236+
228237 -- ** Utilities
229238 , roundUpToPower2
230239 , memcpy
@@ -248,6 +257,7 @@ where
248257
249258import Control.Monad (when, void)
250259import Control.Monad.IO.Class (MonadIO(..))
260+import Data.Bifunctor (first)
251261import Data.Bits (shiftR, (.|.), (.&.))
252262import Data.Functor.Identity (Identity(..))
253263import Data.Proxy (Proxy(..))
@@ -274,13 +284,17 @@ import GHC.Ptr (Ptr(..))
274284import Streamly.Internal.Data.Fold.Type (Fold(..))
275285import Streamly.Internal.Data.Producer.Type (Producer (..))
276286import Streamly.Internal.Data.Stream.Type (Stream)
287+import Streamly.Internal.Data.Parser.Type (Parser (..))
277288import Streamly.Internal.Data.StreamK.Type (StreamK)
278289import Streamly.Internal.Data.SVar.Type (adaptState, defState)
290+import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
279291import Streamly.Internal.Data.Unfold.Type (Unfold(..))
280292import Streamly.Internal.System.IO (arrayPayloadSize, defaultChunkSize)
281293
282294import qualified Streamly.Internal.Data.Fold.Type as FL
283295import qualified Streamly.Internal.Data.MutByteArray.Type as Unboxed
296+import qualified Streamly.Internal.Data.Parser.Type as Parser
297+-- import qualified Streamly.Internal.Data.Fold.Type as Fold
284298import qualified Streamly.Internal.Data.Producer as Producer
285299import qualified Streamly.Internal.Data.Stream.Type as D
286300import qualified Streamly.Internal.Data.Stream.Lift as D
@@ -2582,7 +2596,256 @@ byteEq :: MonadIO m => MutArray a -> MutArray a -> m Bool
25822596byteEq arr1 arr2 = fmap (EQ ==) $ byteCmp arr1 arr2
25832597
25842598-------------------------------------------------------------------------------
2585−-- NFData
2599+-- Compact
2600+-------------------------------------------------------------------------------
2601+
2602+-- | Parser @pCompactChunksLE n@ coalesces adjacent arrays in the input stream
2603+-- only if the combined size would be less than or equal to n.
2604+--
2605+-- /Internal/
2606+{-# INLINE_NORMAL pCompactChunksLE #-}
2607+pCompactChunksLE ::
2608+ forall m a. (MonadIO m, Unbox a)
2609+ => Int -> Parser (MutArray a) m (MutArray a)
2610+pCompactChunksLE n = Parser step initial extract
2611+
2612+ where
2613+
2614+ nBytes = n * SIZE_OF(a)
2615+
2616+ functionName = "Streamly.Internal.Data.MutArray.pCompactChunksLE"
2617+
2618+ initial =
2619+ return
2620+ $ if n <= 0
2621+ then error
2622+ $ functionName
2623+ ++ ": the size of arrays ["
2624+ ++ show n ++ "] must be a natural number"
2625+ else Parser.IPartial Nothing
2626+
2627+ step Nothing arr =
2628+ return
2629+ $ let len = byteLength arr
2630+ in if len >= nBytes
2631+ then Parser.Done 0 arr
2632+ else Parser.Partial 0 (Just arr)
2633+ step (Just buf) arr =
2634+ let len = byteLength buf + byteLength arr
2635+ in if len > nBytes
2636+ then return $ Parser.Done 1 buf
2637+ else do
2638+ -- XXX check this in the Nothing case
2639+ buf1 <-
2640+ if byteCapacity buf < nBytes
2641+ then liftIO $ realloc nBytes buf
2642+ else return buf
2643+ buf2 <- spliceUnsafe buf1 arr
2644+ return $ Parser.Partial 0 (Just buf2)
2645+
2646+ extract Nothing = return $ Parser.Done 0 nil
2647+ extract (Just buf) = return $ Parser.Done 0 buf
2648+
2649+data SpliceState s arr
2650+ = SpliceInitial s
2651+ | SpliceBuffering s arr
2652+ | SpliceYielding arr (SpliceState s arr)
2653+ | SpliceFinish
2654+
2655+-- This mutates the first array (if it has space) to append values from the
2656+-- second one. This would work for immutable arrays as well because an
2657+-- immutable array never has additional space so a new array is allocated
2658+-- instead of mutating it.
2659+
2660+-- | Scan @rCompactChunksLE n@ coalesces adjacent arrays in the input stream
2661+-- only if the combined size would be less than or equal to n.
2662+--
2663+-- /Internal/
2664+{-# INLINE_NORMAL rCompactChunksLE #-}
2665+rCompactChunksLE :: (MonadIO m, Unbox a)
2666+ => Int -> D.Stream m (MutArray a) -> D.Stream m (MutArray a)
2667+rCompactChunksLE n (D.Stream step state) =
2668+ D.Stream step' (SpliceInitial state)
2669+
2670+ where
2671+
2672+ functionName = "Streamly.Internal.Data.MutArray.rCompactChunksLE"
2673+
2674+ {-# INLINE_LATE step' #-}
2675+ step' gst (SpliceInitial st) = do
2676+ when (n <= 0) $
2677+ -- XXX we can pass the module string from the higher level API
2678+ error $ functionName ++ ": the size of arrays [" ++ show n
2679+ ++ "] must be a natural number"
2680+ r <- step gst st
2681+ case r of
2682+ D.Yield arr s -> return $
2683+ let len = byteLength arr
2684+ in if len >= n
2685+ then D.Skip (SpliceYielding arr (SpliceInitial s))
2686+ else D.Skip (SpliceBuffering s arr)
2687+ D.Skip s -> return $ D.Skip (SpliceInitial s)
2688+ D.Stop -> return D.Stop
2689+
2690+ step' gst (SpliceBuffering st buf) = do
2691+ r <- step gst st
2692+ case r of
2693+ D.Yield arr s -> do
2694+ let len = byteLength buf + byteLength arr
2695+ if len > n
2696+ then return $
2697+ D.Skip (SpliceYielding buf (SpliceBuffering s arr))
2698+ else do
2699+ -- XXX check this in the SpliceInitial case
2700+ buf1 <- if byteCapacity buf < n
2701+ then liftIO $ realloc n buf
2702+ else return buf
2703+ buf2 <- spliceUnsafe buf1 arr
2704+ return $ D.Skip (SpliceBuffering s buf2)
2705+ D.Skip s -> return $ D.Skip (SpliceBuffering s buf)
2706+ D.Stop -> return $ D.Skip (SpliceYielding buf SpliceFinish)
2707+
2708+ step' _ SpliceFinish = return D.Stop
2709+
2710+ step' _ (SpliceYielding arr next) = return $ D.Yield arr next
2711+
2712+-- | Fold @fCompactChunksGE n@ coalesces adjacent arrays in the input stream
2713+-- until the size becomes greater than or equal to n.
2714+--
2715+{-# INLINE_NORMAL fCompactChunksGE #-}
2716+fCompactChunksGE ::
2717+ forall m a. (MonadIO m, Unbox a)
2718+ => Int -> FL.Fold m (MutArray a) (MutArray a)
2719+fCompactChunksGE n = Fold step initial extract extract
2720+
2721+ where
2722+
2723+ nBytes = n * SIZE_OF(a)
2724+
2725+ functionName = "Streamly.Internal.Data.MutArray.fCompactChunksGE"
2726+
2727+ initial =
2728+ return
2729+ $ if n < 0
2730+ then error
2731+ $ functionName
2732+ ++ ": the size of arrays ["
2733+ ++ show n ++ "] must be a natural number"
2734+ else FL.Partial Nothing
2735+
2736+ step Nothing arr =
2737+ return
2738+ $ let len = byteLength arr
2739+ in if len >= nBytes
2740+ then FL.Done arr
2741+ else FL.Partial (Just arr)
2742+ step (Just buf) arr = do
2743+ let len = byteLength buf + byteLength arr
2744+ buf1 <-
2745+ if byteCapacity buf < len
2746+ then liftIO $ realloc (max len nBytes) buf
2747+ else return buf
2748+ buf2 <- spliceUnsafe buf1 arr
2749+ if len >= n
2750+ then return $ FL.Done buf2
2751+ else return $ FL.Partial (Just buf2)
2752+
2753+ extract Nothing = return nil
2754+ extract (Just buf) = return buf
2755+
2756+-- | Like 'compactChunksGE' but for transforming folds instead of stream.
2757+--
2758+-- >>> lCompactChunksGE n = Fold.many (MutArray.fCompactChunksGE n)
2759+--
2760+{-# INLINE_NORMAL lCompactChunksGE #-}
2761+lCompactChunksGE :: (MonadIO m, Unbox a)
2762+ => Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
2763+-- lCompactChunksGE n = Fold.many (fCompactChunksGE n)
2764+lCompactChunksGE n (Fold step1 initial1 _ final1) =
2765+ Fold step initial extract final
2766+
2767+ where
2768+
2769+ functionName = "Streamly.Internal.Data.MutArray.lCompactChunksGE"
2770+
2771+ initial = do
2772+ when (n <= 0) $
2773+ -- XXX we can pass the module string from the higher level API
2774+ error $ functionName ++ ": the size of arrays ["
2775+ ++ show n ++ "] must be a natural number"
2776+
2777+ r <- initial1
2778+ return $ first (Tuple' Nothing) r
2779+
2780+ step (Tuple' Nothing r1) arr =
2781+ let len = byteLength arr
2782+ in if len >= n
2783+ then do
2784+ r <- step1 r1 arr
2785+ case r of
2786+ FL.Done _ -> return $ FL.Done ()
2787+ FL.Partial s -> do
2788+ _ <- final1 s
2789+ res <- initial1
2790+ return $ first (Tuple' Nothing) res
2791+ else return $ FL.Partial $ Tuple' (Just arr) r1
2792+
2793+ step (Tuple' (Just buf) r1) arr = do
2794+ let len = byteLength buf + byteLength arr
2795+ buf1 <- if byteCapacity buf < len
2796+ then liftIO $ realloc (max n len) buf
2797+ else return buf
2798+ buf2 <- spliceUnsafe buf1 arr
2799+
2800+ -- XXX this is common in both the equations of step
2801+ if len >= n
2802+ then do
2803+ r <- step1 r1 buf2
2804+ case r of
2805+ FL.Done _ -> return $ FL.Done ()
2806+ FL.Partial s -> do
2807+ _ <- final1 s
2808+ res <- initial1
2809+ return $ first (Tuple' Nothing) res
2810+ else return $ FL.Partial $ Tuple' (Just buf2) r1
2811+
2812+ -- XXX Several folds do extract >=> final, therefore, we need to make final
2813+ -- return "m b" rather than using extract post it if we want extract to be
2814+ -- partial.
2815+ --
2816+ -- extract forces the pending buffer to be sent to the fold which is not
2817+ -- what we want.
2818+ extract _ = error "lCompactChunksGE: not designed for scanning"
2819+
2820+ final (Tuple' Nothing r1) = final1 r1
2821+ final (Tuple' (Just buf) r1) = do
2822+ r <- step1 r1 buf
2823+ case r of
2824+ FL.Partial rr -> final1 rr
2825+ FL.Done _ -> return ()
2826+
2827+-- | @compactChunksGE n stream@ coalesces adjacent arrays in the @stream@ until
2828+-- the size becomes greater than or equal to @n@.
2829+--
2830+-- >>> compactChunksGE n = Stream.foldMany (MutArray.fCompactChunksGE n)
2831+--
2832+{-# INLINE compactChunksGE #-}
2833+compactChunksGE ::
2834+ (MonadIO m, Unbox a)
2835+ => Int -> Stream m (MutArray a) -> Stream m (MutArray a)
2836+compactChunksGE n = D.foldMany (fCompactChunksGE n)
2837+
2838+-- | 'compactChunksEQ n' coalesces adajacent arrays in the input stream to
2839+-- arrays of exact size @n@.
2840+--
2841+-- /Unimplemented/
2842+{-# INLINE compactChunksEQ #-}
2843+compactChunksEQ :: -- (MonadIO m, Unbox a) =>
2844+ Int -> Stream m (MutArray a) -> Stream m (MutArray a)
2845+compactChunksEQ _n = undefined -- D.parseManyD (pCompactChunksEQ n)
2846+
2847+-------------------------------------------------------------------------------
2848+-- In-place mutation algorithms
25862849-------------------------------------------------------------------------------
25872850
25882851-- | Strip elements which match with predicate from both ends.