4-- Module : Streamly.Internal.Data.Array.Foreign.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 'Storable' 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.Foreign.Mut
27 module Streamly.Internal.Data.Array.Foreign.Mut.Type
35import Control.Monad.IO.Class (MonadIO(..))
36import Foreign.Storable (Storable)
37import Streamly.Internal.Data.Stream.Serial (SerialT(..))
38import Streamly.Internal.Data.Unfold.Type (Unfold(..))
40import qualified Streamly.Internal.Data.Stream.StreamD as D
41import qualified Streamly.Internal.Data.Unfold as Unfold
42-- import qualified Streamly.Internal.Data.Stream.Prelude as P
44import Prelude hiding (foldr, length, read, splitAt)
45import Streamly.Internal.Data.Array.Foreign.Mut.Type
47-- | Split the array into a stream of slices using a predicate. The element
48-- matching the predicate is dropped.
52splitOn :: (MonadIO m, Storable a) =>
53 (a -> Bool) -> Array a -> SerialT m (Array a)
54splitOn 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, Storable 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.mapMWithInput 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, Storable 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.mapMWithInput 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, Storable a) => SerialT m a -> m (Array a)
102fromStream (SerialT m) = fromStreamD $ D.fromStreamK m
103-- fromStream (SerialT 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