@@ -251,9 +251,12 @@ module Streamly.Internal.Data.MutArray.Type
251 -- | Append the arrays in a stream to form a stream of larger arrays.
251 -- | Append the arrays in a stream to form a stream of larger arrays.
252 , SpliceState (..)
252 , SpliceState (..)
253 , pCompactLE
253 , pCompactLE
254− , rCompactLE
254+ , pPinnedCompactLE
255 , fCompactGE
256 , fCompactGE
256 , lCompactGE
258 , lCompactGE
257 , compactGE
260 , compactGE
258 , compactEQ
261 , compactEQ
@@ -839,15 +842,15 @@ roundDownTo elemSize size = size - (size `mod` elemSize)
839-- Since this is not inlined Unboxed consrraint leads to dictionary passing
842-- Since this is not inlined Unboxed consrraint leads to dictionary passing
840-- which complicates some inspection tests.
843-- which complicates some inspection tests.
842−{-# NOINLINE reallocExplicit #-}
845+{-# NOINLINE reallocExplicitAs #-}
843−reallocExplicit :: Int -> Int -> MutArray a -> IO (MutArray a)
846+reallocExplicitAs :: PinnedState -> Int -> Int -> MutArray a -> IO (MutArray a)
844−reallocExplicit elemSize newCapacityInBytes MutArray{..} = do
847+reallocExplicitAs ps elemSize newCapacityInBytes MutArray{..} = do
845 assertM(arrEnd <= arrBound)
848 assertM(arrEnd <= arrBound)
847 -- Allocate new array
850 -- Allocate new array
848 let newCapMaxInBytes = roundUpLargeArray newCapacityInBytes
851 let newCapMaxInBytes = roundUpLargeArray newCapacityInBytes
849 contents <-
852 contents <-
850− if Unboxed.isPinned arrContents
853+ if ps == Pinned
851 then Unboxed.pinnedNew newCapMaxInBytes
854 then Unboxed.pinnedNew newCapMaxInBytes
852 else Unboxed.new newCapMaxInBytes
855 else Unboxed.new newCapMaxInBytes
853 let !(MutByteArray mbarrFrom#) = arrContents
856 let !(MutByteArray mbarrFrom#) = arrContents
@@ -887,7 +890,12 @@ reallocExplicit elemSize newCapacityInBytes MutArray{..} = do
887-- If the original array is pinned, the newly allocated array is also pinned.
890-- If the original array is pinned, the newly allocated array is also pinned.
888{-# INLINABLE realloc #-}
891{-# INLINABLE realloc #-}
889realloc :: forall m a. (MonadIO m, Unbox a) => Int -> MutArray a -> m (MutArray a)
892realloc :: forall m a. (MonadIO m, Unbox a) => Int -> MutArray a -> m (MutArray a)
890−realloc bytes arr = liftIO $ reallocExplicit (SIZE_OF(a)) bytes arr
898+ in liftIO $ reallocExplicitAs ps (SIZE_OF(a)) bytes arr
892-- | @reallocWith label capSizer minIncrBytes array@. The label is used
900-- | @reallocWith label capSizer minIncrBytes array@. The label is used
893-- in error messages and the capSizer is used to determine the capacity of the
901-- in error messages and the capSizer is used to determine the capacity of the
@@ -2284,7 +2292,7 @@ writeWithAs ps elemCount =
2284 | INDEX_NEXT(end,a) > bound = do
2292 | INDEX_NEXT(end,a) > bound = do
2285 let oldSize = end - start
2293 let oldSize = end - start
2286 newSize = max (oldSize * 2) 1
2294 newSize = max (oldSize * 2) 1
2287− arr1 <- liftIO $ reallocExplicit (SIZE_OF(a)) newSize arr
2295+ arr1 <- liftIO $ reallocExplicitAs ps (SIZE_OF(a)) newSize arr
2288 snocUnsafe arr1 x
2296 snocUnsafe arr1 x
2289 step arr x = snocUnsafe arr x
2297 step arr x = snocUnsafe arr x
@@ -2943,19 +2951,11 @@ byteEq arr1 arr2 = fmap (EQ ==) $ byteCmp arr1 arr2
2943-- can leave some memory unused. They can split the last array to fit it
2951-- can leave some memory unused. They can split the last array to fit it
2944-- exactly in the space.
2952-- exactly in the space.
2946−-- | Parser @pCompactLE maxElems@ coalesces adjacent arrays in the input stream
2947−-- only if the combined size would be less than or equal to @maxElems@
2948−-- elements. Note that it won't split an array if the original array is already
2949−-- larger than maxElems.
2951−-- @maxElems@ must be greater than 0.
2954−{-# INLINE_NORMAL pCompactLE #-}
2954+{-# INLINE_NORMAL pCompactLeAs #-}
2955−pCompactLE ::
2955+pCompactLeAs ::
2956 forall m a. (MonadIO m, Unbox a)
2956 forall m a. (MonadIO m, Unbox a)
2957− => Int -> Parser (MutArray a) m (MutArray a)
2957+ => PinnedState -> Int -> Parser (MutArray a) m (MutArray a)
2958−pCompactLE maxElems = Parser step initial extract
2958+pCompactLeAs ps maxElems = Parser step initial extract
@@ -2986,7 +2986,8 @@ pCompactLE maxElems = Parser step initial extract
2988 if byteCapacity buf < maxBytes
2988 if byteCapacity buf < maxBytes
2989+ then liftIO $ reallocExplicitAs
2989− then realloc maxBytes buf
2990+ ps (SIZE_OF(a)) maxBytes buf
2990 else return buf
2991 else return buf
2991 buf2 <- spliceUnsafe buf1 arr
2992 buf2 <- spliceUnsafe buf1 arr
2992 return $ Parser.Partial 0 (Just buf2)
2993 return $ Parser.Partial 0 (Just buf2)
@@ -2994,6 +2995,30 @@ pCompactLE maxElems = Parser step initial extract
2994 extract Nothing = return $ Parser.Done 0 nil
2995 extract Nothing = return $ Parser.Done 0 nil
2995 extract (Just buf) = return $ Parser.Done 0 buf
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
2997data SpliceState s arr
3022data SpliceState s arr
2998 = SpliceInitial s
3023 = SpliceInitial s
2999 | SpliceBuffering s arr
3024 | SpliceBuffering s arr
@@ -3005,18 +3030,10 @@ data SpliceState s arr
3005-- immutable array never has additional space so a new array is allocated
3030-- immutable array never has additional space so a new array is allocated
3006-- instead of mutating it.
3031-- instead of mutating it.
3008−-- | Scan @rCompactLE maxElems@ coalesces adjacent arrays in the input stream
3009−-- only if the combined size would be less than or equal to @maxElems@
3010−-- elements. Note that it won't split an array if the original array is already
3011−-- larger than maxElems.
3013−-- @maxElems@ must be greater than 0.
3016−{-# INLINE_NORMAL rCompactLE #-}
3033+{-# INLINE_NORMAL compactLeAs #-}
3017−rCompactLE :: forall m a. (MonadIO m, Unbox a)
3034+compactLeAs :: forall m a. (MonadIO m, Unbox a)
3018− => Int -> D.Stream m (MutArray a) -> D.Stream m (MutArray a)
3035+ => PinnedState -> Int -> D.Stream m (MutArray a) -> D.Stream m (MutArray a)
3019−rCompactLE maxElems (D.Stream step state) =
3036+compactLeAs ps maxElems (D.Stream step state) =
3020 D.Stream step' (SpliceInitial state)
3037 D.Stream step' (SpliceInitial state)
@@ -3052,7 +3069,8 @@ rCompactLE maxElems (D.Stream step state) =
3052 D.Skip (SpliceYielding buf (SpliceBuffering s arr))
3069 D.Skip (SpliceYielding buf (SpliceBuffering s arr))
3054 buf1 <- if byteCapacity buf < maxBytes
3071 buf1 <- if byteCapacity buf < maxBytes
3072+ then liftIO $ reallocExplicitAs
3055− then realloc maxBytes buf
3073+ ps (SIZE_OF(a)) maxBytes buf
3056 else return buf
3074 else return buf
3057 buf2 <- spliceUnsafe buf1 arr
3075 buf2 <- spliceUnsafe buf1 arr
3058 return $ D.Skip (SpliceBuffering s buf2)
3076 return $ D.Skip (SpliceBuffering s buf2)
@@ -3063,14 +3081,12 @@ rCompactLE maxElems (D.Stream step state) =
3064 step' _ (SpliceYielding arr next) = return $ D.Yield arr next
3082 step' _ (SpliceYielding arr next) = return $ D.Yield arr next
3066−-- | Fold @fCompactGE minElems@ coalesces adjacent arrays in the input stream
3084+
3067−-- until the size becomes greater than or equal to @minElems@.
3069−{-# INLINE_NORMAL fCompactGE #-}
3085+{-# INLINE_NORMAL fCompactGeAs #-}
3070−fCompactGE ::
3086+fCompactGeAs ::
3071 forall m a. (MonadIO m, Unbox a)
3087 forall m a. (MonadIO m, Unbox a)
3072− => Int -> FL.Fold m (MutArray a) (MutArray a)
3088+ => PinnedState -> Int -> FL.Fold m (MutArray a) (MutArray a)
3073−fCompactGE minElems = Fold step initial extract extract
3089+fCompactGeAs ps minElems = Fold step initial extract extract
@@ -3098,7 +3114,8 @@ fCompactGE minElems = Fold step initial extract extract
3098 let len = byteLength buf + byteLength arr
3114 let len = byteLength buf + byteLength arr
3100 if byteCapacity buf < len
3116 if byteCapacity buf < len
3117+ then liftIO $ reallocExplicitAs
3101− then realloc (max len minBytes) buf
3118+ ps (SIZE_OF(a)) (max minBytes len) buf
3102 else return buf
3119 else return buf
3103 buf2 <- spliceUnsafe buf1 arr
3120 buf2 <- spliceUnsafe buf1 arr
3104 if len >= minBytes
3121 if len >= minBytes
@@ -3108,15 +3125,30 @@ fCompactGE minElems = Fold step initial extract extract
3108 extract Nothing = return nil
3125 extract Nothing = return nil
3109 extract (Just buf) = return buf
3126 extract (Just buf) = return buf
3111−-- | Like 'compactGE' but for transforming folds instead of stream.
3128+-- | Fold @fCompactGE minElems@ coalesces adjacent arrays in the input stream
3112−--
3129+-- until the size becomes greater than or equal to @minElems@.
3113−-- >>> lCompactGE n = Fold.many (MutArray.fCompactGE n)
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
3115−{-# INLINE_NORMAL lCompactGE #-}
3146+{-# INLINE_NORMAL lCompactGeAs #-}
3116−lCompactGE :: forall m a. (MonadIO m, Unbox a)
3147+lCompactGeAs :: forall m a. (MonadIO m, Unbox a)
3117− => Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
3148+ => PinnedState -> Int -> Fold m (MutArray a) () -> Fold m (MutArray a) ()
3118−-- lCompactGE n = Fold.many (fCompactGE n)
3149+-- The fold version turns out to be a little bit slower.
3150+-- lCompactGeAs ps n = FL.many (fCompactGeAs ps n)
3119−lCompactGE minElems (Fold step1 initial1 _ final1) =
3151+lCompactGeAs ps minElems (Fold step1 initial1 _ final1) =
3120 Fold step initial extract final
3152 Fold step initial extract final
@@ -3154,7 +3186,8 @@ lCompactGE minElems (Fold step1 initial1 _ final1) =
3154 step (Tuple' (Just buf) r1) arr = do
3186 step (Tuple' (Just buf) r1) arr = do
3155 let len = byteLength buf + byteLength arr
3187 let len = byteLength buf + byteLength arr
3156 buf1 <- if byteCapacity buf < len
3188 buf1 <- if byteCapacity buf < len
3189+ then liftIO $ reallocExplicitAs
3157− then realloc (max minBytes len) buf
3190+ ps (SIZE_OF(a)) (max minBytes len) buf
3158 else return buf
3191 else return buf
3159 buf2 <- spliceUnsafe buf1 arr
3192 buf2 <- spliceUnsafe buf1 arr
3160 runInner len r1 buf2
3193 runInner len r1 buf2
@@ -3174,6 +3207,23 @@ lCompactGE minElems (Fold step1 initial1 _ final1) =
3174 FL.Partial rr -> final1 rr
3207 FL.Partial rr -> final1 rr
3175 FL.Done _ -> return ()
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
3177-- | @compactGE n stream@ coalesces adjacent arrays in the @stream@ until
3227-- | @compactGE n stream@ coalesces adjacent arrays in the @stream@ until
3178-- the size becomes greater than or equal to @n@.
3228-- the size becomes greater than or equal to @n@.