on a02f2d0 help sign in
146 lines 4.4 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 -- * Type
28 Array
29 -- , writeIndex
30 -- , writeFrom -- start writing at the given position
31 -- , writeFromRev
32 -- , writeTo -- write from beginning up to the given position
33 -- , writeToRev
34 -- , writeFromTo
35 -- , writeFromThenTo
36 --
37 -- , writeChunksOfFrom
38 -- , ...
40 -- * Mutation
41 , writeIndex
42 , snoc
44 --, writeIndices
45 --, writeRanges
47 -- -- * In-pace mutation (for Mutable Array type)
48 -- , partitionBy
49 -- , shuffleBy
50 -- , foldtWith
51 -- , foldbWith
53 -- * Folding
54 , foldl'
55 , foldr
57 -- * Composable Folds
58 , writeN
59 , write
61 -- * Unfolds
62 , read
64 -- * To containers
65 , toList
67 -- * Combining
68 , spliceWith
69 , spliceWithDoubling
70 , spliceTwo
72 -- * Splitting
73 , breakOn
74 , splitAt
75 )
76where
78import Control.Monad.IO.Class (MonadIO(..))
79import Foreign.Storable (Storable(..))
80import Streamly.Internal.BaseCompat (unsafeWithForeignPtr)
82import Prelude hiding (foldr, length, read, splitAt)
84import Streamly.Internal.Data.Array.Foreign.Mut.Type
86-- | /O(1)/ Write the given element at the given index in the array.
87-- Performs in-place mutation of the array.
88--
89-- /Pre-release/
90{-# INLINE writeIndex #-}
91writeIndex :: (MonadIO m, Storable a) => Array a -> Int -> a -> m ()
92writeIndex arr i a = do
93 let maxIndex = length arr - 1
94 if i < 0
95 then error "writeIndex: negative array index"
96 else if i > maxIndex
97 then error $ "writeIndex: specified array index " ++ show i
98 ++ " is beyond the maximum index " ++ show maxIndex
99 else
100 liftIO $ unsafeWithForeignPtr (aStart arr) $ \p ->
101 pokeElemOff p i a
103{-
105-------------------------------------------------------------------------------
106-- In-place mutation APIs
107-------------------------------------------------------------------------------
109-- | Partition an array into two halves using a partitioning predicate. The
110-- first half retains values where the predicate is 'False' and the second half
111-- retains values where the predicate is 'True'.
112{-# INLINE partitionBy #-}
113partitionBy :: (a -> Bool) -> Array a -> (Array a, Array a)
114partitionBy f arr = undefined
116-- | Shuffle corresponding elements from two arrays using a shuffle function.
117-- If the shuffle function returns 'False' then do nothing otherwise swap the
118-- elements. This can be used in a bottom up fold to shuffle or reorder the
119-- elements.
120shuffleBy :: (a -> a -> m Bool) -> Array a -> Array a -> m (Array a)
121shuffleBy f arr1 arr2 = undefined
123-- XXX we can also make the folds partial by stopping at a certain level.
124--
125-- | Perform a top down hierarchical recursive partitioning fold of items in
126-- the container using the given function as the partition function.
127--
128-- This will perform a quick sort if the partition function is
129-- 'partitionBy (< pivot)'.
130--
131-- @since 0.7.0
132{-# INLINABLE foldtWith #-}
133foldtWith :: Int -> (Array a -> Array a -> m (Array a)) -> Array a -> m (Array a)
134foldtWith level f = undefined
136-- | Perform a pairwise bottom up fold recursively merging the pairs. Level
137-- indicates the level in the tree where the fold would stop.
138--
139-- This will perform a random shuffle if the shuffle function is random.
140-- If we stop at level 0 and repeatedly apply the function then we can do a
141-- bubble sort.
142foldbWith :: Int -> (Array a -> Array a -> m (Array a)) -> Array a -> m (Array a)
143foldbWith level f = undefined
144-}
146-- XXX consider the bulk update/accumulation/permutation APIs from vector.