-- |
-- Module      : Streamly.Internal.Data.MutArray.Stream
-- Copyright   : (c) 2019 Composewell Technologies
-- License     : BSD3-3-Clause
-- Maintainer  : streamly@composewell.com
-- Stability   : experimental
-- Portability : GHC
--
-- Combinators to efficiently manipulate streams of mutable arrays.
--
-- We can either push these in the MutArray module with a "chunks" prefix or
-- keep this as a separate module and release it.
--
module Streamly.Internal.Data.MutArray.Stream
    (
    -- * Generation
      MArray.chunksOf
    , MArray.pinnedChunksOf
    , MArray.writeChunks -- chunksWrite?
    , MArray.splitOn -- chunksSplitOn

    -- * Compaction
    , packArraysChunksOf
    , SpliceState (..)
    , lpackArraysChunksOf
    , compact -- chunksCompact
    , compactLE
    , compactEQ
    , compactGE

    -- * Elimination
    , MArray.flattenArrays -- chunksConcat
    , MArray.flattenArraysRev -- chunksConcatRev
    , MArray.fromArrayStreamK -- chunksCoalesce
    )
where

#include "inline.hs"
#include "ArrayMacros.h"

import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad (when)
import Data.Bifunctor (first)
import Data.Proxy (Proxy(..))
import Streamly.Internal.Data.Unbox (Unbox, sizeOf)
import Streamly.Internal.Data.MutArray.Type (MutArray(..))
import Streamly.Internal.Data.Fold.Type (Fold(..))
import Streamly.Internal.Data.Parser (ParseError)
import Streamly.Internal.Data.Stream.Type (Stream)
import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))

import qualified Streamly.Internal.Data.MutArray as MArray
import qualified Streamly.Internal.Data.Fold.Type as FL
import qualified Streamly.Internal.Data.Parser as ParserD
import qualified Streamly.Internal.Data.Stream as D

-------------------------------------------------------------------------------
-- Compact
-------------------------------------------------------------------------------

data SpliceState s arr
    = SpliceInitial s
    | SpliceBuffering s arr
    | SpliceYielding arr (SpliceState s arr)
    | SpliceFinish

