on 9119e44 help sign in
85 lines 3.1 kB history raw
1#include "inline.hs"
3-- |
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
9-- Portability : GHC
10--
11-- Unboxed pinned mutable array type for 'Storable' types with an option to use
12-- foreign (non-GHC) memory allocators. Fulfils the following goals:
13--
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)
21--
22-- Stream and Fold APIs allow easy, efficient and convenient operations on
23-- arrays.
25module Streamly.Internal.Data.Array.Foreign.Mut
26 (
27 module Streamly.Internal.Data.Array.Foreign.Mut.Type
28 , splitOn
29 , genSlicesFromLen
30 , getSlicesFromLen
31 )
32where
34import Prelude hiding (foldr, length, read, splitAt)
36import Streamly.Internal.Data.Array.Foreign.Mut.Type
37import qualified Streamly.Internal.Data.Stream.StreamD as D
38import Foreign.Storable (Storable)
39import Streamly.Internal.Data.Stream.IsStream.Type (SerialT)
40import qualified Streamly.Internal.Data.Stream.IsStream.Type as IsStream
41import qualified Streamly.Internal.Data.Unfold as Unfold
42import Streamly.Internal.Data.Unfold.Type (Unfold(..))
44-- | Split the array into a stream of slices using a predicate. The element
45-- matching the predicate is dropped.
46--
47-- /Pre-release/
48{-# INLINE splitOn #-}
49splitOn :: (Monad m, Storable a) =>
50 (a -> Bool) -> Array a -> SerialT m (Array a)
51splitOn predicate arr =
52 IsStream.fromStreamD
53 $ fmap (\(i, len) -> getSliceUnsafe i len arr)
54 $ D.sliceOnSuffix predicate (toStreamD arr)
56-- | Generate a stream of array slice descriptors ((index, len)) of specified
57-- length from an array, starting from the supplied array index. The last slice
58-- may be shorter than the requested length depending on the array length.
59--
60-- /Pre-release/
61{-# INLINE genSlicesFromLen #-}
62genSlicesFromLen :: forall m a. (Monad m, Storable a)
63 => Int -- ^ from index
64 -> Int -- ^ length of the slice
65 -> Unfold m (Array a) (Int, Int)
66genSlicesFromLen from len =
67 let fromThenTo n = (from, from + len, n - 1)
68 mkSlice n i = return (i, min len (n - i))
69 in Unfold.lmap length
70 $ Unfold.mapMWithInput mkSlice
71 $ Unfold.lmap fromThenTo Unfold.enumerateFromThenTo
73-- | Generate a stream of slices of specified length from an array, starting
74-- from the supplied array index. The last slice may be shorter than the
75-- requested length depending on the array length.
76--
77-- /Pre-release/
78{-# INLINE getSlicesFromLen #-}
79getSlicesFromLen :: forall m a. (Monad m, Storable a)
80 => Int -- ^ from index
81 -> Int -- ^ length of the slice
82 -> Unfold m (Array a) (Array a)
83getSlicesFromLen from len =
84 let mkSlice arr (i, n) = return $ getSliceUnsafe i n arr
85 in Unfold.mapMWithInput mkSlice (genSlicesFromLen from len)