4-- Module : Streamly.Internal.Data.Array.Mut
5-- Copyright : (c) 2020 Composewell Technologies
6-- License : BSD-3-Clause
7-- Maintainer : streamly@composewell.com
8-- Stability : experimental
11-- Unboxed pinned mutable array type for 'Unboxed' types with an option to use
12-- foreign (non-GHC) memory allocators. Fulfils the following goals:
14-- * Random access (array)
15-- * Efficient storage (unboxed)
16-- * Performance (unboxed access)
17-- * Performance - in-place operations (mutable)
18-- * Performance - GC (pinned, mutable)
19-- * interfacing with OS (pinned)
20-- * Fragmentation control (foreign allocators)
22-- Stream and Fold APIs allow easy, efficient and convenient operations on
25module Streamly.Internal.Data.Array.Mut
27 module Streamly.Internal.Data.Array.Mut.Type
35import Control.Monad.IO.Class (MonadIO(..))
36import Streamly.Internal.Data.Unboxed (Unbox)
37import Streamly.Internal.Data.Stream (Stream)
38import Streamly.Internal.Data.Unfold.Type (Unfold(..))
40import qualified Streamly.Internal.Data.Stream.StreamD as D
41import qualified Streamly.Internal.Data.Stream.Type as Stream
42import qualified Streamly.Internal.Data.Unfold as Unfold
43-- import qualified Streamly.Internal.Data.Stream.Common as P
45import Prelude hiding (foldr, length, read, splitAt)
46import Streamly.Internal.Data.Array.Mut.Type
48-- | Split the array into a stream of slices using a predicate. The element
49-- matching the predicate is dropped.
53splitOn :: (MonadIO m, Unbox a) =>
54 (a -> Bool) -> Array a -> Stream m (Array a)
55splitOn predicate arr =
57 $ fmap (\(i, len) -> getSliceUnsafe i len arr)
58 $ D.sliceOnSuffix predicate (toStreamD arr)
60-- | Generate a stream of array slice descriptors ((index, len)) of specified
61-- length from an array, starting from the supplied array index. The last slice
62-- may be shorter than the requested length depending on the array length.
65{-# INLINE genSlicesFromLen #-}
66genSlicesFromLen :: forall m a. (Monad m, Unbox a)
67 => Int -- ^ from index
68 -> Int -- ^ length of the slice
69 -> Unfold m (Array a) (Int, Int)
70genSlicesFromLen from len =
71 let fromThenTo n = (from, from + len, n - 1)
72 mkSlice n i = return (i, min len (n - i))
74 $ Unfold.mapM2 mkSlice
75 $ Unfold.lmap fromThenTo Unfold.enumerateFromThenTo
77-- | Generate a stream of slices of specified length from an array, starting
78-- from the supplied array index. The last slice may be shorter than the
79-- requested length depending on the array length.
82{-# INLINE getSlicesFromLen #-}
83getSlicesFromLen :: forall m a. (Monad m, Unbox a)
84 => Int -- ^ from index
85 -> Int -- ^ length of the slice
86 -> Unfold m (Array a) (Array a)
87getSlicesFromLen from len =
88 let mkSlice arr (i, n) = return $ getSliceUnsafe i n arr
89 in Unfold.mapM2 mkSlice (genSlicesFromLen from len)
91-- | Create an 'Array' from a stream. This is useful when we want to create a
92-- single array from a stream of unknown size. 'writeN' is at least twice
93-- as efficient when the size is already known.
95-- Note that if the input stream is too large memory allocation for the array
96-- may fail. When the stream size is not known, `arraysOf` followed by
97-- processing of indvidual arrays in the resulting stream should be preferred.
100{-# INLINE fromStream #-}
101fromStream :: (MonadIO m, Unbox a) => Stream m a -> m (Array a)
102fromStream = fromStreamD . Stream.toStreamD
103-- fromStream (Stream m) = P.fold write m
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list