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.StreamD (Stream)
38import Streamly.Internal.Data.Unfold.Type (Unfold(..))
40import qualified Streamly.Internal.Data.Stream.StreamD as D
41import qualified Streamly.Internal.Data.Unfold as Unfold
43import Prelude hiding (foldr, length, read, splitAt)
44import Streamly.Internal.Data.Array.Mut.Type
46-- | Split the array into a stream of slices using a predicate. The element
47-- matching the predicate is dropped.
51splitOn :: (MonadIO m, Unbox a) =>
52 (a -> Bool) -> MutArray a -> Stream m (MutArray a)
53splitOn predicate arr =
54 fmap (\(i, len) -> getSliceUnsafe i len arr)
55 $ D.sliceOnSuffix predicate (toStreamD arr)
57-- | Generate a stream of array slice descriptors ((index, len)) of specified
58-- length from an array, starting from the supplied array index. The last slice
59-- may be shorter than the requested length depending on the array length.
62{-# INLINE genSlicesFromLen #-}
63genSlicesFromLen :: forall m a. (Monad m, Unbox a)
64 => Int -- ^ from index
65 -> Int -- ^ length of the slice
66 -> Unfold m (MutArray a) (Int, Int)
67genSlicesFromLen from len =
68 let fromThenTo n = (from, from + len, n - 1)
69 mkSlice n i = return (i, min len (n - i))
71 $ Unfold.mapM2 mkSlice
72 $ Unfold.lmap fromThenTo Unfold.enumerateFromThenTo
74-- | Generate a stream of slices of specified length from an array, starting
75-- from the supplied array index. The last slice may be shorter than the
76-- requested length depending on the array length.
79{-# INLINE getSlicesFromLen #-}
80getSlicesFromLen :: forall m a. (Monad m, Unbox a)
81 => Int -- ^ from index
82 -> Int -- ^ length of the slice
83 -> Unfold m (MutArray a) (MutArray a)
84getSlicesFromLen from len =
85 let mkSlice arr (i, n) = return $ getSliceUnsafe i n arr
86 in Unfold.mapM2 mkSlice (genSlicesFromLen from len)
88-- | Create an 'Array' from a stream. This is useful when we want to create a
89-- single array from a stream of unknown size. 'writeN' is at least twice
90-- as efficient when the size is already known.
92-- Note that if the input stream is too large memory allocation for the array
93-- may fail. When the stream size is not known, `arraysOf` followed by
94-- processing of indvidual arrays in the resulting stream should be preferred.
97{-# INLINE fromStream #-}
98fromStream :: (MonadIO m, Unbox a) => Stream m a -> m (MutArray a)
99fromStream = fromStreamD
100-- 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