-- XXX This can be removed once compactLEFold/compactLE are implemented.
--
-- | This mutates the first array (if it has space) to append values from the
-- second one. This would work for immutable arrays as well because an
-- immutable array never has space so a new array is allocated instead of
-- mutating it.
--
-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
-- maximum specified size. Note that if a single array is bigger than the
-- specified size we do not split it to fit. When we coalesce multiple arrays
-- if the size would exceed the specified size we do not coalesce therefore the
-- actual array size may be less than the specified chunk size.
--
-- @since 0.7.0
{-# INLINE_NORMAL packArraysChunksOf #-}
packArraysChunksOf :: (MonadIO m, Unbox a)
    => Int -> D.Stream m (MutArray a) -> D.Stream m (MutArray a)
packArraysChunksOf :: forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Stream m (MutArray a) -> Stream m (MutArray a)
packArraysChunksOf Int
n (D.Stream State StreamK m (MutArray a) -> s -> m (Step s (MutArray a))
step s
state) =
    forall (m :: * -> *) a s.
(State StreamK m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State StreamK m (MutArray a)
-> SpliceState s (MutArray a)
-> m (Step (SpliceState s (MutArray a)) (MutArray a))
step' (forall s arr. s -> SpliceState s arr
SpliceInitial s
state)

    where

    {-# INLINE_LATE step' #-}
    step' :: State StreamK m (MutArray a)
-> SpliceState s (MutArray a)
-> m (Step (SpliceState s (MutArray a)) (MutArray a))
step' State StreamK m (MutArray a)
gst (SpliceInitial s
st) = do
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n forall a. Ord a => a -> a -> Bool
<= Int
0) forall a b. (a -> b) -> a -> b
$
            -- XXX we can pass the module string from the higher level API
            forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Streamly.Internal.Data.MutArray.Type.packArraysChunksOf: the size of "
                 forall a. [a] -> [a] -> [a]
++ [Char]
"arrays [" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n forall a. [a] -> [a] -> [a]
++ [Char]
"] must be a natural number"
        Step s (MutArray a)
r <- State StreamK m (MutArray a) -> s -> m (Step s (MutArray a))
step State StreamK m (MutArray a)
gst s
st
        case Step s (MutArray a)
r of
            D.Yield MutArray a
arr s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
                let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
                 in if Int
len forall a. Ord a => a -> a -> Bool
>= Int
n
                    then forall s a. s -> Step s a
D.Skip (forall s arr. arr -> SpliceState s arr -> SpliceState s arr
SpliceYielding MutArray a
arr (forall s arr. s -> SpliceState s arr
SpliceInitial s
s))
                    else forall s a. s -> Step s a
D.Skip (forall s arr. s -> arr -> SpliceState s arr
SpliceBuffering s
s MutArray a
arr)
            D.Skip s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. s -> Step s a
D.Skip (forall s arr. s -> SpliceState s arr
SpliceInitial s
s)
            Step s (MutArray a)
D.Stop -> forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
D.Stop

    step' State StreamK m (MutArray a)
gst (SpliceBuffering s
st MutArray a
buf) = do
        Step s (MutArray a)
r <- State StreamK m (MutArray a) -> s -> m (Step s (MutArray a))
step State StreamK m (MutArray a)
gst s
st
        case Step s (MutArray a)
r of
            D.Yield MutArray a
arr s
s -> do
                let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
buf forall a. Num a => a -> a -> a
+ forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
                if Int
len forall a. Ord a => a -> a -> Bool
> Int
n
                then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
                    forall s a. s -> Step s a
D.Skip (forall s arr. arr -> SpliceState s arr -> SpliceState s arr
SpliceYielding MutArray a
buf (forall s arr. s -> arr -> SpliceState s arr
SpliceBuffering s
s MutArray a
arr))
                else do
                    MutArray a
buf' <- if forall a. MutArray a -> Int
MArray.byteCapacity MutArray a
buf forall a. Ord a => a -> a -> Bool
< Int
n
                            then forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> MutArray a -> m (MutArray a)
MArray.realloc Int
n MutArray a
buf
                            else forall (m :: * -> *) a. Monad m => a -> m a
return MutArray a
buf
                    MutArray a
buf'' <- forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
MutArray a -> MutArray a -> m (MutArray a)
MArray.splice MutArray a
buf' MutArray a
arr
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. s -> Step s a
D.Skip (forall s arr. s -> arr -> SpliceState s arr
SpliceBuffering s
s MutArray a
buf'')
            D.Skip s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. s -> Step s a
D.Skip (forall s arr. s -> arr -> SpliceState s arr
SpliceBuffering s
s MutArray a
buf)
            Step s (MutArray a)
D.Stop -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. s -> Step s a
D.Skip (forall s arr. arr -> SpliceState s arr -> SpliceState s arr
SpliceYielding MutArray a
buf forall s arr. SpliceState s arr
SpliceFinish)

    step' State StreamK m (MutArray a)
_ SpliceState s (MutArray a)
SpliceFinish = forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
D.Stop

    step' State StreamK m (MutArray a)
_ (SpliceYielding MutArray a
arr SpliceState s (MutArray a)
next) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. a -> s -> Step s a
D.Yield MutArray a
arr SpliceState s (MutArray a)
next

-- XXX Remove this once compactLEFold is implemented
-- lpackArraysChunksOf = Fold.many compactLEFold
--
{-# INLINE_NORMAL lpackArraysChunksOf #-}
lpackArraysChunksOf :: (MonadIO m, Unbox a)
    => Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
lpackArraysChunksOf :: forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
lpackArraysChunksOf Int
n (Fold s -> MutArray a -> m (Step s ())
step1 m (Step s ())
initial1 s -> m ()
_ s -> m ()
final1) =
    forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> (s -> m b) -> Fold m a b
Fold Tuple' (Maybe (MutArray a)) s
-> MutArray a -> m (Step (Tuple' (Maybe (MutArray a)) s) ())
step forall {a}. m (Step (Tuple' (Maybe a) s) ())
initial forall {p} {a}. p -> a
extract Tuple' (Maybe (MutArray a)) s -> m ()
final

    where

    initial :: m (Step (Tuple' (Maybe a) s) ())
initial = do
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n forall a. Ord a => a -> a -> Bool
<= Int
0) forall a b. (a -> b) -> a -> b
$
            -- XXX we can pass the module string from the higher level API
            forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Streamly.Internal.Data.MutArray.Type.packArraysChunksOf: the size of "
                 forall a. [a] -> [a] -> [a]
++ [Char]
"arrays [" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n forall a. [a] -> [a] -> [a]
++ [Char]
"] must be a natural number"

        Step s ()
r <- m (Step s ())
initial1
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall a b. a -> b -> Tuple' a b
Tuple' forall a. Maybe a
Nothing) Step s ()
r

    step :: Tuple' (Maybe (MutArray a)) s
-> MutArray a -> m (Step (Tuple' (Maybe (MutArray a)) s) ())
step (Tuple' Maybe (MutArray a)
Nothing s
r1) MutArray a
arr =
            let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
             in if Int
len forall a. Ord a => a -> a -> Bool
>= Int
n
                then do
                    Step s ()
r <- s -> MutArray a -> m (Step s ())
step1 s
r1 MutArray a
arr
                    case Step s ()
r of
                        FL.Done ()
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
FL.Done ()
                        FL.Partial s
s -> do
                            ()
_ <- s -> m ()
final1 s
s
                            Step s ()
res <- m (Step s ())
initial1
                            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall a b. a -> b -> Tuple' a b
Tuple' forall a. Maybe a
Nothing) Step s ()
res
                else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
FL.Partial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' (forall a. a -> Maybe a
Just MutArray a
arr) s
r1

    step (Tuple' (Just MutArray a
buf) s
r1) MutArray a
arr = do
            let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
buf forall a. Num a => a -> a -> a
+ forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
            MutArray a
buf' <- if forall a. MutArray a -> Int
MArray.byteCapacity MutArray a
buf forall a. Ord a => a -> a -> Bool
< Int
len
                    then forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> MutArray a -> m (MutArray a)
MArray.realloc (forall a. Ord a => a -> a -> a
max Int
n Int
len) MutArray a
buf
                    else forall (m :: * -> *) a. Monad m => a -> m a
return MutArray a
buf
            MutArray a
buf'' <- forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
MutArray a -> MutArray a -> m (MutArray a)
MArray.splice MutArray a
buf' MutArray a
arr

            -- XXX this is common in both the equations of step
            if Int
len forall a. Ord a => a -> a -> Bool
>= Int
n
            then do
                Step s ()
r <- s -> MutArray a -> m (Step s ())
step1 s
r1 MutArray a
buf''
                case Step s ()
r of
                    FL.Done ()
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
FL.Done ()
                    FL.Partial s
s -> do
                        ()
_ <- s -> m ()
final1 s
s
                        Step s ()
res <- m (Step s ())
initial1
                        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall a b. a -> b -> Tuple' a b
Tuple' forall a. Maybe a
Nothing) Step s ()
res
            else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
FL.Partial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' (forall a. a -> Maybe a
Just MutArray a
buf'') s
r1

    -- XXX Several folds do extract >=> final, therefore, we need to make final
    -- return  "m b" rather than using extract post it if we want extract to be
    -- partial.
    --
    -- extract forces the pending buffer to be sent to the fold which is not
    -- what we want.
    extract :: p -> a
extract p
_ = forall a. HasCallStack => [Char] -> a
error [Char]
"lpackArraysChunksOf: not designed for scanning"

    final :: Tuple' (Maybe (MutArray a)) s -> m ()
final (Tuple' Maybe (MutArray a)
Nothing s
r1) = s -> m ()
final1 s
r1
    final (Tuple' (Just MutArray a
buf) s
r1) = do
        Step s ()
r <- s -> MutArray a -> m (Step s ())
step1 s
r1 MutArray a
buf
        case Step s ()
r of
            FL.Partial s
rr -> s -> m ()
final1 s
rr
            FL.Done ()
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- XXX Same as compactLE, to be removed once that is implemented.
--
-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
-- maximum specified size in bytes.
--
-- /Internal/
{-# INLINE compact #-}
compact :: (MonadIO m, Unbox a)
    => Int -> Stream m (MutArray a) -> Stream m (MutArray a)
compact :: forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Stream m (MutArray a) -> Stream m (MutArray a)
compact = forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Stream m (MutArray a) -> Stream m (MutArray a)
packArraysChunksOf

-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
-- maximum specified size. Note that if a single array is bigger than the
-- specified size we do not split it to fit. When we coalesce multiple arrays
-- if the size would exceed the specified size we do not coalesce therefore the
-- actual array size may be less than the specified chunk size.
--
-- /Internal/
{-# INLINE_NORMAL compactLEParserD #-}
compactLEParserD ::
       forall m a. (MonadIO m, Unbox a)
    => Int -> ParserD.Parser (MutArray a) m (MutArray a)
compactLEParserD :: forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Parser (MutArray a) m (MutArray a)
compactLEParserD Int
n = forall a (m :: * -> *) b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m (Step s b)) -> Parser a m b
ParserD.Parser forall {m :: * -> *} {a}.
(MonadIO m, Unbox a) =>
Maybe (MutArray a)
-> MutArray a -> m (Step (Maybe (MutArray a)) (MutArray a))
step forall {a} {b}. m (Initial (Maybe a) b)
initial forall {m :: * -> *} {a} {s}.
Monad m =>
Maybe (MutArray a) -> m (Step s (MutArray a))
extract

    where

    nBytes :: Int
nBytes = Int
n forall a. Num a => a -> a -> a
* SIZE_OF(a)

    initial :: m (Initial (Maybe a) b)
initial =
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ if Int
n forall a. Ord a => a -> a -> Bool
<= Int
0
              then forall a. HasCallStack => [Char] -> a
error
                       forall a b. (a -> b) -> a -> b
$ [Char]
functionPath
                       forall a. [a] -> [a] -> [a]
++ [Char]
": the size of arrays ["
                       forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n forall a. [a] -> [a] -> [a]
++ [Char]
"] must be a natural number"
              else forall s b. s -> Initial s b
ParserD.IPartial forall a. Maybe a
Nothing

    step :: Maybe (MutArray a)
-> MutArray a -> m (Step (Maybe (MutArray a)) (MutArray a))
step Maybe (MutArray a)
Nothing MutArray a
arr =
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
               in if Int
len forall a. Ord a => a -> a -> Bool
>= Int
nBytes
                  then forall s b. Int -> b -> Step s b
ParserD.Done Int
0 MutArray a
arr
                  else forall s b. Int -> s -> Step s b
ParserD.Partial Int
0 (forall a. a -> Maybe a
Just MutArray a
arr)
    step (Just MutArray a
buf) MutArray a
arr =
        let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
buf forall a. Num a => a -> a -> a
+ forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
         in if Int
len forall a. Ord a => a -> a -> Bool
> Int
nBytes
            then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
ParserD.Done Int
1 MutArray a
buf
            else do
                MutArray a
buf1 <-
                    if forall a. MutArray a -> Int
MArray.byteCapacity MutArray a
buf forall a. Ord a => a -> a -> Bool
< Int
nBytes
                    then forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> MutArray a -> m (MutArray a)
MArray.realloc Int
nBytes MutArray a
buf
                    else forall (m :: * -> *) a. Monad m => a -> m a
return MutArray a
buf
                MutArray a
buf2 <- forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
MutArray a -> MutArray a -> m (MutArray a)
MArray.splice MutArray a
buf1 MutArray a
arr
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
ParserD.Partial Int
0 (forall a. a -> Maybe a
Just MutArray a
buf2)

    extract :: Maybe (MutArray a) -> m (Step s (MutArray a))
extract Maybe (MutArray a)
Nothing = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
ParserD.Done Int
0 forall a. MutArray a
MArray.nil
    extract (Just MutArray a
buf) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
ParserD.Done Int
0 MutArray a
buf

    functionPath :: [Char]
functionPath =
        [Char]
"Streamly.Internal.Data.Stream.MutChunked.compactLEParserD"

-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
-- minimum specified size. Note that if all the arrays in the stream together
-- are smaller than the specified size the resulting array will be smaller than
-- the specified size. When we coalesce multiple arrays if the size would exceed
-- the specified size we stop coalescing further.
--
-- /Internal/
{-# INLINE_NORMAL compactGEFold #-}
compactGEFold ::
       forall m a. (MonadIO m, Unbox a)
    => Int -> FL.Fold m (MutArray a) (MutArray a)
compactGEFold :: forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Fold m (MutArray a) (MutArray a)
compactGEFold Int
n = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> (s -> m b) -> Fold m a b
Fold forall {m :: * -> *} {a}.
(MonadIO m, Unbox a) =>
Maybe (MutArray a)
-> MutArray a -> m (Step (Maybe (MutArray a)) (MutArray a))
step forall {a} {b}. m (Step (Maybe a) b)
initial forall {m :: * -> *} {a}.
Monad m =>
Maybe (MutArray a) -> m (MutArray a)
extract forall {m :: * -> *} {a}.
Monad m =>
Maybe (MutArray a) -> m (MutArray a)
extract

    where

    nBytes :: Int
nBytes = Int
n forall a. Num a => a -> a -> a
* SIZE_OF(a)

    initial :: m (Step (Maybe a) b)
initial =
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ if Int
n forall a. Ord a => a -> a -> Bool
< Int
0
              then forall a. HasCallStack => [Char] -> a
error
                       forall a b. (a -> b) -> a -> b
$ [Char]
functionPath
                       forall a. [a] -> [a] -> [a]
++ [Char]
": the size of arrays ["
                       forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n forall a. [a] -> [a] -> [a]
++ [Char]
"] must be a natural number"
              else forall s b. s -> Step s b
FL.Partial forall a. Maybe a
Nothing

    step :: Maybe (MutArray a)
-> MutArray a -> m (Step (Maybe (MutArray a)) (MutArray a))
step Maybe (MutArray a)
Nothing MutArray a
arr =
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
               in if Int
len forall a. Ord a => a -> a -> Bool
>= Int
nBytes
                  then forall s b. b -> Step s b
FL.Done MutArray a
arr
                  else forall s b. s -> Step s b
FL.Partial (forall a. a -> Maybe a
Just MutArray a
arr)
    step (Just MutArray a
buf) MutArray a
arr = do
        let len :: Int
len = forall a. MutArray a -> Int
MArray.byteLength MutArray a
buf forall a. Num a => a -> a -> a
+ forall a. MutArray a -> Int
MArray.byteLength MutArray a
arr
        MutArray a
buf1 <-
            if forall a. MutArray a -> Int
MArray.byteCapacity MutArray a
buf forall a. Ord a => a -> a -> Bool
< Int
len
            then forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> MutArray a -> m (MutArray a)
MArray.realloc (forall a. Ord a => a -> a -> a
max Int
len Int
nBytes) MutArray a
buf
            else forall (m :: * -> *) a. Monad m => a -> m a
return MutArray a
buf
        MutArray a
buf2 <- forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
MutArray a -> MutArray a -> m (MutArray a)
MArray.splice MutArray a
buf1 MutArray a
arr
        if Int
len forall a. Ord a => a -> a -> Bool
>= Int
n
        then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
FL.Done MutArray a
buf2
        else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
FL.Partial (forall a. a -> Maybe a
Just MutArray a
buf2)

    extract :: Maybe (MutArray a) -> m (MutArray a)
extract Maybe (MutArray a)
Nothing = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. MutArray a
MArray.nil
    extract (Just MutArray a
buf) = forall (m :: * -> *) a. Monad m => a -> m a
return MutArray a
buf

    functionPath :: [Char]
functionPath =
        [Char]
"Streamly.Internal.Data.Stream.MutChunked.compactGEFold"

-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
-- maximum specified size in bytes.
--
-- /Internal/
compactLE :: (MonadIO m, Unbox a) =>
    Int -> Stream m (MutArray a) -> Stream m (Either ParseError (MutArray a))
compactLE :: forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int
-> Stream m (MutArray a)
-> Stream m (Either ParseError (MutArray a))
compactLE Int
n = forall (m :: * -> *) a b.
Monad m =>
Parser a m b -> Stream m a -> Stream m (Either ParseError b)
D.parseManyD (forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Parser (MutArray a) m (MutArray a)
compactLEParserD Int
n)

-- | Like 'compactLE' but generates arrays of exactly equal to the size
-- specified except for the last array in the stream which could be shorter.
--
-- /Unimplemented/
{-# INLINE compactEQ #-}
compactEQ :: -- (MonadIO m, Unbox a) =>
    Int -> Stream m (MutArray a) -> Stream m (MutArray a)
compactEQ :: forall (m :: * -> *) a.
Int -> Stream m (MutArray a) -> Stream m (MutArray a)
compactEQ Int
_n Stream m (MutArray a)
_xs = forall a. HasCallStack => a
undefined
    -- IsStream.fromStreamD $ D.foldMany (compactEQFold n) (IsStream.toStreamD xs)

-- | Like 'compactLE' but generates arrays of size greater than or equal to the
-- specified except for the last array in the stream which could be shorter.
--
-- /Internal/
{-# INLINE compactGE #-}
compactGE ::
       (MonadIO m, Unbox a)
    => Int -> Stream m (MutArray a) -> Stream m (MutArray a)
compactGE :: forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Stream m (MutArray a) -> Stream m (MutArray a)
compactGE Int
n = forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Stream m a -> Stream m b
D.foldMany (forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Fold m (MutArray a) (MutArray a)
compactGEFold Int
n)