{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
#include "inline.hs"
module Streamly.Internal.Data.SmallArray
(
SmallArray(..)
, foldl'
, foldr
, length
, writeN
, toStreamD
, toStreamDRev
, toStream
, toStreamRev
, read
, fromListN
, fromStreamDN
, fromStreamN
, streamFold
, fold
)
where
import Prelude hiding (foldr, length, read)
import Control.DeepSeq (NFData(..))
import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO, liftIO)
import GHC.IO (unsafePerformIO)
import Data.Functor.Identity (runIdentity)
import Streamly.Internal.Data.SmallArray.Types
import Streamly.Internal.Data.Unfold.Types (Unfold(..))
import Streamly.Internal.Data.Fold.Types (Fold(..))
import Streamly.Internal.Data.Stream.StreamK.Type (IsStream)
import Streamly.Internal.Data.Stream.Serial (SerialT)
import qualified Streamly.Internal.Data.Stream.StreamD as D
{-# NOINLINE bottomElement #-}
bottomElement :: a
bottomElement :: forall a. a
bottomElement = forall a. HasCallStack => a
undefined
{-# INLINE length #-}
length :: SmallArray a -> Int
length :: forall a. SmallArray a -> Int
length SmallArray a
arr = forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
arr
{-# INLINE_NORMAL toStreamD #-}
toStreamD :: Monad m => SmallArray a -> D.Stream m a
toStreamD :: forall (m :: * -> *) a. Monad m => SmallArray a -> Stream m a
toStreamD SmallArray a
arr = forall (m :: * -> *) a s.
(State Stream m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream forall {m :: * -> *} {p}. Monad m => p -> Int -> m (Step Int a)
step Int
0
where
{-# INLINE_LATE step #-}
step :: p -> Int -> m (Step Int a)
step p
_ Int
i
| Int
i forall a. Eq a => a -> a -> Bool
== forall a. SmallArray a -> Int
length SmallArray a
arr = forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
D.Stop
| Bool
otherwise =
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
case forall a. SmallArray a -> Int -> (# a #)
indexSmallArray## SmallArray a
arr Int
i of
(# a
x #) -> forall s a. a -> s -> Step s a
D.Yield a
x (Int
i forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE_NORMAL toStreamDRev #-}
toStreamDRev :: Monad m => SmallArray a -> D.Stream m a
toStreamDRev :: forall (m :: * -> *) a. Monad m => SmallArray a -> Stream m a
toStreamDRev SmallArray a
arr = forall (m :: * -> *) a s.
(State Stream m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream forall {m :: * -> *} {p}. Monad m => p -> Int -> m (Step Int a)
step (forall a. SmallArray a -> Int
length SmallArray a
arr forall a. Num a => a -> a -> a
- Int
1)
where
{-# INLINE_LATE step #-}
step :: p -> Int -> m (Step Int a)
step p
_ Int
i
| Int
i forall a. Ord a => a -> a -> Bool
< Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
D.Stop
| Bool
otherwise =
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
case forall a. SmallArray a -> Int -> (# a #)
indexSmallArray## SmallArray a
arr Int
i of
(# a
x #) -> forall s a. a -> s -> Step s a
D.Yield a
x (Int
i forall a. Num a => a -> a -> a
- Int
1)
{-# INLINE_NORMAL foldl' #-}
foldl' :: (b -> a -> b) -> b -> SmallArray a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> SmallArray a -> b
foldl' b -> a -> b
f b
z SmallArray a
arr = forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) b a.
Monad m =>
(b -> a -> b) -> b -> Stream m a -> m b
D.foldl' b -> a -> b
f b
z forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => SmallArray a -> Stream m a
toStreamD SmallArray a
arr
{-# INLINE_NORMAL foldr #-}
foldr :: (a -> b -> b) -> b -> SmallArray a -> b
foldr :: forall a b. (a -> b -> b) -> b -> SmallArray a -> b
foldr a -> b -> b
f b
z SmallArray a
arr = forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b.
Monad m =>
(a -> b -> b) -> b -> Stream m a -> m b
D.foldr a -> b -> b
f b
z forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => SmallArray a -> Stream m a
toStreamD SmallArray a
arr
{-# INLINE_NORMAL writeN #-}
writeN :: MonadIO m => Int -> Fold m a (SmallArray a)
writeN :: forall (m :: * -> *) a. MonadIO m => Int -> Fold m a (SmallArray a)
writeN Int
limit = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold forall {m :: * -> *} {a}.
MonadIO m =>
(SmallMutableArray RealWorld a, Int)
-> a -> m (SmallMutableArray RealWorld a, Int)
step forall {a}. m (SmallMutableArray RealWorld a, Int)
initial forall {m :: * -> *} {a}.
MonadIO m =>
(SmallMutableArray RealWorld a, Int) -> m (SmallArray a)
extract
where
initial :: m (SmallMutableArray RealWorld a, Int)
initial = do
SmallMutableArray RealWorld a
marr <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
limit forall a. a
bottomElement
forall (m :: * -> *) a. Monad m => a -> m a
return (SmallMutableArray RealWorld a
marr, Int
0)
step :: (SmallMutableArray RealWorld a, Int)
-> a -> m (SmallMutableArray RealWorld a, Int)
step (SmallMutableArray RealWorld a
marr, Int
i) a
x
| Int
i forall a. Eq a => a -> a -> Bool
== Int
limit = forall (m :: * -> *) a. Monad m => a -> m a
return (SmallMutableArray RealWorld a
marr, Int
i)
| Bool
otherwise = do
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray RealWorld a
marr Int
i a
x
forall (m :: * -> *) a. Monad m => a -> m a
return (SmallMutableArray RealWorld a
marr, Int
i forall a. Num a => a -> a -> a
+ Int
1)
extract :: (SmallMutableArray RealWorld a, Int) -> m (SmallArray a)
extract (SmallMutableArray RealWorld a
marr, Int
len) = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> Int -> m (SmallArray a)
freezeSmallArray SmallMutableArray RealWorld a
marr Int
0 Int
len
{-# INLINE_NORMAL fromStreamDN #-}
fromStreamDN :: MonadIO m => Int -> D.Stream m a -> m (SmallArray a)
fromStreamDN :: forall (m :: * -> *) a.
MonadIO m =>
Int -> Stream m a -> m (SmallArray a)
fromStreamDN Int
limit Stream m a
str = do
SmallMutableArray RealWorld a
marr <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray (forall a. Ord a => a -> a -> a
max Int
limit Int
0) forall a. a
bottomElement
Int
i <-
forall (m :: * -> *) b a.
Monad m =>
(b -> a -> m b) -> b -> Stream m a -> m b
D.foldlM'
(\Int
i a
x -> Int
i seq :: forall a b. a -> b -> b
`seq` (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray RealWorld a
marr Int
i a
x) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (Int
i forall a. Num a => a -> a -> a
+ Int
1))
Int
0 forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Monad m => Int -> Stream m a -> Stream m a
D.take Int
limit Stream m a
str
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> Int -> m (SmallArray a)
freezeSmallArray SmallMutableArray RealWorld a
marr Int
0 Int
i
{-# INLINABLE fromListN #-}
fromListN :: Int -> [a] -> SmallArray a
fromListN :: forall a. Int -> [a] -> SmallArray a
fromListN Int
n [a]
xs = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadIO m =>
Int -> Stream m a -> m (SmallArray a)
fromStreamDN Int
n forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Applicative m => [a] -> Stream m a
D.fromList [a]
xs
instance NFData a => NFData (SmallArray a) where
{-# INLINE rnf #-}
rnf :: SmallArray a -> ()
rnf = forall b a. (b -> a -> b) -> b -> SmallArray a -> b
foldl' (\()
_ a
x -> forall a. NFData a => a -> ()
rnf a
x) ()
{-# INLINE fromStreamN #-}
fromStreamN :: MonadIO m => Int -> SerialT m a -> m (SmallArray a)
fromStreamN :: forall (m :: * -> *) a.
MonadIO m =>
Int -> SerialT m a -> m (SmallArray a)
fromStreamN Int
n SerialT m a
m = 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
$ forall a. HasCallStack => [Char] -> a
error [Char]
"fromStreamN: negative write count specified"
forall (m :: * -> *) a.
MonadIO m =>
Int -> Stream m a -> m (SmallArray a)
fromStreamDN Int
n forall a b. (a -> b) -> a -> b
$ forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
t m a -> Stream m a
D.toStreamD SerialT m a
m
{-# INLINE_EARLY toStream #-}
toStream :: (Monad m, IsStream t) => SmallArray a -> t m a
toStream :: forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, IsStream t) =>
SmallArray a -> t m a
toStream = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
D.fromStreamD forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => SmallArray a -> Stream m a
toStreamD
{-# INLINE_EARLY toStreamRev #-}
toStreamRev :: (Monad m, IsStream t) => SmallArray a -> t m a
toStreamRev :: forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, IsStream t) =>
SmallArray a -> t m a
toStreamRev = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
D.fromStreamD forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => SmallArray a -> Stream m a
toStreamDRev
{-# INLINE fold #-}
fold :: Monad m => Fold m a b -> SmallArray a -> m b
fold :: forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> SmallArray a -> m b
fold Fold m a b
f SmallArray a
arr = forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Stream m a -> m b
D.runFold Fold m a b
f (forall (m :: * -> *) a. Monad m => SmallArray a -> Stream m a
toStreamD SmallArray a
arr)
{-# INLINE streamFold #-}
streamFold :: Monad m => (SerialT m a -> m b) -> SmallArray a -> m b
streamFold :: forall (m :: * -> *) a b.
Monad m =>
(SerialT m a -> m b) -> SmallArray a -> m b
streamFold SerialT m a -> m b
f SmallArray a
arr = SerialT m a -> m b
f (forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, IsStream t) =>
SmallArray a -> t m a
toStream SmallArray a
arr)
{-# INLINE_NORMAL read #-}
read :: Monad m => Unfold m (SmallArray a) a
read :: forall (m :: * -> *) a. Monad m => Unfold m (SmallArray a) a
read = forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold forall {m :: * -> *} {a}.
Monad m =>
(SmallArray a, Int) -> m (Step (SmallArray a, Int) a)
step forall {m :: * -> *} {b} {a}. (Monad m, Num b) => a -> m (a, b)
inject
where
inject :: a -> m (a, b)
inject a
arr = forall (m :: * -> *) a. Monad m => a -> m a
return (a
arr, b
0)
step :: (SmallArray a, Int) -> m (Step (SmallArray a, Int) a)
step (SmallArray a
arr, Int
i)
| Int
i forall a. Eq a => a -> a -> Bool
== forall a. SmallArray a -> Int
length SmallArray a
arr = forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
D.Stop
| Bool
otherwise =
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
case forall a. SmallArray a -> Int -> (# a #)
indexSmallArray## SmallArray a
arr Int
i of
(# a
x #) -> forall s a. a -> s -> Step s a
D.Yield a
x (SmallArray a
arr, Int
i forall a. Num a => a -> a -> a
+ Int
1)