@@ -31,57 +31,37 @@ module Streamly.Internal.Data.MutArray.Type
31 -- ** Type
31 -- ** Type
32 -- $arrayNotes
32 -- $arrayNotes
33 MutArray (..)
33 MutArray (..)
36− -- *** Pinned and Unpinned
39 , isPinned
36 , isPinned
41− -- ** Casting
38+ -- -- * Constructing and Writing
43− , castUnsafe -- XXX unsafeCast
48 -- ** Construction
39 -- ** Construction
52− -- | New arrays are always empty arrays with some reserve capacity to
53− -- extend the length without reallocating.
55− , newArrayWith -- emptyAlignedWith
57− , pinnedNewAligned -- XXX not required
58− -- , new -- uninitialized array of specified length
64− -- *** Slicing
42+ -- *** Uninitialized Arrays
65− -- | Get a subarray without copying
43+ , pinnedNew
66− , getSliceUnsafe -- XXX unsafeGetSlice
44+ , pinnedNewBytes
67− , getSlice
45+ , pinnedNewAligned
68− , splitAt -- XXX should be able to express using getSlice
46+ , new
69− , breakOn
47+ , newArrayWith
71− -- *** Stream Folds
49+ -- *** From streams
72 , ArrayUnsafe (..)
50 , ArrayUnsafe (..)
73− , unsafeCreateOfWith
51+ , writeNWithUnsafe
74− , unsafeCreateOf
52+ , writeNWith
75− , unsafePinnedCreateOf
53+ , writeNUnsafe
76− , pinnedCreateOf
54+ , pinnedWriteNUnsafe
77− , createOfWith
55+ , writeN
78− , createOf
56+ , pinnedWriteN
79− , revCreateOf
57+ , pinnedWriteNAligned
81− , pinnedCreate
59+ , writeWith
82− , createWith
60+ , write
83− , create
61+ , pinnedWrite
86 -- *** From containers
66 -- *** From containers
87 , fromListN
67 , fromListN
@@ -97,11 +77,11 @@ module Streamly.Internal.Data.MutArray.Type
97 , fromByteStr#
77 , fromByteStr#
98 , fromPtrN
78 , fromPtrN
99 , fromChunksK
79 , fromChunksK
100− , fromChunksRealloced -- fromSmallChunks
80+ , fromChunksRealloced
102 -- ** Random writes
82 -- ** Random writes
103 , putIndex
83 , putIndex
104− , putIndexUnsafe -- XXX unsafePutIndex
84+ , putIndexUnsafe
105 , putIndices
85 , putIndices
106 -- , putFromThenTo
86 -- , putFromThenTo
107 -- , putFrom -- start writing at the given position
87 -- , putFrom -- start writing at the given position
@@ -109,69 +89,76 @@ module Streamly.Internal.Data.MutArray.Type
109 -- , putFromTo
89 -- , putFromTo
110 -- , putFromRev
90 -- , putFromRev
111 -- , putUptoRev
91 -- , putUptoRev
112− , modifyIndexUnsafe -- XXX unsafeModifyIndex
92+ , modifyIndexUnsafe
113 , modifyIndex
93 , modifyIndex
114 , modifyIndices
94 , modifyIndices
116 , swapIndices
96 , swapIndices
117 , unsafeSwapIndices
97 , unsafeSwapIndices
119− -- ** Reading
99+ -- ** Growing and Shrinking
100+ -- | Arrays grow only at the end, though it is possible to grow on both sides
101+ -- and therefore have a cons as well as snoc. But that will require two
102+ -- bounds in the array representation.
121− -- *** Indexing
104+ -- *** Appending elements
122− , getIndex
105+ , snocWith
123− , getIndexUnsafe -- XXX unsafeGetIndex
106+ , snoc
124− -- , getFromThenTo
107+ , snocLinear
125− , getIndexRev -- getRevIndex?
108+ , snocMay
126− , indexReader
109+ , snocUnsafe
129− -- *** To Streams
111+ -- *** Appending streams
130− , read
112+ , writeAppendNUnsafe
131− , readRev
113+ , writeAppendN
117+ -- ** Eliminating and Reading
124+ -- *** To containers
132 , toStreamWith
125 , toStreamWith
133 , toStreamRevWith
126 , toStreamRevWith
135 , toStreamKWith
127 , toStreamKWith
137 , toStreamKRevWith
128 , toStreamKRevWith
139− -- *** To Containers
130+ , readRev
143 -- experimental
135 -- experimental
144 , producerWith
136 , producerWith
145 , producer
137 , producer
147− , reader
139+ -- *** Random reads
148− , readerRevWith
140+ , getIndex
149− , readerRev
141+ , getIndexUnsafe
151− -- ** Size and Capacity
143+ , getIndicesWith
152− -- *** Size
144+ -- , getFromThenTo
153− , length
145+ , getIndexRev
161− -- *** Capacity Management
147+ -- ** Memory Management
162 , blockSize
148 , blockSize
163 , arrayChunkBytes
149 , arrayChunkBytes
164 , allocBytesToElemCount
150 , allocBytesToElemCount
165− , realloc -- this is "resize"
151+ , realloc
167− , growExp
153+ , resizeExp
168 , rightSize
154 , rightSize
170− -- ** Folding
156+ -- ** Size
171− , foldl'
157+ , length
172− , foldr
158+ , byteLength
173− , byteCmp
159+ -- , capacity
174− , byteEq
160+ , byteCapacity
176 -- ** In-place Mutation Algorithms
163 -- ** In-place Mutation Algorithms
@@ -183,82 +170,59 @@ module Streamly.Internal.Data.MutArray.Type
183 , mergeBy
170 , mergeBy
186− -- ** Growing and Shrinking
173+ -- ** Casting
187− -- | Arrays grow only at the end, though it is possible to grow on both
174+ , cast
188− -- sides and therefore have a cons as well as snoc. But that will require
175+ , castUnsafe
189− -- both lower and upper bound in the array representation.
176+ , asBytes
191− -- *** Appending elements
178+ , asUnpinnedPtrUnsafe
196− , snocUnsafe -- XXX unsafeSnoc
198− -- *** Appending streams
204− -- *** Appending arrays
209− , spliceUnsafe -- XXX unsafeSplice
212− -- , appendSliceFrom
214− -- ** Serialization using Unbox
217− , pokeSkipUnsafe -- unsafePokeSkip
219− -- ** Deserialization using Unbox
180+ -- ** Folding
220− , peekUncons
181+ , foldl'
221− , peekUnconsUnsafe -- unsafePeekUncons
182+ , foldr
222− , peekSkipUnsafe -- unsafePeekSkip
183+ , cmp
224− -- Arrays of arrays
187+ -- ** Arrays of arrays
225 -- We can add dimensionality parameter to the array type to get
188 -- We can add dimensionality parameter to the array type to get
226 -- multidimensional arrays. Multidimensional arrays would just be a
189 -- multidimensional arrays. Multidimensional arrays would just be a
227 -- convenience wrapper on top of single dimensional arrays.
190 -- convenience wrapper on top of single dimensional arrays.
229− -- ** Streams of Arrays
192+ -- | Operations dealing with multiple arrays, streams of arrays or
230− -- *** Chunk
193+ -- multidimensional array representations.
231− -- | Group a stream into arrays.
194+
195+ -- *** Construct from streams
232 , chunksOf
196 , chunksOf
233 , pinnedChunksOf
197 , pinnedChunksOf
234 , buildChunks
198 , buildChunks
236− -- *** Split
200+ -- *** Eliminate to streams
237− -- | Split an array into slices.
201+ , concatChunks
204+ -- *** Construct from arrays
205+ -- get chunks without copying
239 -- , getSlicesFromLenN
208 -- , getSlicesFromLenN
209+ , splitAt -- XXX should be able to express using getSlice
240 , splitOn
210 , splitOn
241− -- , slicesOf
211+ , breakOn
243− -- *** Concat
213+ -- ** Cloning arrays
244− -- | Append the arrays in a stream to form a stream of elements.
214+ , clone
245− , concatWith
215+ , pinnedClone
247− , concat
217+ -- ** Appending arrays
248− , concatRev
218+ , spliceCopy
250− -- *** Compact
220+ , splice
251− -- | Append the arrays in a stream to form a stream of larger arrays.
221+ , spliceExp
252− , SpliceState (..)
222+ , spliceUnsafe
253− , pCompactLE
223+ -- , putSlice
254− , pPinnedCompactLE
224+ -- , appendSlice
255− , compactLeAs
225+ -- , appendSliceFrom
263 -- ** Utilities
227 -- ** Utilities
264 , roundUpToPower2
228 , roundUpToPower2
@@ -267,37 +231,12 @@ module Streamly.Internal.Data.MutArray.Type
267 , c_memchr
231 , c_memchr
269 -- * Deprecated
233 -- * Deprecated
271 , writeChunks
234 , writeChunks
272 , flattenArrays
235 , flattenArrays
273 , flattenArraysRev
236 , flattenArraysRev
274 , fromArrayStreamK
237 , fromArrayStreamK
275 , fromStreamDN
238 , fromStreamDN
276 , fromStreamD
239 , fromStreamD
286− , writeAppendNUnsafe
293− , pinnedWriteNUnsafe
296− , pinnedWriteNAligned -- XXX not required
@@ -308,7 +247,6 @@ where
309import Control.Monad (when, void)
248import Control.Monad (when, void)
310import Control.Monad.IO.Class (MonadIO(..))
249import Control.Monad.IO.Class (MonadIO(..))
311−import Data.Bifunctor (first)
312import Data.Bits (shiftR, (.|.), (.&.))
250import Data.Bits (shiftR, (.|.), (.&.))
313import Data.Functor.Identity (Identity(..))
251import Data.Functor.Identity (Identity(..))
314import Data.Proxy (Proxy(..))
252import Data.Proxy (Proxy(..))
@@ -335,17 +273,13 @@ import GHC.Ptr (Ptr(..))
335import Streamly.Internal.Data.Fold.Type (Fold(..))
273import Streamly.Internal.Data.Fold.Type (Fold(..))
336import Streamly.Internal.Data.Producer.Type (Producer (..))
274import Streamly.Internal.Data.Producer.Type (Producer (..))
337import Streamly.Internal.Data.Stream.Type (Stream)
275import Streamly.Internal.Data.Stream.Type (Stream)
338−import Streamly.Internal.Data.Parser.Type (Parser (..))
339import Streamly.Internal.Data.StreamK.Type (StreamK)
276import Streamly.Internal.Data.StreamK.Type (StreamK)
340import Streamly.Internal.Data.SVar.Type (adaptState, defState)
277import Streamly.Internal.Data.SVar.Type (adaptState, defState)
341−import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
342import Streamly.Internal.Data.Unfold.Type (Unfold(..))
278import Streamly.Internal.Data.Unfold.Type (Unfold(..))
343import Streamly.Internal.System.IO (arrayPayloadSize, defaultChunkSize)
279import Streamly.Internal.System.IO (arrayPayloadSize, defaultChunkSize)
345import qualified Streamly.Internal.Data.Fold.Type as FL
281import qualified Streamly.Internal.Data.Fold.Type as FL
346import qualified Streamly.Internal.Data.MutByteArray.Type as Unboxed
282import qualified Streamly.Internal.Data.MutByteArray.Type as Unboxed
347−import qualified Streamly.Internal.Data.Parser.Type as Parser
348−-- import qualified Streamly.Internal.Data.Fold.Type as Fold
349import qualified Streamly.Internal.Data.Producer as Producer
283import qualified Streamly.Internal.Data.Producer as Producer
350import qualified Streamly.Internal.Data.Stream.Type as D
284import qualified Streamly.Internal.Data.Stream.Type as D
351import qualified Streamly.Internal.Data.Stream.Lift as D
285import qualified Streamly.Internal.Data.Stream.Lift as D
@@ -353,7 +287,7 @@ import qualified Streamly.Internal.Data.StreamK.Type as K
353import qualified Prelude
287import qualified Prelude
355import Prelude hiding
289import Prelude hiding
356− (Foldable(..), concat, read, unlines, splitAt, reverse, truncate)
290+ (Foldable(..), read, unlines, splitAt, reverse, truncate)
358#include "DocTestDataMutArray.hs"
292#include "DocTestDataMutArray.hs"
@@ -479,8 +413,6 @@ isPinned MutArray{..} = Unboxed.isPinned arrContents
479-- we need more than that. See stg_pinnedNewAlignedByteArrayzh and
413-- we need more than that. See stg_pinnedNewAlignedByteArrayzh and
480-- allocatePinned in GHC source.
414-- allocatePinned in GHC source.
482−-- XXX Rename to emptyAlignedWith, alignSize should be first arg.
484-- | @newArrayWith allocator alignment count@ allocates a new array of zero
416-- | @newArrayWith allocator alignment count@ allocates a new array of zero
485-- length and with a capacity to hold @count@ elements, using @allocator
417-- length and with a capacity to hold @count@ elements, using @allocator
486-- size alignment@ as the memory allocator function.
418-- size alignment@ as the memory allocator function.
@@ -504,25 +436,12 @@ newArrayWith alloc alignSize count = do
504 , arrBound = size
436 , arrBound = size
507−-- For arrays "nil" sounds a bit odd. empty is better. The only problem with
508−-- empty is that it is also used by the Alternative type class. But assuming we
509−-- will mostly import the Array module qualified this should be fine.
511−-- | Create an empty array.
517−empty = MutArray Unboxed.empty 0 0 0
519−{-# DEPRECATED nil "Please use empty instead." #-}
521#ifdef DEVBUILD
440#ifdef DEVBUILD
522 Unbox a =>
441 Unbox a =>
524 MutArray a
443 MutArray a
525−nil = empty
444+nil = MutArray Unboxed.nil 0 0 0
527{-# INLINE newBytesAs #-}
446{-# INLINE newBytesAs #-}
528newBytesAs :: MonadIO m =>
447newBytesAs :: MonadIO m =>
@@ -539,13 +458,12 @@ newBytesAs ps bytes = do
539 , arrBound = bytes
458 , arrBound = bytes
542−-- | Allocates a pinned empty array that with a reserved capacity of bytes.
461+-- | Allocates a pinned empty array that can hold 'count' items. The memory of
543−-- The memory of the array is uninitialized and the allocation is aligned as
462+-- the array is uninitialized and the allocation is aligned as per the
544−-- per the 'Unboxed' instance of the type.
463+-- 'Unboxed' instance of the type.
546-- /Pre-release/
465-- /Pre-release/
547{-# INLINE pinnedNewBytes #-}
466{-# INLINE pinnedNewBytes #-}
548−{-# DEPRECATED pinnedNewBytes "Please use pinnedEmptyOf with appropriate calculation" #-}
549pinnedNewBytes :: MonadIO m =>
467pinnedNewBytes :: MonadIO m =>
550#ifdef DEVBUILD
468#ifdef DEVBUILD
551 Unbox a =>
469 Unbox a =>
@@ -570,31 +488,21 @@ newAs ps =
570 (error "new: alignment is not used in unpinned arrays.")
488 (error "new: alignment is not used in unpinned arrays.")
572-- XXX can unaligned allocation be more efficient when alignment is not needed?
490-- XXX can unaligned allocation be more efficient when alignment is not needed?
574−-- | Allocates a pinned array of zero length but growable to the specified
492+-- | Allocates an empty pinned array that can hold 'count' items. The memory of
575−-- capacity without reallocation.
493+-- the array is uninitialized and the allocation is aligned as per the 'Unboxed'
576−{-# INLINE pinnedEmptyOf #-}
494+-- instance of the type.
577−pinnedEmptyOf :: forall m a. (MonadIO m, Unbox a) => Int -> m (MutArray a)
495+--
578−pinnedEmptyOf = newAs Pinned
580−-- XXX Deprecate in major
581−-- {-# DEPRECATED pinnedNew "Please use pinnedEmptyOf instead." #-}
582{-# INLINE pinnedNew #-}
496{-# INLINE pinnedNew #-}
583pinnedNew :: forall m a. (MonadIO m, Unbox a) => Int -> m (MutArray a)
497pinnedNew :: forall m a. (MonadIO m, Unbox a) => Int -> m (MutArray a)
584−pinnedNew = pinnedEmptyOf
498+pinnedNew = newAs Pinned
586−-- | Allocates an unpinned array of zero length but growable to the specified
500+-- | Allocates an empty unpinned array that can hold 'count' items. The memory
587−-- capacity without reallocation.
501+-- of the array is uninitialized.
589−{-# INLINE emptyOf #-}
590−emptyOf :: (MonadIO m, Unbox a) => Int -> m (MutArray a)
591−emptyOf = newAs Unpinned
593−-- XXX Deprecate in major
594−-- {-# DEPRECATED new "Please use emptyOf instead." #-}
595{-# INLINE new #-}
503{-# INLINE new #-}
596new :: (MonadIO m, Unbox a) => Int -> m (MutArray a)
504new :: (MonadIO m, Unbox a) => Int -> m (MutArray a)
597−new = emptyOf
505+new = newAs Unpinned
599-------------------------------------------------------------------------------
507-------------------------------------------------------------------------------
600-- Random writes
508-- Random writes
@@ -642,7 +550,7 @@ putIndices arr = FL.foldlM' step (return ())
645− step () (i, x) = putIndex i arr x
553+ step () (i, x) = liftIO (putIndex i arr x)
647-- | Modify a given index of an array using a modifier function.
555-- | Modify a given index of an array using a modifier function.
@@ -838,19 +746,22 @@ arrayChunkBytes = 1024
838roundDownTo :: Int -> Int -> Int
746roundDownTo :: Int -> Int -> Int
839roundDownTo elemSize size = size - (size `mod` elemSize)
747roundDownTo elemSize size = size - (size `mod` elemSize)
749+-- XXX See if resizing can be implemented by reading the old array as a stream
750+-- and then using writeN to the new array.
841-- NOTE: we are passing elemSize explicitly to avoid an Unboxed constraint.
752-- NOTE: we are passing elemSize explicitly to avoid an Unboxed constraint.
842-- Since this is not inlined Unboxed consrraint leads to dictionary passing
753-- Since this is not inlined Unboxed consrraint leads to dictionary passing
843-- which complicates some inspection tests.
754-- which complicates some inspection tests.
845−{-# NOINLINE reallocExplicitAs #-}
756+{-# NOINLINE reallocExplicit #-}
846−reallocExplicitAs :: PinnedState -> Int -> Int -> MutArray a -> IO (MutArray a)
757+reallocExplicit :: Int -> Int -> MutArray a -> IO (MutArray a)
847−reallocExplicitAs ps elemSize newCapacityInBytes MutArray{..} = do
758+reallocExplicit elemSize newCapacityInBytes MutArray{..} = do
848 assertM(arrEnd <= arrBound)
759 assertM(arrEnd <= arrBound)
850 -- Allocate new array
761 -- Allocate new array
851 let newCapMaxInBytes = roundUpLargeArray newCapacityInBytes
762 let newCapMaxInBytes = roundUpLargeArray newCapacityInBytes
852 contents <-
763 contents <-
853− if ps == Pinned
764+ if Unboxed.isPinned arrContents
854 then Unboxed.pinnedNew newCapMaxInBytes
765 then Unboxed.pinnedNew newCapMaxInBytes
855 else Unboxed.new newCapMaxInBytes
766 else Unboxed.new newCapMaxInBytes
856 let !(MutByteArray mbarrFrom#) = arrContents
767 let !(MutByteArray mbarrFrom#) = arrContents
@@ -875,10 +786,6 @@ reallocExplicitAs ps elemSize newCapacityInBytes MutArray{..} = do
875 , arrBound = newCapInBytes
786 , arrBound = newCapInBytes
878−-- XXX Should these be called reallocBytes etc?
879−-- XXX We may also need reallocAs to allocate as pinned/unpinned explicitly. In
880−-- fact clone/pinnedClone can be implemented using reallocAs.
882-- | @realloc newCapacity array@ reallocates the array to the specified
789-- | @realloc newCapacity array@ reallocates the array to the specified
883-- capacity in bytes.
790-- capacity in bytes.
@@ -890,12 +797,7 @@ reallocExplicitAs ps elemSize newCapacityInBytes MutArray{..} = do
890-- If the original array is pinned, the newly allocated array is also pinned.
797-- If the original array is pinned, the newly allocated array is also pinned.
891{-# INLINABLE realloc #-}
798{-# INLINABLE realloc #-}
892realloc :: forall m a. (MonadIO m, Unbox a) => Int -> MutArray a -> m (MutArray a)
799realloc :: forall m a. (MonadIO m, Unbox a) => Int -> MutArray a -> m (MutArray a)
898− in liftIO $ reallocExplicitAs ps (SIZE_OF(a)) bytes arr
800+realloc bytes arr = liftIO $ reallocExplicit (SIZE_OF(a)) bytes arr
900-- | @reallocWith label capSizer minIncrBytes array@. The label is used
802-- | @reallocWith label capSizer minIncrBytes array@. The label is used
901-- in error messages and the capSizer is used to determine the capacity of the
803-- in error messages and the capSizer is used to determine the capacity of the
@@ -918,14 +820,14 @@ reallocWith label capSizer minIncrBytes arr = do
920 badSize newSize =
822 badSize newSize =
921− Prelude.concat
823+ concat
923 , ": new array size (in bytes) is less than required size "
825 , ": new array size (in bytes) is less than required size "
924 , show newSize
826 , show newSize
925 , ". Please check the sizing function passed."
827 , ". Please check the sizing function passed."
928−-- | @grow newCapacity array@ changes the total capacity of the array so that
830+-- | @resize newCapacity array@ changes the total capacity of the array so that
929-- it is enough to hold the specified number of elements. Nothing is done if
831-- it is enough to hold the specified number of elements. Nothing is done if
930-- the specified capacity is less than the length of the array.
832-- the specified capacity is less than the length of the array.
@@ -933,46 +835,34 @@ reallocWith label capSizer minIncrBytes arr = do
933-- the block size (4K).
835-- the block size (4K).
935-- /Pre-release/
837-- /Pre-release/
936−{-# INLINE grow #-}
838+{-# INLINE resize #-}
937−grow :: forall m a. (MonadIO m, Unbox a) =>
839+resize :: forall m a. (MonadIO m, Unbox a) =>
938 Int -> MutArray a -> m (MutArray a)
840 Int -> MutArray a -> m (MutArray a)
939−grow nElems arr@MutArray{..} = do
841+resize nElems arr@MutArray{..} = do
940 let req = SIZE_OF(a) * nElems
842 let req = SIZE_OF(a) * nElems
941− cap = arrBound - arrStart
843+ len = arrEnd - arrStart
942− if req < cap
844+ if req < len
943 then return arr
845 then return arr
944 else realloc req arr
846 else realloc req arr
946−{-# DEPRECATED resize "Please use grow instead." #-}
947−{-# INLINE resize #-}
948−resize :: forall m a. (MonadIO m, Unbox a) =>
949− Int -> MutArray a -> m (MutArray a)
952−-- | Like 'grow' but if the requested byte capacity is more than
848+-- | Like 'resize' but if the byte capacity is more than 'largeObjectThreshold'
953−-- 'largeObjectThreshold' then it is rounded up to the closest power of 2.
849+-- then it is rounded up to the closest power of 2.
955-- /Pre-release/
851-- /Pre-release/
956−{-# INLINE growExp #-}
852+{-# INLINE resizeExp #-}
957−growExp :: forall m a. (MonadIO m, Unbox a) =>
853+resizeExp :: forall m a. (MonadIO m, Unbox a) =>
958 Int -> MutArray a -> m (MutArray a)
854 Int -> MutArray a -> m (MutArray a)
959−growExp nElems arr@MutArray{..} = do
855+resizeExp nElems arr@MutArray{..} = do
960 let req = roundUpLargeArray (SIZE_OF(a) * nElems)
856 let req = roundUpLargeArray (SIZE_OF(a) * nElems)
962 if req > largeObjectThreshold
858 if req > largeObjectThreshold
963 then roundUpToPower2 req
859 then roundUpToPower2 req
965− cap = arrBound - arrStart
861+ len = arrEnd - arrStart
966− if req1 < cap
862+ if req1 < len
967 then return arr
863 then return arr
968 else realloc req1 arr
864 else realloc req1 arr
970−{-# DEPRECATED resizeExp "Please use growExp instead." #-}
971−{-# INLINE resizeExp #-}
972−resizeExp :: forall m a. (MonadIO m, Unbox a) =>
973− Int -> MutArray a -> m (MutArray a)
976-- | Resize the allocated memory to drop any reserved free space at the end of
866-- | Resize the allocated memory to drop any reserved free space at the end of
977-- the array and reallocate it to reduce wastage.
867-- the array and reallocate it to reduce wastage.
@@ -1037,7 +927,7 @@ snocUnsafe arr@MutArray{..} = snocNewEnd (INDEX_NEXT(arrEnd,a)) arr
1037{-# INLINE snocMay #-}
927{-# INLINE snocMay #-}
1038snocMay :: forall m a. (MonadIO m, Unbox a) =>
928snocMay :: forall m a. (MonadIO m, Unbox a) =>
1039 MutArray a -> a -> m (Maybe (MutArray a))
929 MutArray a -> a -> m (Maybe (MutArray a))
1040−snocMay arr@MutArray{..} x = do
930+snocMay arr@MutArray{..} x = liftIO $ do
1041 let newEnd = INDEX_NEXT(arrEnd,a)
931 let newEnd = INDEX_NEXT(arrEnd,a)
1042 if newEnd <= arrBound
932 if newEnd <= arrBound
1043 then Just <$> snocNewEnd newEnd arr x
933 then Just <$> snocNewEnd newEnd arr x
@@ -1051,7 +941,7 @@ snocWithRealloc :: forall m a. (MonadIO m, Unbox a) =>
1052 -> m (MutArray a)
942 -> m (MutArray a)
1053snocWithRealloc sizer arr x = do
943snocWithRealloc sizer arr x = do
1054− arr1 <- reallocWith "snocWith" sizer (SIZE_OF(a)) arr
944+ arr1 <- liftIO $ reallocWith "snocWith" sizer (SIZE_OF(a)) arr
1055 snocUnsafe arr1 x
945 snocUnsafe arr1 x
1057-- | @snocWith sizer arr elem@ mutates @arr@ to append @elem@. The length of
947-- | @snocWith sizer arr elem@ mutates @arr@ to append @elem@. The length of
@@ -1073,7 +963,7 @@ snocWith :: forall m a. (MonadIO m, Unbox a) =>
1073 -> MutArray a
963 -> MutArray a
1075 -> m (MutArray a)
965 -> m (MutArray a)
1076−snocWith allocSize arr x = do
966+snocWith allocSize arr x = liftIO $ do
1077 let newEnd = INDEX_NEXT(arrEnd arr,a)
967 let newEnd = INDEX_NEXT(arrEnd arr,a)
1078 if newEnd <= arrBound arr
968 if newEnd <= arrBound arr
1079 then snocNewEnd newEnd arr x
969 then snocNewEnd newEnd arr x
@@ -1117,126 +1007,6 @@ snoc = snocWith f
1117 then oldSize * 2
1007 then oldSize * 2
1118 else roundUpToPower2 oldSize * 2
1008 else roundUpToPower2 oldSize * 2
1120−-------------------------------------------------------------------------------
1121−-- Serialization/Deserialization
1122−-------------------------------------------------------------------------------
1124−{-# INLINE pokeNewEnd #-}
1125−pokeNewEnd :: (MonadIO m, Unbox a) =>
1126− Int -> MutArray Word8 -> a -> m (MutArray Word8)
1127−pokeNewEnd newEnd arr@MutArray{..} x = liftIO $ do
1128− assert (newEnd <= arrBound) (return ())
1129− liftIO $ pokeAt arrEnd arrContents x
1130− return $ arr {arrEnd = newEnd}
1132−-- | Really really unsafe, unboxes a Haskell type and appends the resulting
1133−-- bytes to the byte array, may cause silent data corruption or if you are
1134−-- lucky a segfault if the array does not have enough space to append the
1138−{-# INLINE pokeAppendUnsafe #-}
1139−pokeAppendUnsafe :: forall m a. (MonadIO m, Unbox a) =>
1140− MutArray Word8 -> a -> m (MutArray Word8)
1141−pokeAppendUnsafe arr@MutArray{..} = pokeNewEnd (arrEnd + SIZE_OF(a)) arr
1143−-- | Skip the specified number of bytes in the array. The data in the skipped
1144−-- region remains uninitialzed.
1145−{-# INLINE pokeSkipUnsafe #-}
1146−pokeSkipUnsafe :: Int -> MutArray Word8 -> MutArray Word8
1147−pokeSkipUnsafe n arr@MutArray{..} = do
1148− let newEnd = arrEnd + n
1149− in assert (newEnd <= arrBound) (arr {arrEnd = newEnd})
1151−-- | Like 'pokeAppend' but does not grow the array when pre-allocated array
1152−-- capacity becomes full.
1155−{-# INLINE pokeAppendMay #-}
1156−pokeAppendMay :: forall m a. (MonadIO m, Unbox a) =>
1157− MutArray Word8 -> a -> m (Maybe (MutArray Word8))
1158−pokeAppendMay arr@MutArray{..} x = liftIO $ do
1159− let newEnd = arrEnd + SIZE_OF(a)
1160− if newEnd <= arrBound
1161− then Just <$> pokeNewEnd newEnd arr x
1162− else return Nothing
1164−{-# NOINLINE pokeWithRealloc #-}
1165−pokeWithRealloc :: forall m a. (MonadIO m, Unbox a) =>
1169− -> m (MutArray Word8)
1170−pokeWithRealloc sizer arr x = do
1171− arr1 <- liftIO $ reallocWith "pokeWithRealloc" sizer (SIZE_OF(a)) arr
1172− pokeAppendUnsafe arr1 x
1174−{-# INLINE pokeAppendWith #-}
1175−pokeAppendWith :: forall m a. (MonadIO m, Unbox a) =>
1179− -> m (MutArray Word8)
1180−pokeAppendWith allocSize arr x = liftIO $ do
1181− let newEnd = arrEnd arr + SIZE_OF(a)
1182− if newEnd <= arrBound arr
1183− then pokeNewEnd newEnd arr x
1184− else pokeWithRealloc allocSize arr x
1186−-- | Unbox a Haskell type and append the resulting bytes to a mutable byte
1187−-- array. The array is grown exponentially when more space is needed.
1191−-- >>> pokeAppend arr x = MutArray.castUnsafe <$> MutArray.snoc (MutArray.castUnsafe arr) x
1193−{-# INLINE pokeAppend #-}
1194−pokeAppend :: forall m a. (MonadIO m, Unbox a) =>
1195− MutArray Word8 -> a -> m (MutArray Word8)
1196−pokeAppend = pokeAppendWith f
1201− if isPower2 oldSize
1203− else roundUpToPower2 oldSize * 2
1205−-- | Really really unsafe, create a Haskell value from an unboxed byte array,
1206−-- does not check if the array is big enough, may return garbage or if you are
1207−-- lucky may cause a segfault.
1210−{-# INLINE peekUnconsUnsafe #-}
1211−peekUnconsUnsafe :: forall m a. (MonadIO m, Unbox a) =>
1212− MutArray Word8 -> m (a, MutArray Word8)
1213−peekUnconsUnsafe MutArray{..} = do
1214− let start1 = arrStart + SIZE_OF(a)
1215− assert (start1 <= arrEnd) (return ())
1217− r <- peekAt arrStart arrContents
1218− return (r, MutArray arrContents start1 arrEnd arrBound)
1220−-- | Discard the specified number of bytes in the array.
1221−{-# INLINE peekSkipUnsafe #-}
1222−peekSkipUnsafe :: Int -> MutArray Word8 -> MutArray Word8
1223−peekSkipUnsafe n MutArray{..} =
1224− let start1 = arrStart + n
1225− in assert (start1 <= arrEnd) (MutArray arrContents start1 arrEnd arrBound)
1227−-- | Create a Haskell value from its unboxed representation from the head of a
1228−-- byte array, return the value and the remaining array.
1229−{-# INLINE peekUncons #-}
1230−peekUncons :: forall m a. (MonadIO m, Unbox a) =>
1231− MutArray Word8 -> m (Maybe a, MutArray Word8)
1232−peekUncons arr@MutArray{..} = do
1233− let start1 = arrStart + SIZE_OF(a)
1235− then return (Nothing, arr)
1237− r <- peekAt arrStart arrContents
1238− return (Just r, MutArray arrContents start1 arrEnd arrBound)
1240-------------------------------------------------------------------------------
1010-------------------------------------------------------------------------------
1241-- Random reads
1011-- Random reads
1242-------------------------------------------------------------------------------
1012-------------------------------------------------------------------------------
@@ -1279,10 +1049,10 @@ getIndexRev i MutArray{..} = do
1279data GetIndicesState contents start end st =
1049data GetIndicesState contents start end st =
1280 GetIndicesState contents start end st
1050 GetIndicesState contents start end st
1282−{-# INLINE indexReaderWith #-}
1052+{-# INLINE getIndicesWith #-}
1283−indexReaderWith :: (Monad m, Unbox a) =>
1053+getIndicesWith :: (Monad m, Unbox a) =>
1284 (forall b. IO b -> m b) -> D.Stream m Int -> Unfold m (MutArray a) a
1054 (forall b. IO b -> m b) -> D.Stream m Int -> Unfold m (MutArray a) a
1285−indexReaderWith liftio (D.Stream stepi sti) = Unfold step inject
1055+getIndicesWith liftio (D.Stream stepi sti) = Unfold step inject
@@ -1301,26 +1071,14 @@ indexReaderWith liftio (D.Stream stepi sti) = Unfold step inject
1301 D.Skip s -> return $ D.Skip (GetIndicesState contents start end s)
1071 D.Skip s -> return $ D.Skip (GetIndicesState contents start end s)
1302 D.Stop -> return D.Stop
1072 D.Stop -> return D.Stop
1304−{-# DEPRECATED getIndicesWith "Please use indexReaderWith instead." #-}
1305−{-# INLINE getIndicesWith #-}
1306−getIndicesWith :: (Monad m, Unbox a) =>
1307− (forall b. IO b -> m b) -> D.Stream m Int -> Unfold m (MutArray a) a
1308−getIndicesWith = indexReaderWith
1310-- | Given an unfold that generates array indices, read the elements on those
1074-- | Given an unfold that generates array indices, read the elements on those
1311-- indices from the supplied MutArray. An error is thrown if an index is out of
1075-- indices from the supplied MutArray. An error is thrown if an index is out of
1312-- bounds.
1076-- bounds.
1314-- /Pre-release/
1078-- /Pre-release/
1315−{-# INLINE indexReader #-}
1316−indexReader :: (MonadIO m, Unbox a) => Stream m Int -> Unfold m (MutArray a) a
1317−indexReader = indexReaderWith liftIO
1319−-- XXX DO NOT REMOVE, change the signature to use Stream instead of unfold
1320−{-# DEPRECATED getIndices "Please use indexReader instead." #-}
1321{-# INLINE getIndices #-}
1079{-# INLINE getIndices #-}
1322getIndices :: (MonadIO m, Unbox a) => Stream m Int -> Unfold m (MutArray a) a
1080getIndices :: (MonadIO m, Unbox a) => Stream m Int -> Unfold m (MutArray a) a
1323−getIndices = indexReader
1081+getIndices = getIndicesWith liftIO
1325-------------------------------------------------------------------------------
1083-------------------------------------------------------------------------------
1326-- Subarrays
1084-- Subarrays
@@ -1615,7 +1373,7 @@ chunksOfAs ps n (D.Stream step state) =
1616-- Same as the following but may be more efficient:
1374-- Same as the following but may be more efficient:
1618−-- >>> chunksOf n = Stream.foldMany (MutArray.createOf n)
1376+-- >>> chunksOf n = Stream.foldMany (MutArray.writeN n)
1620-- /Pre-release/
1378-- /Pre-release/
1621{-# INLINE_NORMAL chunksOf #-}
1379{-# INLINE_NORMAL chunksOf #-}
@@ -1624,14 +1382,14 @@ chunksOf :: forall m a. (MonadIO m, Unbox a)
1624-- XXX the idiomatic implementation leads to large regression in the D.reverse'
1382-- XXX the idiomatic implementation leads to large regression in the D.reverse'
1625-- benchmark. It seems it has difficulty producing optimized code when
1383-- benchmark. It seems it has difficulty producing optimized code when
1626-- converting to StreamK. Investigate GHC optimizations.
1384-- converting to StreamK. Investigate GHC optimizations.
1627−-- chunksOf n = D.foldMany (createOf n)
1385+-- chunksOf n = D.foldMany (writeN n)
1628chunksOf = chunksOfAs Unpinned
1386chunksOf = chunksOfAs Unpinned
1630-- | Like 'chunksOf' but creates pinned arrays.
1388-- | Like 'chunksOf' but creates pinned arrays.
1631{-# INLINE_NORMAL pinnedChunksOf #-}
1389{-# INLINE_NORMAL pinnedChunksOf #-}
1632pinnedChunksOf :: forall m a. (MonadIO m, Unbox a)
1390pinnedChunksOf :: forall m a. (MonadIO m, Unbox a)
1633 => Int -> D.Stream m a -> D.Stream m (MutArray a)
1391 => Int -> D.Stream m a -> D.Stream m (MutArray a)
1634−-- pinnedChunksOf n = D.foldMany (pinnedCreateOf n)
1392+-- pinnedChunksOf n = D.foldMany (pinnedWriteN n)
1635pinnedChunksOf = chunksOfAs Pinned
1393pinnedChunksOf = chunksOfAs Pinned
1637-- | When we are buffering a stream of unknown size into an array we do not
1395-- | When we are buffering a stream of unknown size into an array we do not
@@ -1664,10 +1422,16 @@ data FlattenState s contents a =
1664 OuterLoop s
1422 OuterLoop s
1665 | InnerLoop s contents !Int !Int
1423 | InnerLoop s contents !Int !Int
1425+-- | Use the "reader" unfold instead.
1427+-- @concatChunks = unfoldMany reader@
1429+-- We can try this if there are any fusion issues in the unfold.
1667−{-# INLINE_NORMAL concatWith #-}
1431+{-# INLINE_NORMAL concatChunks #-}
1668−concatWith :: forall m a. (Monad m, Unbox a)
1432+concatChunks :: forall m a. (MonadIO m, Unbox a)
1669− => (forall b. IO b -> m b) -> D.Stream m (MutArray a) -> D.Stream m a
1433+ => D.Stream m (MutArray a) -> D.Stream m a
1670−concatWith liftio (D.Stream step state) = D.Stream step' (OuterLoop state)
1434+concatChunks (D.Stream step state) = D.Stream step' (OuterLoop state)
@@ -1684,30 +1448,24 @@ concatWith liftio (D.Stream step state) = D.Stream step' (OuterLoop state)
1684 return $ D.Skip $ OuterLoop st
1448 return $ D.Skip $ OuterLoop st
1686 step' _ (InnerLoop st contents p end) = do
1450 step' _ (InnerLoop st contents p end) = do
1687− x <- liftio $ peekAt p contents
1451+ x <- liftIO $ peekAt p contents
1688 return $ D.Yield x (InnerLoop st contents (INDEX_NEXT(p,a)) end)
1452 return $ D.Yield x (InnerLoop st contents (INDEX_NEXT(p,a)) end)
1454+{-# DEPRECATED flattenArrays "Please use \"unfoldMany reader\" instead." #-}
1455+flattenArrays :: forall m a. (MonadIO m, Unbox a)
1456+ => D.Stream m (MutArray a) -> D.Stream m a
1457+flattenArrays = concatChunks
1690−-- | Use the "reader" unfold instead.
1459+-- | Use the "readerRev" unfold instead.
1692−-- @concat = unfoldMany reader@
1461+-- @concatChunks = unfoldMany readerRev@
1694-- We can try this if there are any fusion issues in the unfold.
1463-- We can try this if there are any fusion issues in the unfold.
1696−{-# INLINE_NORMAL concat #-}
1465+{-# INLINE_NORMAL concatChunksRev #-}
1697−concat :: forall m a. (MonadIO m, Unbox a)
1698− => D.Stream m (MutArray a) -> D.Stream m a
1699−concat = concatWith liftIO
1701−{-# DEPRECATED flattenArrays "Please use \"unfoldMany reader\" instead." #-}
1702−{-# INLINE flattenArrays #-}
1703−flattenArrays :: forall m a. (MonadIO m, Unbox a)
1466+concatChunksRev :: forall m a. (MonadIO m, Unbox a)
1704 => D.Stream m (MutArray a) -> D.Stream m a
1467 => D.Stream m (MutArray a) -> D.Stream m a
1705−flattenArrays = concat
1707−{-# INLINE_NORMAL concatRevWith #-}
1708−concatRevWith :: forall m a. (Monad m, Unbox a)
1709− => (forall b. IO b -> m b) -> D.Stream m (MutArray a) -> D.Stream m a
1710−concatRevWith liftio (D.Stream step state) = D.Stream step' (OuterLoop state)
1468+concatChunksRev (D.Stream step state) = D.Stream step' (OuterLoop state)
@@ -1725,26 +1483,14 @@ concatRevWith liftio (D.Stream step state) = D.Stream step' (OuterLoop state)
1725 return $ D.Skip $ OuterLoop st
1483 return $ D.Skip $ OuterLoop st
1727 step' _ (InnerLoop st contents p start) = do
1485 step' _ (InnerLoop st contents p start) = do
1728− x <- liftio $ peekAt p contents
1486+ x <- liftIO $ peekAt p contents
1729 let cur = INDEX_PREV(p,a)
1487 let cur = INDEX_PREV(p,a)
1730 return $ D.Yield x (InnerLoop st contents cur start)
1488 return $ D.Yield x (InnerLoop st contents cur start)
1732−-- | Use the "readerRev" unfold instead.
1734−-- @concat = unfoldMany readerRev@
1736−-- We can try this if there are any fusion issues in the unfold.
1738−{-# INLINE_NORMAL concatRev #-}
1739−concatRev :: forall m a. (MonadIO m, Unbox a)
1740− => D.Stream m (MutArray a) -> D.Stream m a
1741−concatRev = concatRevWith liftIO
1743{-# DEPRECATED flattenArraysRev "Please use \"unfoldMany readerRev\" instead." #-}
1490{-# DEPRECATED flattenArraysRev "Please use \"unfoldMany readerRev\" instead." #-}
1744−{-# INLINE flattenArraysRev #-}
1745flattenArraysRev :: forall m a. (MonadIO m, Unbox a)
1491flattenArraysRev :: forall m a. (MonadIO m, Unbox a)
1746 => D.Stream m (MutArray a) -> D.Stream m a
1492 => D.Stream m (MutArray a) -> D.Stream m a
1747−flattenArraysRev = concatRev
1493+flattenArraysRev = concatChunksRev
1749-------------------------------------------------------------------------------
1495-------------------------------------------------------------------------------
1750-- Unfolds
1496-- Unfolds
@@ -1973,7 +1719,7 @@ foldr f z arr = D.foldr f z $ read arr
1974-- XXX Keep the bound intact to not lose any free space? Perf impact?
1720-- XXX Keep the bound intact to not lose any free space? Perf impact?
1976−-- | @unsafeAppendN n arr@ appends up to @n@ input items to the supplied
1722+-- | @writeAppendNUnsafe n arr@ appends up to @n@ input items to the supplied
1977-- array.
1723-- array.
1979-- Unsafe: Do not drive the fold beyond @n@ elements, it will lead to memory
1725-- Unsafe: Do not drive the fold beyond @n@ elements, it will lead to memory
@@ -1982,12 +1728,13 @@ foldr f z arr = D.foldr f z $ read arr
1982-- Any free space left in the array after appending @n@ elements is lost.
1728-- Any free space left in the array after appending @n@ elements is lost.
1984-- /Internal/
1730-- /Internal/
1985−{-# INLINE_NORMAL unsafeAppendN #-}
1731+{-# INLINE_NORMAL writeAppendNUnsafe #-}
1986−unsafeAppendN :: forall m a. (MonadIO m, Unbox a) =>
1732+writeAppendNUnsafe :: forall m a. (MonadIO m, Unbox a) =>
1988 -> m (MutArray a)
1734 -> m (MutArray a)
1989 -> Fold m a (MutArray a)
1735 -> Fold m a (MutArray a)
1736+writeAppendNUnsafe n action =
1990−unsafeAppendN n action = fmap fromArrayUnsafe $ FL.foldlM' step initial
1737+ fmap fromArrayUnsafe $ FL.foldlM' step initial
@@ -2000,7 +1747,7 @@ unsafeAppendN n action = fmap fromArrayUnsafe $ FL.foldlM' step initial
2000 -- otherwise we lose that space.
1747 -- otherwise we lose that space.
2002 if free < needed
1749 if free < needed
2003− then noinline reallocWith "unsafeAppendN" (+ needed) needed arr
1750+ then noinline reallocWith "writeAppendNUnsafeWith" (+ needed) needed arr
2004 else return arr
1751 else return arr
2005 return $ toArrayUnsafe arr1
1752 return $ toArrayUnsafe arr1
@@ -2008,51 +1755,30 @@ unsafeAppendN n action = fmap fromArrayUnsafe $ FL.foldlM' step initial
2008 liftIO $ pokeAt end contents x
1755 liftIO $ pokeAt end contents x
2009 return $ ArrayUnsafe contents start (INDEX_NEXT(end,a))
1756 return $ ArrayUnsafe contents start (INDEX_NEXT(end,a))
2011−{-# DEPRECATED writeAppendNUnsafe "Please use unsafeAppendN instead." #-}
2012−{-# INLINE writeAppendNUnsafe #-}
2013−writeAppendNUnsafe :: forall m a. (MonadIO m, Unbox a) =>
2016− -> Fold m a (MutArray a)
2017−writeAppendNUnsafe = unsafeAppendN
2019-- | Append @n@ elements to an existing array. Any free space left in the array
1758-- | Append @n@ elements to an existing array. Any free space left in the array
2020-- after appending @n@ elements is lost.
1759-- after appending @n@ elements is lost.
2022−-- >>> appendN n initial = Fold.take n (MutArray.unsafeAppendN n initial)
1761+-- >>> writeAppendN n initial = Fold.take n (MutArray.writeAppendNUnsafe n initial)
2024−{-# INLINE_NORMAL appendN #-}
1763+{-# INLINE_NORMAL writeAppendN #-}
2025−appendN :: forall m a. (MonadIO m, Unbox a) =>
2026− Int -> m (MutArray a) -> Fold m a (MutArray a)
2027−appendN n initial = FL.take n (unsafeAppendN n initial)
2029−-- XXX Deprecate in major
2030−-- {-# DEPRECATED writeAppendN "Please use appendN instead." #-}
2031−{-# INLINE writeAppendN #-}
2032writeAppendN :: forall m a. (MonadIO m, Unbox a) =>
1764writeAppendN :: forall m a. (MonadIO m, Unbox a) =>
2033 Int -> m (MutArray a) -> Fold m a (MutArray a)
1765 Int -> m (MutArray a) -> Fold m a (MutArray a)
2034−writeAppendN = appendN
1766+writeAppendN n initial = FL.take n (writeAppendNUnsafe n initial)
2036−-- | @appendWith realloc action@ mutates the array generated by @action@ to
1768+-- | @writeAppendWith realloc action@ mutates the array generated by @action@ to
2037-- append the input stream. If there is no reserved space available in the
1769-- append the input stream. If there is no reserved space available in the
2038-- array it is reallocated to a size in bytes determined by @realloc oldSize@,
1770-- array it is reallocated to a size in bytes determined by @realloc oldSize@,
2039-- where @oldSize@ is the current size of the array in bytes.
1771-- where @oldSize@ is the current size of the array in bytes.
2041-- Note that the returned array may be a mutated version of original array.
1773-- Note that the returned array may be a mutated version of original array.
2043−-- >>> appendWith sizer = Fold.foldlM' (MutArray.snocWith sizer)
1775+-- >>> writeAppendWith sizer = Fold.foldlM' (MutArray.snocWith sizer)
2045-- /Pre-release/
1777-- /Pre-release/
2046−{-# INLINE appendWith #-}
2047−appendWith :: forall m a. (MonadIO m, Unbox a) =>
2048− (Int -> Int) -> m (MutArray a) -> Fold m a (MutArray a)
2049−appendWith sizer = FL.foldlM' (snocWith sizer)
2051−{-# DEPRECATED writeAppendWith "Please use appendWith instead." #-}
2052{-# INLINE writeAppendWith #-}
1778{-# INLINE writeAppendWith #-}
2053writeAppendWith :: forall m a. (MonadIO m, Unbox a) =>
1779writeAppendWith :: forall m a. (MonadIO m, Unbox a) =>
2054 (Int -> Int) -> m (MutArray a) -> Fold m a (MutArray a)
1780 (Int -> Int) -> m (MutArray a) -> Fold m a (MutArray a)
2055−writeAppendWith = appendWith
1781+writeAppendWith sizer = FL.foldlM' (snocWith sizer)
2057-- | @append action@ mutates the array generated by @action@ to append the
1783-- | @append action@ mutates the array generated by @action@ to append the
2058-- input stream. If there is no reserved space available in the array it is
1784-- input stream. If there is no reserved space available in the array it is
@@ -2060,33 +1786,26 @@ writeAppendWith = appendWith
2061-- Note that the returned array may be a mutated version of original array.
1787-- Note that the returned array may be a mutated version of original array.
2063−-- >>> append = MutArray.appendWith (* 2)
1789+-- >>> writeAppend = MutArray.writeAppendWith (* 2)
2065−{-# INLINE append #-}
2066−append :: forall m a. (MonadIO m, Unbox a) =>
2067− m (MutArray a) -> Fold m a (MutArray a)
2068−append = appendWith (* 2)
2070−-- XXX Deprecate in major
2071−-- {-# DEPRECATED writeAppend "Please use append instead." #-}
2072{-# INLINE writeAppend #-}
1791{-# INLINE writeAppend #-}
2073writeAppend :: forall m a. (MonadIO m, Unbox a) =>
1792writeAppend :: forall m a. (MonadIO m, Unbox a) =>
2074 m (MutArray a) -> Fold m a (MutArray a)
1793 m (MutArray a) -> Fold m a (MutArray a)
2075−writeAppend = append
1794+writeAppend = writeAppendWith (* 2)
2077-- XXX We can carry bound as well in the state to make sure we do not lose the
1796-- XXX We can carry bound as well in the state to make sure we do not lose the
2078-- remaining capacity. Need to check perf impact.
1797-- remaining capacity. Need to check perf impact.
2080−-- | Like 'unsafeCreateOf' but takes a new array allocator @alloc size@
1799+-- | Like 'writeNUnsafe' but takes a new array allocator @alloc size@ function
2081−-- function as argument.
1800+-- as argument.
2083−-- >>> unsafeCreateOfWith alloc n = MutArray.unsafeAppendN (alloc n) n
1802+-- >>> writeNWithUnsafe alloc n = MutArray.writeAppendNUnsafe (alloc n) n
2085-- /Pre-release/
1804-- /Pre-release/
2086−{-# INLINE_NORMAL unsafeCreateOfWith #-}
1805+{-# INLINE_NORMAL writeNWithUnsafe #-}
2087−unsafeCreateOfWith :: forall m a. (MonadIO m, Unbox a)
1806+writeNWithUnsafe :: forall m a. (MonadIO m, Unbox a)
2088 => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
1807 => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
2089−unsafeCreateOfWith alloc n = fromArrayUnsafe <$> FL.foldlM' step initial
1808+writeNWithUnsafe alloc n = fromArrayUnsafe <$> FL.foldlM' step initial
@@ -2097,64 +1816,40 @@ unsafeCreateOfWith alloc n = fromArrayUnsafe <$> FL.foldlM' step initial
2098 $ ArrayUnsafe contents start (INDEX_NEXT(end,a))
1817 $ ArrayUnsafe contents start (INDEX_NEXT(end,a))
2100−{-# DEPRECATED writeNWithUnsafe "Please use unsafeCreateOfWith instead." #-}
2101−{-# INLINE writeNWithUnsafe #-}
2102−writeNWithUnsafe :: forall m a. (MonadIO m, Unbox a)
2103− => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
2104−writeNWithUnsafe = unsafeCreateOfWith
2106{-# INLINE_NORMAL writeNUnsafeAs #-}
1819{-# INLINE_NORMAL writeNUnsafeAs #-}
2107writeNUnsafeAs :: forall m a. (MonadIO m, Unbox a)
1820writeNUnsafeAs :: forall m a. (MonadIO m, Unbox a)
2108 => PinnedState -> Int -> Fold m a (MutArray a)
1821 => PinnedState -> Int -> Fold m a (MutArray a)
2109−writeNUnsafeAs ps = unsafeCreateOfWith (newAs ps)
1822+writeNUnsafeAs ps = writeNWithUnsafe (newAs ps)
2111−-- | Like 'createOf' but does not check the array bounds when writing. The fold
1824+-- | Like 'writeN' but does not check the array bounds when writing. The fold
2112-- driver must not call the step function more than 'n' times otherwise it will
1825-- driver must not call the step function more than 'n' times otherwise it will
2113-- corrupt the memory and crash. This function exists mainly because any
1826-- corrupt the memory and crash. This function exists mainly because any
2114-- conditional in the step function blocks fusion causing 10x performance
1827-- conditional in the step function blocks fusion causing 10x performance
2115-- slowdown.
1828-- slowdown.
2117−-- >>> unsafeCreateOf = MutArray.unsafeCreateOfWith MutArray.emptyOf
1830+-- >>> writeNUnsafe = MutArray.writeNWithUnsafe MutArray.new
2119−{-# INLINE_NORMAL unsafeCreateOf #-}
2120−unsafeCreateOf :: forall m a. (MonadIO m, Unbox a)
2121− => Int -> Fold m a (MutArray a)
2122−unsafeCreateOf = writeNUnsafeAs Unpinned
2124−{-# DEPRECATED writeNUnsafe "Please use unsafeCreateOf instead." #-}
2125−{-# INLINE writeNUnsafe #-}
1832+{-# INLINE_NORMAL writeNUnsafe #-}
2126writeNUnsafe :: forall m a. (MonadIO m, Unbox a)
1833writeNUnsafe :: forall m a. (MonadIO m, Unbox a)
2127 => Int -> Fold m a (MutArray a)
1834 => Int -> Fold m a (MutArray a)
2128−writeNUnsafe = unsafeCreateOf
1835+writeNUnsafe = writeNUnsafeAs Unpinned
2130−-- | Like 'unsafeCreateOf' but creates a pinned array.
2131−{-# INLINE_NORMAL unsafePinnedCreateOf #-}
2132−unsafePinnedCreateOf :: forall m a. (MonadIO m, Unbox a)
2133− => Int -> Fold m a (MutArray a)
2134−unsafePinnedCreateOf = writeNUnsafeAs Pinned
2136−{-# DEPRECATED pinnedWriteNUnsafe "Please use unsafePinnedCreateOf instead." #-}
1837+-- | Like 'writeNUnsafe' but creates a pinned array.
2137−{-# INLINE pinnedWriteNUnsafe #-}
1838+{-# INLINE_NORMAL pinnedWriteNUnsafe #-}
2138pinnedWriteNUnsafe :: forall m a. (MonadIO m, Unbox a)
1839pinnedWriteNUnsafe :: forall m a. (MonadIO m, Unbox a)
2139 => Int -> Fold m a (MutArray a)
1840 => Int -> Fold m a (MutArray a)
2140−pinnedWriteNUnsafe = unsafePinnedCreateOf
1841+pinnedWriteNUnsafe = writeNUnsafeAs Pinned
2142−-- | @createOfWith alloc n@ folds a maximum of @n@ elements into an array
1843+-- | @writeNWith alloc n@ folds a maximum of @n@ elements into an array
2143-- allocated using the @alloc@ function.
1844-- allocated using the @alloc@ function.
2145−-- >>> createOfWith alloc n = Fold.take n (MutArray.unsafeCreateOfWith alloc n)
1846+-- >>> writeNWith alloc n = Fold.take n (MutArray.writeNWithUnsafe alloc n)
2146−-- >>> createOfWith alloc n = MutArray.appendN (alloc n) n
1847+-- >>> writeNWith alloc n = MutArray.writeAppendN (alloc n) n
2148−{-# INLINE_NORMAL createOfWith #-}
1849+{-# INLINE_NORMAL writeNWith #-}
2149−createOfWith :: forall m a. (MonadIO m, Unbox a)
2150− => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
2151−createOfWith alloc n = FL.take n (unsafeCreateOfWith alloc n)
2153−-- {-# DEPRECATED writeNWith "Please use createOfWith instead." #-}
2154−{-# INLINE writeNWith #-}
2155writeNWith :: forall m a. (MonadIO m, Unbox a)
1850writeNWith :: forall m a. (MonadIO m, Unbox a)
2156 => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
1851 => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
2157−writeNWith = createOfWith
1852+writeNWith alloc n = FL.take n (writeNWithUnsafe alloc n)
2159{-# INLINE_NORMAL writeNAs #-}
1854{-# INLINE_NORMAL writeNAs #-}
2160writeNAs ::
1855writeNAs ::
@@ -2162,42 +1857,28 @@ writeNAs ::
2162 => PinnedState
1857 => PinnedState
2164 -> Fold m a (MutArray a)
1859 -> Fold m a (MutArray a)
2165−writeNAs ps = createOfWith (newAs ps)
1860+writeNAs ps = writeNWith (newAs ps)
2167−-- | @createOf n@ folds a maximum of @n@ elements from the input stream to an
1862+-- | @writeN n@ folds a maximum of @n@ elements from the input stream to an
2168-- 'MutArray'.
1863-- 'MutArray'.
2170−-- >>> createOf = MutArray.createOfWith MutArray.new
1865+-- >>> writeN = MutArray.writeNWith MutArray.new
2171−-- >>> createOf n = Fold.take n (MutArray.unsafeCreateOf n)
1866+-- >>> writeN n = Fold.take n (MutArray.writeNUnsafe n)
2172−-- >>> createOf n = MutArray.appendN n (MutArray.emptyOf n)
1867+-- >>> writeN n = MutArray.writeAppendN n (MutArray.new n)
2174−{-# INLINE_NORMAL createOf #-}
1869+{-# INLINE_NORMAL writeN #-}
2175−createOf :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a)
2176−createOf = writeNAs Unpinned
2178−-- XXX Deprecate in major
2179−-- {-# DEPRECATED writeN "Please use createOf instead." #-}
2180−{-# INLINE writeN #-}
2181writeN :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a)
1870writeN :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a)
2182−writeN = createOf
1871+writeN = writeNAs Unpinned
2184−-- | Like 'createOf' but creates a pinned array.
2185−{-# INLINE_NORMAL pinnedCreateOf #-}
2187− forall m a. (MonadIO m, Unbox a)
2189− -> Fold m a (MutArray a)
2190−pinnedCreateOf = writeNAs Pinned
2192−{-# DEPRECATED pinnedWriteN "Please use pinnedCreateOf instead." #-}
1873+-- | Like 'writeN' but creates a pinned array.
2193−{-# INLINE pinnedWriteN #-}
1874+{-# INLINE_NORMAL pinnedWriteN #-}
2194pinnedWriteN ::
1875pinnedWriteN ::
2195 forall m a. (MonadIO m, Unbox a)
1876 forall m a. (MonadIO m, Unbox a)
2197 -> Fold m a (MutArray a)
1878 -> Fold m a (MutArray a)
2198−pinnedWriteN = pinnedCreateOf
1879+pinnedWriteN = writeNAs Pinned
2200−-- | Like unsafeCreateOfWith but writes the array in reverse order.
1881+-- | Like writeNWithUnsafe but writes the array in reverse order.
2202-- /Internal/
1883-- /Internal/
2203{-# INLINE_NORMAL writeRevNWithUnsafe #-}
1884{-# INLINE_NORMAL writeRevNWithUnsafe #-}
@@ -2218,7 +1899,7 @@ writeRevNWithUnsafe alloc n = fromArrayUnsafe <$> FL.foldlM' step initial
2219 $ ArrayUnsafe contents ptr end
1900 $ ArrayUnsafe contents ptr end
2221−-- | Like createOfWith but writes the array in reverse order.
1902+-- | Like writeNWith but writes the array in reverse order.
2223-- /Internal/
1904-- /Internal/
2224{-# INLINE_NORMAL writeRevNWith #-}
1905{-# INLINE_NORMAL writeRevNWith #-}
@@ -2226,36 +1907,31 @@ writeRevNWith :: forall m a. (MonadIO m, Unbox a)
2226 => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
1907 => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a)
2227writeRevNWith alloc n = FL.take n (writeRevNWithUnsafe alloc n)
1908writeRevNWith alloc n = FL.take n (writeRevNWithUnsafe alloc n)
2229−-- | Like 'createOf' but writes the array in reverse order.
1910+-- | Like writeN but writes the array in reverse order.
2231-- /Pre-release/
1912-- /Pre-release/
2232−{-# INLINE_NORMAL revCreateOf #-}
1913+{-# INLINE_NORMAL writeRevN #-}
2233−revCreateOf :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a)
2234−revCreateOf = writeRevNWith new
2236−{-# DEPRECATED writeRevN "Please use revCreateOf instead." #-}
2237−{-# INLINE writeRevN #-}
2238writeRevN :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a)
1914writeRevN :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a)
2239−writeRevN = revCreateOf
1915+writeRevN = writeRevNWith new
2241-- | @pinnedWriteNAligned align n@ folds a maximum of @n@ elements from the
1917-- | @pinnedWriteNAligned align n@ folds a maximum of @n@ elements from the
2242-- input stream to a 'MutArray' aligned to the given size.
1918-- input stream to a 'MutArray' aligned to the given size.
2244−-- >>> pinnedWriteNAligned align = MutArray.createOfWith (MutArray.pinnedNewAligned align)
1920+-- >>> pinnedWriteNAligned align = MutArray.writeNWith (MutArray.pinnedNewAligned align)
2245−-- >>> pinnedWriteNAligned align n = MutArray.appendN n (MutArray.pinnedNewAligned align n)
1921+-- >>> pinnedWriteNAligned align n = MutArray.writeAppendN n (MutArray.pinnedNewAligned align n)
2247-- /Pre-release/
1923-- /Pre-release/
2249{-# INLINE_NORMAL pinnedWriteNAligned #-}
1925{-# INLINE_NORMAL pinnedWriteNAligned #-}
2250pinnedWriteNAligned :: forall m a. (MonadIO m, Unbox a)
1926pinnedWriteNAligned :: forall m a. (MonadIO m, Unbox a)
2251 => Int -> Int -> Fold m a (MutArray a)
1927 => Int -> Int -> Fold m a (MutArray a)
2252−pinnedWriteNAligned align = createOfWith (pinnedNewAligned align)
1928+pinnedWriteNAligned align = writeNWith (pinnedNewAligned align)
2254-- XXX Buffer to a list instead?
1930-- XXX Buffer to a list instead?
2256-- | Buffer a stream into a stream of arrays.
1932-- | Buffer a stream into a stream of arrays.
2258−-- >>> buildChunks n = Fold.many (MutArray.createOf n) Fold.toStreamK
1934+-- >>> buildChunks n = Fold.many (MutArray.writeN n) Fold.toStreamK
2260-- Breaking an array into an array stream can be useful to consume a large
1936-- Breaking an array into an array stream can be useful to consume a large
2261-- array sequentially such that memory of the array is released incrementatlly.
1937-- array sequentially such that memory of the array is released incrementatlly.
@@ -2267,10 +1943,9 @@ pinnedWriteNAligned align = createOfWith (pinnedNewAligned align)
2267{-# INLINE_NORMAL buildChunks #-}
1943{-# INLINE_NORMAL buildChunks #-}
2268buildChunks :: (MonadIO m, Unbox a) =>
1944buildChunks :: (MonadIO m, Unbox a) =>
2269 Int -> Fold m a (StreamK n (MutArray a))
1945 Int -> Fold m a (StreamK n (MutArray a))
2270−buildChunks n = FL.many (createOf n) FL.toStreamK
1946+buildChunks n = FL.many (writeN n) FL.toStreamK
2272{-# DEPRECATED writeChunks "Please use buildChunks instead." #-}
1948{-# DEPRECATED writeChunks "Please use buildChunks instead." #-}
2273−{-# INLINE writeChunks #-}
2274writeChunks :: (MonadIO m, Unbox a) =>
1949writeChunks :: (MonadIO m, Unbox a) =>
2275 Int -> Fold m a (StreamK n (MutArray a))
1950 Int -> Fold m a (StreamK n (MutArray a))
2276writeChunks = buildChunks
1951writeChunks = buildChunks
@@ -2278,29 +1953,29 @@ writeChunks = buildChunks
2278{-# INLINE_NORMAL writeWithAs #-}
1953{-# INLINE_NORMAL writeWithAs #-}
2279writeWithAs :: forall m a. (MonadIO m, Unbox a)
1954writeWithAs :: forall m a. (MonadIO m, Unbox a)
2280 => PinnedState -> Int -> Fold m a (MutArray a)
1955 => PinnedState -> Int -> Fold m a (MutArray a)
2281−-- writeWithAs ps n = FL.rmapM rightSize $ appendWith (* 2) (newAs ps n)
1956+-- writeWithAs ps n = FL.rmapM rightSize $ writeAppendWith (* 2) (newAs ps n)
2282writeWithAs ps elemCount =
1957writeWithAs ps elemCount =
2283 FL.rmapM extract $ FL.foldlM' step initial
1958 FL.rmapM extract $ FL.foldlM' step initial
2287 initial = do
1962 initial = do
2288− when (elemCount < 0) $ error "createWith: elemCount is negative"
1963+ when (elemCount < 0) $ error "writeWith: elemCount is negative"
2289− newAs ps elemCount
1964+ liftIO $ newAs ps elemCount
2291 step arr@(MutArray _ start end bound) x
1966 step arr@(MutArray _ start end bound) x
2292 | INDEX_NEXT(end,a) > bound = do
1967 | INDEX_NEXT(end,a) > bound = do
2293 let oldSize = end - start
1968 let oldSize = end - start
2294 newSize = max (oldSize * 2) 1
1969 newSize = max (oldSize * 2) 1
2295− arr1 <- liftIO $ reallocExplicitAs ps (SIZE_OF(a)) newSize arr
1970+ arr1 <- liftIO $ reallocExplicit (SIZE_OF(a)) newSize arr
2296 snocUnsafe arr1 x
1971 snocUnsafe arr1 x
2297 step arr x = snocUnsafe arr x
1972 step arr x = snocUnsafe arr x
2299 extract = liftIO . rightSize
1974 extract = liftIO . rightSize
2301−-- XXX Compare createWith with fromStreamD which uses an array of streams
1976+-- XXX Compare writeWith with fromStreamD which uses an array of streams
2302-- implementation. We can write this using buildChunks above if that is faster.
1977-- implementation. We can write this using buildChunks above if that is faster.
2303−-- If createWith is faster then we should use that to implement
1978+-- If writeWith is faster then we should use that to implement
2304-- fromStreamD.
1979-- fromStreamD.
2306-- XXX The realloc based implementation needs to make one extra copy if we use
1981-- XXX The realloc based implementation needs to make one extra copy if we use
@@ -2315,56 +1990,39 @@ writeWithAs ps elemCount =
2315-- XXX check if GHC's memory allocator is efficient enough. We can try the C
1990-- XXX check if GHC's memory allocator is efficient enough. We can try the C
2316-- malloc to compare against.
1991-- malloc to compare against.
2318−-- | @createWith minCount@ folds the whole input to a single array. The array
1993+-- | @writeWith minCount@ folds the whole input to a single array. The array
2319-- starts at a size big enough to hold minCount elements, the size is doubled
1994-- starts at a size big enough to hold minCount elements, the size is doubled
2320-- every time the array needs to be grown.
1995-- every time the array needs to be grown.
2322-- /Caution! Do not use this on infinite streams./
1997-- /Caution! Do not use this on infinite streams./
2324−-- >>> f n = MutArray.appendWith (* 2) (MutArray.emptyOf n)
1999+-- >>> f n = MutArray.writeAppendWith (* 2) (MutArray.new n)
2325−-- >>> createWith n = Fold.rmapM MutArray.rightSize (f n)
2000+-- >>> writeWith n = Fold.rmapM MutArray.rightSize (f n)
2326−-- >>> createWith n = Fold.rmapM MutArray.fromChunksK (MutArray.buildChunks n)
2001+-- >>> writeWith n = Fold.rmapM MutArray.fromChunksK (MutArray.buildChunks n)
2328-- /Pre-release/
2003-- /Pre-release/
2329−{-# INLINE_NORMAL createWith #-}
2004+{-# INLINE_NORMAL writeWith #-}
2330−createWith :: forall m a. (MonadIO m, Unbox a)
2331− => Int -> Fold m a (MutArray a)
2332−-- createWith n = FL.rmapM rightSize $ appendWith (* 2) (emptyOf n)
2333−createWith = writeWithAs Unpinned
2335−{-# DEPRECATED writeWith "Please use createWith instead." #-}
2336−{-# INLINE writeWith #-}
2337writeWith :: forall m a. (MonadIO m, Unbox a)
2005writeWith :: forall m a. (MonadIO m, Unbox a)
2338 => Int -> Fold m a (MutArray a)
2006 => Int -> Fold m a (MutArray a)
2339−writeWith = createWith
2007+-- writeWith n = FL.rmapM rightSize $ writeAppendWith (* 2) (new n)
2008+writeWith = writeWithAs Unpinned
2341-- | Fold the whole input to a single array.
2010-- | Fold the whole input to a single array.
2343−-- Same as 'createWith' using an initial array size of 'arrayChunkBytes' bytes
2012+-- Same as 'writeWith' using an initial array size of 'arrayChunkBytes' bytes
2344-- rounded up to the element size.
2013-- rounded up to the element size.
2346-- /Caution! Do not use this on infinite streams./
2015-- /Caution! Do not use this on infinite streams./
2348−{-# INLINE create #-}
2349−create :: forall m a. (MonadIO m, Unbox a) => Fold m a (MutArray a)
2350−create = createWith (allocBytesToElemCount (undefined :: a) arrayChunkBytes)
2352−-- XXX Deprecate in major
2353−-- {-# DEPRECATED write "Please use create instead." #-}
2354{-# INLINE write #-}
2017{-# INLINE write #-}
2355write :: forall m a. (MonadIO m, Unbox a) => Fold m a (MutArray a)
2018write :: forall m a. (MonadIO m, Unbox a) => Fold m a (MutArray a)
2356−write = create
2019+write = writeWith (allocBytesToElemCount (undefined :: a) arrayChunkBytes)
2358−-- | Like 'create' but creates a pinned array.
2021+-- | Like 'write' but creates a pinned array.
2359−{-# INLINE pinnedCreate #-}
2360−pinnedCreate :: forall m a. (MonadIO m, Unbox a) => Fold m a (MutArray a)
2362− writeWithAs Pinned (allocBytesToElemCount (undefined :: a) arrayChunkBytes)
2364−{-# DEPRECATED pinnedWrite "Please use pinnedCreate instead." #-}
2365{-# INLINE pinnedWrite #-}
2022{-# INLINE pinnedWrite #-}
2366pinnedWrite :: forall m a. (MonadIO m, Unbox a) => Fold m a (MutArray a)
2023pinnedWrite :: forall m a. (MonadIO m, Unbox a) => Fold m a (MutArray a)
2367−pinnedWrite = pinnedCreate
2024+pinnedWrite =
2025+ writeWithAs Pinned (allocBytesToElemCount (undefined :: a) arrayChunkBytes)
2369-------------------------------------------------------------------------------
2027-------------------------------------------------------------------------------
2370-- construct from streams, known size
2028-- construct from streams, known size
@@ -2374,7 +2032,7 @@ pinnedWrite = pinnedCreate
2374fromStreamDNAs :: forall m a. (MonadIO m, Unbox a)
2032fromStreamDNAs :: forall m a. (MonadIO m, Unbox a)
2375 => PinnedState -> Int -> D.Stream m a -> m (MutArray a)
2033 => PinnedState -> Int -> D.Stream m a -> m (MutArray a)
2376fromStreamDNAs ps limit str = do
2034fromStreamDNAs ps limit str = do
2377− (arr :: MutArray a) <- newAs ps limit
2035+ (arr :: MutArray a) <- liftIO $ newAs ps limit
2378 end <- D.foldlM' (fwrite (arrContents arr)) (return $ arrEnd arr) $ D.take limit str
2036 end <- D.foldlM' (fwrite (arrContents arr)) (return $ arrEnd arr) $ D.take limit str
2379 return $ arr {arrEnd = end}
2037 return $ arr {arrEnd = end}
@@ -2384,18 +2042,17 @@ fromStreamDNAs ps limit str = do
2384 liftIO $ pokeAt ptr arrContents x
2042 liftIO $ pokeAt ptr arrContents x
2385 return $ INDEX_NEXT(ptr,a)
2043 return $ INDEX_NEXT(ptr,a)
2387−-- | Use the 'createOf' fold instead.
2045+-- | Use the 'writeN' fold instead.
2389−-- >>> fromStreamN n = Stream.fold (MutArray.createOf n)
2047+-- >>> fromStreamN n = Stream.fold (MutArray.writeN n)
2391{-# INLINE_NORMAL fromStreamN #-}
2049{-# INLINE_NORMAL fromStreamN #-}
2392fromStreamN :: forall m a. (MonadIO m, Unbox a)
2050fromStreamN :: forall m a. (MonadIO m, Unbox a)
2393 => Int -> D.Stream m a -> m (MutArray a)
2051 => Int -> D.Stream m a -> m (MutArray a)
2394−-- fromStreamDN n = D.fold (createOf n)
2052+-- fromStreamDN n = D.fold (writeN n)
2395fromStreamN = fromStreamDNAs Unpinned
2053fromStreamN = fromStreamDNAs Unpinned
2397{-# DEPRECATED fromStreamDN "Please use fromStreamN instead." #-}
2055{-# DEPRECATED fromStreamDN "Please use fromStreamN instead." #-}
2398−{-# INLINE fromStreamDN #-}
2399fromStreamDN :: forall m a. (MonadIO m, Unbox a)
2056fromStreamDN :: forall m a. (MonadIO m, Unbox a)
2400 => Int -> D.Stream m a -> m (MutArray a)
2057 => Int -> D.Stream m a -> m (MutArray a)
2401fromStreamDN = fromStreamN
2058fromStreamDN = fromStreamN
@@ -2418,20 +2075,20 @@ pinnedFromListN n xs = fromStreamDNAs Pinned n $ D.fromList xs
2418-- /Pre-release/
2075-- /Pre-release/
2419{-# INLINE fromListRevN #-}
2076{-# INLINE fromListRevN #-}
2420fromListRevN :: (MonadIO m, Unbox a) => Int -> [a] -> m (MutArray a)
2077fromListRevN :: (MonadIO m, Unbox a) => Int -> [a] -> m (MutArray a)
2421−fromListRevN n xs = D.fold (revCreateOf n) $ D.fromList xs
2078+fromListRevN n xs = D.fold (writeRevN n) $ D.fromList xs
2423-- | Convert a pure stream in Identity monad to a mutable array.
2080-- | Convert a pure stream in Identity monad to a mutable array.
2424{-# INLINABLE fromPureStreamN #-}
2081{-# INLINABLE fromPureStreamN #-}
2425fromPureStreamN :: (MonadIO m, Unbox a) =>
2082fromPureStreamN :: (MonadIO m, Unbox a) =>
2426 Int -> Stream Identity a -> m (MutArray a)
2083 Int -> Stream Identity a -> m (MutArray a)
2427fromPureStreamN n xs =
2084fromPureStreamN n xs =
2428− D.fold (createOf n) $ D.morphInner (return . runIdentity) xs
2085+ liftIO $ D.fold (writeN n) $ D.morphInner (return . runIdentity) xs
2430-- | Convert a pure stream in Identity monad to a mutable array.
2087-- | Convert a pure stream in Identity monad to a mutable array.
2431{-# INLINABLE fromPureStream #-}
2088{-# INLINABLE fromPureStream #-}
2432fromPureStream :: (MonadIO m, Unbox a) => Stream Identity a -> m (MutArray a)
2089fromPureStream :: (MonadIO m, Unbox a) => Stream Identity a -> m (MutArray a)
2433fromPureStream xs =
2090fromPureStream xs =
2434− D.fold create $ D.morphInner (return . runIdentity) xs
2091+ liftIO $ D.fold write $ D.morphInner (return . runIdentity) xs
2436{-# INLINABLE fromPtrN #-}
2093{-# INLINABLE fromPtrN #-}
2437fromPtrN :: MonadIO m => Int -> Ptr Word8 -> m (MutArray Word8)
2094fromPtrN :: MonadIO m => Int -> Ptr Word8 -> m (MutArray Word8)
@@ -2440,7 +2097,7 @@ fromPtrN len addr = do
2440 -- XXX We can implement a stream copy in a similar way by streaming Word64
2097 -- XXX We can implement a stream copy in a similar way by streaming Word64
2441 -- first and then remaining Word8.
2098 -- first and then remaining Word8.
2442 arr <- new len
2099 arr <- new len
2443− _ <- unsafeAsPtr arr
2100+ _ <- asUnpinnedPtrUnsafe arr
2444 (\ptr -> liftIO $ c_memcpy ptr addr (fromIntegral len))
2101 (\ptr -> liftIO $ c_memcpy ptr addr (fromIntegral len))
2445 return (arr {arrEnd = len})
2102 return (arr {arrEnd = len})
@@ -2456,7 +2113,7 @@ fromByteStr# addr = do
2456 len <- liftIO $ c_strlen (Ptr addr)
2113 len <- liftIO $ c_strlen (Ptr addr)
2457 let lenInt = fromIntegral len
2114 let lenInt = fromIntegral len
2458 arr <- new lenInt
2115 arr <- new lenInt
2459− _ <- unsafeAsPtr arr (\ptr -> liftIO $ c_memcpy ptr (Ptr addr) len)
2116+ _ <- asUnpinnedPtrUnsafe arr (\ptr -> liftIO $ c_memcpy ptr (Ptr addr) len)
2460 return (arr {arrEnd = lenInt})
2117 return (arr {arrEnd = lenInt})
2462-------------------------------------------------------------------------------
2119-------------------------------------------------------------------------------
@@ -2477,7 +2134,7 @@ fromChunksRealloced s = do
2477 arr <- D.foldlM' spliceExp (pure a) strm
2134 arr <- D.foldlM' spliceExp (pure a) strm
2478 -- Reallocation is exponential so there may be 50% empty space in
2135 -- Reallocation is exponential so there may be 50% empty space in
2479 -- worst case. One more reallocation to reclaim the space.
2136 -- worst case. One more reallocation to reclaim the space.
2480− rightSize arr
2137+ liftIO $ rightSize arr
2481 Nothing -> pure nil
2138 Nothing -> pure nil
2483-------------------------------------------------------------------------------
2140-------------------------------------------------------------------------------
@@ -2515,7 +2172,6 @@ fromChunksK :: (Unbox a, MonadIO m) =>
2515fromChunksK = fromChunkskAs Unpinned
2172fromChunksK = fromChunkskAs Unpinned
2517{-# DEPRECATED fromArrayStreamK "Please use fromChunksK instead." #-}
2174{-# DEPRECATED fromArrayStreamK "Please use fromChunksK instead." #-}
2518−{-# INLINE fromArrayStreamK #-}
2519fromArrayStreamK :: (Unbox a, MonadIO m) =>
2175fromArrayStreamK :: (Unbox a, MonadIO m) =>
2520 StreamK m (MutArray a) -> m (MutArray a)
2176 StreamK m (MutArray a) -> m (MutArray a)
2521fromArrayStreamK = fromChunksK
2177fromArrayStreamK = fromChunksK
@@ -2527,7 +2183,7 @@ fromStreamDAs ps m =
2527 arrayStreamKFromStreamDAs Unpinned m >>= fromChunkskAs ps
2183 arrayStreamKFromStreamDAs Unpinned m >>= fromChunkskAs ps
2529-- | Create an 'Array' from a stream. This is useful when we want to create a
2185-- | Create an 'Array' from a stream. This is useful when we want to create a
2530−-- single array from a stream of unknown size. 'createOf' is at least twice
2186+-- single array from a stream of unknown size. 'writeN' is at least twice
2531-- as efficient when the size is already known.
2187-- as efficient when the size is already known.
2533-- Note that if the input stream is too large memory allocation for the array
2189-- Note that if the input stream is too large memory allocation for the array
@@ -2539,19 +2195,19 @@ fromStreamDAs ps m =
2539fromStream :: (MonadIO m, Unbox a) => Stream m a -> m (MutArray a)
2195fromStream :: (MonadIO m, Unbox a) => Stream m a -> m (MutArray a)
2540fromStream = fromStreamDAs Unpinned
2196fromStream = fromStreamDAs Unpinned
2542−-- fromStream (Stream m) = P.fold create m
2198+-- fromStream (Stream m) = P.fold write m
2543-- CAUTION: a very large number (millions) of arrays can degrade performance
2199-- CAUTION: a very large number (millions) of arrays can degrade performance
2544-- due to GC overhead because we need to buffer the arrays before we flatten
2200-- due to GC overhead because we need to buffer the arrays before we flatten
2545-- all the arrays.
2201-- all the arrays.
2547−-- XXX Compare if this is faster or "fold create".
2203+-- XXX Compare if this is faster or "fold write".
2549-- | We could take the approach of doubling the memory allocation on each
2205-- | We could take the approach of doubling the memory allocation on each
2550-- overflow. This would result in more or less the same amount of copying as in
2206-- overflow. This would result in more or less the same amount of copying as in
2551-- the chunking approach. However, if we have to shrink in the end then it may
2207-- the chunking approach. However, if we have to shrink in the end then it may
2552-- result in an extra copy of the entire data.
2208-- result in an extra copy of the entire data.
2554−-- >>> fromStreamD = StreamD.fold MutArray.create
2210+-- >>> fromStreamD = StreamD.fold MutArray.write
2556{-# INLINE fromStreamD #-}
2212{-# INLINE fromStreamD #-}
2557{-# DEPRECATED fromStreamD "Please use fromStream instead." #-}
2213{-# DEPRECATED fromStreamD "Please use fromStream instead." #-}
@@ -2581,10 +2237,6 @@ fromListRev xs = fromListRevN (Prelude.length xs) xs
2581-- Cloning
2237-- Cloning
2582-------------------------------------------------------------------------------
2238-------------------------------------------------------------------------------
2584−-- Arrays are aligned on 64-bit boundaries. The fastest way to copy an array is
2585−-- to unsafeCast it to Word64, read it, write it to Word64 array and unsafeCast
2586−-- it again. We can use SIMD read/write as well.
2588{-# INLINE cloneAs #-}
2240{-# INLINE cloneAs #-}
2589cloneAs ::
2241cloneAs ::
2590 ( MonadIO m
2242 ( MonadIO m
@@ -2594,7 +2246,7 @@ cloneAs ::
2595 => PinnedState -> MutArray a -> m (MutArray a)
2247 => PinnedState -> MutArray a -> m (MutArray a)
2596cloneAs ps src =
2248cloneAs ps src =
2597− do
2249+ liftIO $ do
2598 let startSrc = arrStart src
2250 let startSrc = arrStart src
2599 srcLen = arrEnd src - startSrc
2251 srcLen = arrEnd src - startSrc
2600 newArrContents <-
2252 newArrContents <-
@@ -2633,16 +2285,17 @@ spliceCopy :: forall m a. MonadIO m =>
2633 Unbox a =>
2285 Unbox a =>
2635 MutArray a -> MutArray a -> m (MutArray a)
2287 MutArray a -> MutArray a -> m (MutArray a)
2636−spliceCopy arr1 arr2 = do
2288+spliceCopy arr1 arr2 = liftIO $ do
2637 let start1 = arrStart arr1
2289 let start1 = arrStart arr1
2638 start2 = arrStart arr2
2290 start2 = arrStart arr2
2639 len1 = arrEnd arr1 - start1
2291 len1 = arrEnd arr1 - start1
2640 len2 = arrEnd arr2 - start2
2292 len2 = arrEnd arr2 - start2
2641− let len = len1 + len2
2293+ let newLen = len1 + len2
2642 newArrContents <-
2294 newArrContents <-
2643 if Unboxed.isPinned (arrContents arr1)
2295 if Unboxed.isPinned (arrContents arr1)
2644− then liftIO $ Unboxed.pinnedNew len
2296+ then Unboxed.pinnedNew newLen
2645− else liftIO $ Unboxed.new len
2297+ else Unboxed.new newLen
2298+ let len = len1 + len2
2646 putSliceUnsafe (arrContents arr1) start1 newArrContents 0 len1
2299 putSliceUnsafe (arrContents arr1) start1 newArrContents 0 len1
2647 putSliceUnsafe (arrContents arr2) start2 newArrContents len1 len2
2300 putSliceUnsafe (arrContents arr2) start2 newArrContents len1 len2
2648 return $ MutArray newArrContents 0 len len
2301 return $ MutArray newArrContents 0 len len
@@ -2654,7 +2307,7 @@ spliceCopy arr1 arr2 = do
2654spliceUnsafe :: MonadIO m =>
2307spliceUnsafe :: MonadIO m =>
2655 MutArray a -> MutArray a -> m (MutArray a)
2308 MutArray a -> MutArray a -> m (MutArray a)
2656spliceUnsafe dst src =
2309spliceUnsafe dst src =
2657− do
2310+ liftIO $ do
2658 let startSrc = arrStart src
2311 let startSrc = arrStart src
2659 srcLen = arrEnd src - startSrc
2312 srcLen = arrEnd src - startSrc
2660 endDst = arrEnd dst
2313 endDst = arrEnd dst
@@ -2676,7 +2329,7 @@ spliceWith :: forall m a. (MonadIO m, Unbox a) =>
2676 (Int -> Int -> Int) -> MutArray a -> MutArray a -> m (MutArray a)
2329 (Int -> Int -> Int) -> MutArray a -> MutArray a -> m (MutArray a)
2677spliceWith sizer dst@(MutArray _ start end bound) src = do
2330spliceWith sizer dst@(MutArray _ start end bound) src = do
2679− let f = appendWith (`sizer` byteLength src) (return dst)
2332+ let f = writeAppendWith (`sizer` byteLength src) (return dst)
2680 in D.fold f (toStreamD src)
2333 in D.fold f (toStreamD src)
2682 assert (end <= bound) (return ())
2335 assert (end <= bound) (return ())
@@ -2692,7 +2345,7 @@ spliceWith sizer dst@(MutArray _ start end bound) src = do
2692 $ "splice: newSize is less than the total size "
2345 $ "splice: newSize is less than the total size "
2693 ++ "of arrays being appended. Please check the "
2346 ++ "of arrays being appended. Please check the "
2694 ++ "sizer function passed."
2347 ++ "sizer function passed."
2695− realloc newSizeInBytes dst
2348+ liftIO $ realloc newSizeInBytes dst
2696 else return dst
2349 else return dst
2697 spliceUnsafe dst1 src
2350 spliceUnsafe dst1 src
@@ -2744,7 +2397,7 @@ splitOn predicate arr =
2744{-# INLINE breakOn #-}
2397{-# INLINE breakOn #-}
2745breakOn :: MonadIO m
2398breakOn :: MonadIO m
2746 => Word8 -> MutArray Word8 -> m (MutArray Word8, Maybe (MutArray Word8))
2399 => Word8 -> MutArray Word8 -> m (MutArray Word8, Maybe (MutArray Word8))
2747−breakOn sep arr@MutArray{..} = unsafeAsPtr arr $ \p -> liftIO $ do
2400+breakOn sep arr@MutArray{..} = asUnpinnedPtrUnsafe arr $ \p -> liftIO $ do
2748 -- XXX We do not need memchr here, we can use a Haskell equivalent.
2401 -- XXX We do not need memchr here, we can use a Haskell equivalent.
2749 -- Need efficient stream based primitives that work on Word64.
2402 -- Need efficient stream based primitives that work on Word64.
2750 loc <- c_memchr p sep (fromIntegral $ byteLength arr)
2403 loc <- c_memchr p sep (fromIntegral $ byteLength arr)
@@ -2767,41 +2420,32 @@ breakOn sep arr@MutArray{..} = unsafeAsPtr arr $ \p -> liftIO $ do
2770−-- | Like 'splitAt' but does not check whether the index is valid.
2772−{-# INLINE unsafeSplitAt #-}
2773−unsafeSplitAt :: forall a. Unbox a =>
2774− Int -> MutArray a -> (MutArray a, MutArray a)
2775−unsafeSplitAt i MutArray{..} =
2776− let off = i * SIZE_OF(a)
2779− { arrContents = arrContents
2780− , arrStart = arrStart
2785− { arrContents = arrContents
2788− , arrBound = arrBound
2792-- | Create two slices of an array without copying the original array. The
2423-- | Create two slices of an array without copying the original array. The
2793-- specified index @i@ is the first index of the second slice.
2424-- specified index @i@ is the first index of the second slice.
2795−{-# INLINE splitAt #-}
2796splitAt :: forall a. Unbox a => Int -> MutArray a -> (MutArray a, MutArray a)
2426splitAt :: forall a. Unbox a => Int -> MutArray a -> (MutArray a, MutArray a)
2797−splitAt i arr =
2427+splitAt i arr@MutArray{..} =
2798 let maxIndex = length arr - 1
2428 let maxIndex = length arr - 1
2799 in if i < 0
2429 in if i < 0
2800 then error "sliceAt: negative array index"
2430 then error "sliceAt: negative array index"
2801 else if i > maxIndex
2431 else if i > maxIndex
2802 then error $ "sliceAt: specified array index " ++ show i
2432 then error $ "sliceAt: specified array index " ++ show i
2803 ++ " is beyond the maximum index " ++ show maxIndex
2433 ++ " is beyond the maximum index " ++ show maxIndex
2804− else unsafeSplitAt i arr
2434+ else let off = i * SIZE_OF(a)
2437+ { arrContents = arrContents
2438+ , arrStart = arrStart
2443+ { arrContents = arrContents
2446+ , arrBound = arrBound
2806-------------------------------------------------------------------------------
2450-------------------------------------------------------------------------------
2807-- Casting
2451-- Casting
@@ -2851,13 +2495,9 @@ cast arr =
2851-- guarantees that unsafe calls will be performed in the calling thread. Making
2495-- guarantees that unsafe calls will be performed in the calling thread. Making
2852-- it safe to pass heap-allocated objects to unsafe functions.
2496-- it safe to pass heap-allocated objects to unsafe functions.
2854−-- XXX Should we just name it asPtr, the unsafety is implicit for any pointer
2498+-- Should we just name it asPtr, the unsafety is implicit for any pointer
2855-- operations. And we are safe from Haskell perspective because we will be
2499-- operations. And we are safe from Haskell perspective because we will be
2856-- pinning the memory.
2500-- pinning the memory.
2858−-- XXX we cannot pass the length of the ptr here as in some cases it may not be
2859−-- available e.g. a null terminated C string. However, we can create another
2860−-- flavor of the API e.g. asPtrN.
2862-- | Use a @MutArray a@ as @Ptr a@. This is useful when we want to pass an
2502-- | Use a @MutArray a@ as @Ptr a@. This is useful when we want to pass an
2863-- array as a pointer to some operating system call or to a "safe" FFI call.
2503-- array as a pointer to some operating system call or to a "safe" FFI call.
@@ -2875,21 +2515,16 @@ cast arr =
2876-- /Pre-release/
2516-- /Pre-release/
2878−{-# INLINE unsafePinnedAsPtr #-}
2879−unsafePinnedAsPtr :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b
2880−unsafePinnedAsPtr arr f =
2881− Unboxed.unsafePinnedAsPtr
2882− (arrContents arr) (\ptr -> f (ptr `plusPtr` arrStart arr))
2884−{-# DEPRECATED asPtrUnsafe "Please use unsafePinnedAsPtr instead." #-}
2885{-# INLINE asPtrUnsafe #-}
2518{-# INLINE asPtrUnsafe #-}
2886asPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b
2519asPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b
2887−asPtrUnsafe = unsafePinnedAsPtr
2520+asPtrUnsafe arr f =
2521+ Unboxed.asPtrUnsafe
2522+ (arrContents arr) (\ptr -> f (ptr `plusPtr` arrStart arr))
2889−{-# INLINE unsafeAsPtr #-}
2524+{-# INLINE asUnpinnedPtrUnsafe #-}
2890−unsafeAsPtr :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b
2525+asUnpinnedPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b
2891−unsafeAsPtr arr f =
2526+asUnpinnedPtrUnsafe arr f =
2892− Unboxed.unsafeAsPtr
2527+ Unboxed.asUnpinnedPtrUnsafe
2893 (arrContents arr) (\ptr -> f (ptr `plusPtr` arrStart arr))
2528 (arrContents arr) (\ptr -> f (ptr `plusPtr` arrStart arr))
2895-------------------------------------------------------------------------------
2530-------------------------------------------------------------------------------
@@ -2907,26 +2542,28 @@ unsafeAsPtr arr f =
2907-- /Pre-release/
2542-- /Pre-release/
2908{-# INLINE byteCmp #-}
2543{-# INLINE byteCmp #-}
2909byteCmp :: MonadIO m => MutArray a -> MutArray a -> m Ordering
2544byteCmp :: MonadIO m => MutArray a -> MutArray a -> m Ordering
2910−byteCmp arr1 arr2 = do
2545+byteCmp arr1 arr2 =
2911− let marr1 = getMutableByteArray# (arrContents arr1)
2548+ let marr1 = getMutableByteArray# (arrContents arr1)
2912− marr2 = getMutableByteArray# (arrContents arr2)
2549+ marr2 = getMutableByteArray# (arrContents arr2)
2913− !(I# st1#) = arrStart arr1
2550+ !(I# st1#) = arrStart arr1
2914− !(I# st2#) = arrStart arr2
2551+ !(I# st2#) = arrStart arr2
2915− !(I# len#) = byteLength arr1
2552+ !(I# len#) = byteLength arr1
2916− case compare (byteLength arr1) (byteLength arr2) of
2553+ case compare (byteLength arr1) (byteLength arr2) of
2917− EQ -> do
2554+ EQ -> do
2918− r <- liftIO $ IO $ \s# ->
2555+ r <- liftIO $ IO $ \s# ->
2919− let res =
2556+ let res =
2921− (compareByteArrays#
2558+ (compareByteArrays#
2922− (unsafeCoerce# marr1)
2559+ (unsafeCoerce# marr1)
2924− (unsafeCoerce# marr2)
2561+ (unsafeCoerce# marr2)
2927− in (# s#, res #)
2564+ in (# s#, res #)
2928− return $ compare r 0
2565+ return $ compare r 0
2929− x -> return x
2566+ x -> return x
2931{-# INLINE cmp #-}
2568{-# INLINE cmp #-}
2932{-# DEPRECATED cmp "Please use byteCmp instead." #-}
2569{-# DEPRECATED cmp "Please use byteCmp instead." #-}
@@ -2943,309 +2580,7 @@ byteEq :: MonadIO m => MutArray a -> MutArray a -> m Bool
2943byteEq arr1 arr2 = fmap (EQ ==) $ byteCmp arr1 arr2
2580byteEq arr1 arr2 = fmap (EQ ==) $ byteCmp arr1 arr2
2945-------------------------------------------------------------------------------
2582-------------------------------------------------------------------------------
2946−-- Compact
2583+-- NFData
2947−-------------------------------------------------------------------------------
2949−-- Note: LE versions avoid an extra copy compared to GE. LE parser trades
2950−-- backtracking one array in lieu of avoiding a copy. However, LE and GE both
2951−-- can leave some memory unused. They can split the last array to fit it
2952−-- exactly in the space.
2954−{-# INLINE_NORMAL pCompactLeAs #-}
2956− forall m a. (MonadIO m, Unbox a)
2957− => PinnedState -> Int -> Parser (MutArray a) m (MutArray a)
2958−pCompactLeAs ps maxElems = Parser step initial extract
2962− maxBytes = maxElems * SIZE_OF(a)
2964− functionName = "Streamly.Internal.Data.MutArray.pCompactLE"
2971− ++ ": the size of arrays ["
2972− ++ show maxElems ++ "] must be a natural number"
2973− else Parser.IPartial Nothing
2977− $ let len = byteLength arr
2978− in if len >= maxBytes
2979− then Parser.Done 0 arr
2980− else Parser.Partial 0 (Just arr)
2981− -- XXX Split the last array to use the space more compactly.
2982− step (Just buf) arr =
2983− let len = byteLength buf + byteLength arr
2984− in if len > maxBytes
2985− then return $ Parser.Done 1 buf
2988− if byteCapacity buf < maxBytes
2989− then liftIO $ reallocExplicitAs
2990− ps (SIZE_OF(a)) maxBytes buf
2992− buf2 <- spliceUnsafe buf1 arr
2993− return $ Parser.Partial 0 (Just buf2)
2995− extract Nothing = return $ Parser.Done 0 nil
2996− extract (Just buf) = return $ Parser.Done 0 buf
2998−-- | Parser @pCompactLE maxElems@ coalesces adjacent arrays in the input stream
2999−-- only if the combined size would be less than or equal to @maxElems@
3000−-- elements. Note that it won't split an array if the original array is already
3001−-- larger than maxElems.
3003−-- @maxElems@ must be greater than 0.
3005−-- Generates unpinned arrays irrespective of the pinning status of input
3009−{-# INLINE pCompactLE #-}
3011− forall m a. (MonadIO m, Unbox a)
3012− => Int -> Parser (MutArray a) m (MutArray a)
3013−pCompactLE = pCompactLeAs Unpinned
3015−-- | Pinned version of 'pCompactLE'.
3016−{-# INLINE pPinnedCompactLE #-}
3018− forall m a. (MonadIO m, Unbox a)
3019− => Int -> Parser (MutArray a) m (MutArray a)
3020−pPinnedCompactLE = pCompactLeAs Pinned
3022−data SpliceState s arr
3024− | SpliceBuffering s arr
3025− | SpliceYielding arr (SpliceState s arr)
3028−-- This mutates the first array (if it has space) to append values from the
3029−-- second one. This would work for immutable arrays as well because an
3030−-- immutable array never has additional space so a new array is allocated
3031−-- instead of mutating it.
3033−{-# INLINE_NORMAL compactLeAs #-}
3034−compactLeAs :: forall m a. (MonadIO m, Unbox a)
3035− => PinnedState -> Int -> D.Stream m (MutArray a) -> D.Stream m (MutArray a)
3036−compactLeAs ps maxElems (D.Stream step state) =
3037− D.Stream step' (SpliceInitial state)
3041− maxBytes = maxElems * SIZE_OF(a)
3043− functionName = "Streamly.Internal.Data.MutArray.rCompactLE"
3045− {-# INLINE_LATE step' #-}
3046− step' gst (SpliceInitial st) = do
3047− when (maxElems <= 0) $
3048− -- XXX we can pass the module string from the higher level API
3049− error $ functionName ++ ": the size of arrays [" ++ show maxElems
3050− ++ "] must be a natural number"
3053− D.Yield arr s -> return $
3054− let len = byteLength arr
3055− in if len >= maxBytes
3056− then D.Skip (SpliceYielding arr (SpliceInitial s))
3057− else D.Skip (SpliceBuffering s arr)
3058− D.Skip s -> return $ D.Skip (SpliceInitial s)
3059− D.Stop -> return D.Stop
3061− -- XXX Split the last array to use the space more compactly.
3062− step' gst (SpliceBuffering st buf) = do
3065− D.Yield arr s -> do
3066− let len = byteLength buf + byteLength arr
3069− D.Skip (SpliceYielding buf (SpliceBuffering s arr))
3071− buf1 <- if byteCapacity buf < maxBytes
3072− then liftIO $ reallocExplicitAs
3073− ps (SIZE_OF(a)) maxBytes buf
3075− buf2 <- spliceUnsafe buf1 arr
3076− return $ D.Skip (SpliceBuffering s buf2)
3077− D.Skip s -> return $ D.Skip (SpliceBuffering s buf)
3078− D.Stop -> return $ D.Skip (SpliceYielding buf SpliceFinish)
3080− step' _ SpliceFinish = return D.Stop
3082− step' _ (SpliceYielding arr next) = return $ D.Yield arr next
3085−{-# INLINE_NORMAL fCompactGeAs #-}
3087− forall m a. (MonadIO m, Unbox a)
3088− => PinnedState -> Int -> FL.Fold m (MutArray a) (MutArray a)
3089−fCompactGeAs ps minElems = Fold step initial extract extract
3093− minBytes = minElems * SIZE_OF(a)
3095− functionName = "Streamly.Internal.Data.MutArray.fCompactGE"
3102− ++ ": the size of arrays ["
3103− ++ show minElems ++ "] must be a natural number"
3104− else FL.Partial Nothing
3108− $ let len = byteLength arr
3109− in if len >= minBytes
3111− else FL.Partial (Just arr)
3112− -- XXX Buffer arrays as a list to avoid copy and reallocations
3113− step (Just buf) arr = do
3114− let len = byteLength buf + byteLength arr
3116− if byteCapacity buf < len
3117− then liftIO $ reallocExplicitAs
3118− ps (SIZE_OF(a)) (max minBytes len) buf
3120− buf2 <- spliceUnsafe buf1 arr
3122− then return $ FL.Done buf2
3123− else return $ FL.Partial (Just buf2)
3125− extract Nothing = return nil
3126− extract (Just buf) = return buf
3128−-- | Fold @fCompactGE minElems@ coalesces adjacent arrays in the input stream
3129−-- until the size becomes greater than or equal to @minElems@.
3131−-- Generates unpinned arrays irrespective of the pinning status of input
3133−{-# INLINE fCompactGE #-}
3135− forall m a. (MonadIO m, Unbox a)
3136− => Int -> FL.Fold m (MutArray a) (MutArray a)
3137−fCompactGE = fCompactGeAs Unpinned
3139−-- | Pinned version of 'fCompactGE'.
3140−{-# INLINE fPinnedCompactGE #-}
3142− forall m a. (MonadIO m, Unbox a)
3143− => Int -> FL.Fold m (MutArray a) (MutArray a)
3144−fPinnedCompactGE = fCompactGeAs Pinned
3146−{-# INLINE_NORMAL lCompactGeAs #-}
3147−lCompactGeAs :: forall m a. (MonadIO m, Unbox a)
3148− => PinnedState -> Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
3149−-- The fold version turns out to be a little bit slower.
3150−-- lCompactGeAs ps n = FL.many (fCompactGeAs ps n)
3151−lCompactGeAs ps minElems (Fold step1 initial1 _ final1) =
3152− Fold step initial extract final
3156− minBytes = minElems * SIZE_OF(a)
3158− functionName = "Streamly.Internal.Data.MutArray.lCompactGE"
3161− when (minElems <= 0) $
3162− -- XXX we can pass the module string from the higher level API
3163− error $ functionName ++ ": the size of arrays ["
3164− ++ show minElems ++ "] must be a natural number"
3167− return $ first (Tuple' Nothing) r
3169− {-# INLINE runInner #-}
3170− runInner len acc buf =
3175− FL.Done _ -> return $ FL.Done ()
3179− return $ first (Tuple' Nothing) res
3180− else return $ FL.Partial $ Tuple' (Just buf) acc
3182− step (Tuple' Nothing r1) arr =
3183− runInner (byteLength arr) r1 arr
3185− -- XXX Buffer arrays as a list to avoid copy and reallocations
3186− step (Tuple' (Just buf) r1) arr = do
3187− let len = byteLength buf + byteLength arr
3188− buf1 <- if byteCapacity buf < len
3189− then liftIO $ reallocExplicitAs
3190− ps (SIZE_OF(a)) (max minBytes len) buf
3192− buf2 <- spliceUnsafe buf1 arr
3193− runInner len r1 buf2
3195− -- XXX Several folds do extract >=> final, therefore, we need to make final
3196− -- return "m b" rather than using extract post it if we want extract to be
3199− -- extract forces the pending buffer to be sent to the fold which is not
3201− extract _ = error "lCompactGE: not designed for scanning"
3203− final (Tuple' Nothing r1) = final1 r1
3204− final (Tuple' (Just buf) r1) = do
3207− FL.Partial rr -> final1 rr
3208− FL.Done _ -> return ()
3210−-- | Like 'compactGE' but for transforming folds instead of stream.
3212−-- >>> lCompactGE n = Fold.many (MutArray.fCompactGE n)
3214−-- Generates unpinned arrays irrespective of the pinning status of input
3216−{-# INLINE lCompactGE #-}
3217−lCompactGE :: forall m a. (MonadIO m, Unbox a)
3218− => Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
3219−lCompactGE = lCompactGeAs Unpinned
3221−-- | Pinned version of 'lCompactGE'.
3222−{-# INLINE lPinnedCompactGE #-}
3223−lPinnedCompactGE :: forall m a. (MonadIO m, Unbox a)
3224− => Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
3225−lPinnedCompactGE = lCompactGeAs Pinned
3227−-- | @compactGE n stream@ coalesces adjacent arrays in the @stream@ until
3228−-- the size becomes greater than or equal to @n@.
3230−-- >>> compactGE n = Stream.foldMany (MutArray.fCompactGE n)
3232−{-# INLINE compactGE #-}
3234− (MonadIO m, Unbox a)
3235− => Int -> Stream m (MutArray a) -> Stream m (MutArray a)
3236−compactGE n = D.foldMany (fCompactGE n)
3238−-- | 'compactEQ n' coalesces adajacent arrays in the input stream to
3239−-- arrays of exact size @n@.
3242−{-# INLINE compactEQ #-}
3243−compactEQ :: -- (MonadIO m, Unbox a) =>
3244− Int -> Stream m (MutArray a) -> Stream m (MutArray a)
3245−compactEQ _n = undefined -- D.parseManyD (pCompactEQ n)
3247−-------------------------------------------------------------------------------
3248−-- In-place mutation algorithms
3249-------------------------------------------------------------------------------
2584-------------------------------------------------------------------------------
3251-- | Strip elements which match with predicate from both ends.
2586-- | Strip elements which match with predicate from both ends.