on 7cb856b help sign in
89 lines 3.2 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.MutArray
3-- Copyright : (c) 2020 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
7-- Portability : GHC
8--
9module Streamly.Internal.Data.MutArray
10 (
11 module Streamly.Internal.Data.MutArray.Type
12 -- * Unboxed IORef
13 , module Streamly.Internal.Data.IORef.Unboxed
14 , splitOn
15 , genSlicesFromLen
16 , getSlicesFromLen
17 , fromStream
18 )
19where
21#include "inline.hs"
23import Control.Monad.IO.Class (MonadIO(..))
24import Streamly.Internal.Data.Unbox (Unbox)
25import Streamly.Internal.Data.Stream (Stream)
26import Streamly.Internal.Data.Unfold.Type (Unfold(..))
28import qualified Streamly.Internal.Data.Stream as D
29import qualified Streamly.Internal.Data.Unfold as Unfold
31import Prelude hiding (foldr, length, read, splitAt)
32import Streamly.Internal.Data.MutArray.Type
33import Streamly.Internal.Data.IORef.Unboxed
35-- | Split the array into a stream of slices using a predicate. The element
36-- matching the predicate is dropped.
37--
38-- /Pre-release/
39{-# INLINE splitOn #-}
40splitOn :: (MonadIO m, Unbox a) =>
41 (a -> Bool) -> MutArray a -> Stream m (MutArray a)
42splitOn predicate arr =
43 fmap (\(i, len) -> getSliceUnsafe i len arr)
44 $ D.sliceOnSuffix predicate (read arr)
46-- | Generate a stream of array slice descriptors ((index, len)) of specified
47-- length from an array, starting from the supplied array index. The last slice
48-- may be shorter than the requested length depending on the array length.
49--
50-- /Pre-release/
51{-# INLINE genSlicesFromLen #-}
52genSlicesFromLen :: forall m a. (Monad m, Unbox a)
53 => Int -- ^ from index
54 -> Int -- ^ length of the slice
55 -> Unfold m (MutArray a) (Int, Int)
56genSlicesFromLen from len =
57 let fromThenTo n = (from, from + len, n - 1)
58 mkSlice n i = return (i, min len (n - i))
59 in Unfold.lmap length
60 $ Unfold.mapM2 mkSlice
61 $ Unfold.lmap fromThenTo Unfold.enumerateFromThenTo
63-- | Generate a stream of slices of specified length from an array, starting
64-- from the supplied array index. The last slice may be shorter than the
65-- requested length depending on the array length.
66--
67-- /Pre-release/
68{-# INLINE getSlicesFromLen #-}
69getSlicesFromLen :: forall m a. (Monad m, Unbox a)
70 => Int -- ^ from index
71 -> Int -- ^ length of the slice
72 -> Unfold m (MutArray a) (MutArray a)
73getSlicesFromLen from len =
74 let mkSlice arr (i, n) = return $ getSliceUnsafe i n arr
75 in Unfold.mapM2 mkSlice (genSlicesFromLen from len)
77-- | Create an 'Array' from a stream. This is useful when we want to create a
78-- single array from a stream of unknown size. 'writeN' is at least twice
79-- as efficient when the size is already known.
80--
81-- Note that if the input stream is too large memory allocation for the array
82-- may fail. When the stream size is not known, `chunksOf` followed by
83-- processing of indvidual arrays in the resulting stream should be preferred.
84--
85-- /Pre-release/
86{-# INLINE fromStream #-}
87fromStream :: (MonadIO m, Unbox a) => Stream m a -> m (MutArray a)
88fromStream = fromStreamD
89-- fromStream (Stream m) = P.fold write m