on master help sign in
Round up space to 4K for large objects

In shrinkToFit. Also, rename shrinkToFit to rightSize.

commita096f77c3e3032b2f8f27e291d52a18bd2ab1a18 authorHarendra Kumar <harendra@composewell.com> dateMon 11 Oct 2021, 22:59 (5 years ago) parent8f467a4
3 files changed+24−14
src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+21−11 src/Streamly/Internal/Data/Array/Foreign/Type.hs+2−2 src/Streamly/Internal/Data/Array/Stream/Foreign.hs+1−1
src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+21−11
@@ -29,7 +29,7 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
2929
3030 -- * Resizing
3131 , realloc
32− , shrinkToFit
32+ , rightSize
3333
3434 -- * Size
3535 , length
@@ -533,18 +533,28 @@ realloc i arr =
533533 $ reallocAligned
534534 (sizeOf (undefined :: a)) (alignment (undefined :: a)) i arr
535535
536−-- | Remove the free space from an Array.
537−{-# INLINE shrinkToFit #-}
538−shrinkToFit :: (MonadIO m, Storable a) => Array a -> m (Array a)
539−shrinkToFit arr@Array{..} = do
536+-- | Drop any reserved free space at the end of the array and reallocate it to
537+-- reduce wastage.
538+--
539+-- Up to 25% wastage is allowed to avoid reallocations. If the capacity is
540+-- more than 'largeObjectThreshold' then free space up to the 'blockSize' is
541+-- retained.
542+--
543+-- /Pre-release/
544+{-# INLINE rightSize #-}
545+rightSize :: forall m a. (MonadIO m, Storable a) => Array a -> m (Array a)
546+rightSize arr@Array{..} = do
540547 assert (aEnd <= aBound) (return ())
541548 let start = unsafeForeignPtrToPtr aStart
542− let used = aEnd `minusPtr` start
549+ len = aEnd `minusPtr` start
550+ capacity = aBound `minusPtr` start
551+ target = roundUpLargeArray len
543552 waste = aBound `minusPtr` aEnd
544− -- if used == waste == 0 then do not realloc
545− -- if the wastage is more than 25% of the array then realloc
546− if used < 3 * waste
547− then realloc used arr
553+ assert (target >= len) (return ())
554+ assert (len `mod` sizeOf (undefined :: a) == 0) (return ())
555+ -- We trade off some wastage (25%) to avoid reallocations and copying.
556+ if target < capacity && len < 3 * waste
557+ then realloc target arr
548558 else return arr
549559
550560-------------------------------------------------------------------------------
@@ -1106,7 +1116,7 @@ writeWith alignSize elemCount =
11061116 (sizeOf (undefined :: a)) alignSize newSize arr
11071117 insertElem arr1 x
11081118 step arr x = insertElem arr x
1109− extract = liftIO . shrinkToFit
1119+ extract = liftIO . rightSize
11101120
11111121-- | Fold the whole input to a single array.
11121122--
src/Streamly/Internal/Data/Array/Foreign/Type.hs+2−2
@@ -170,12 +170,12 @@ foreign import ccall unsafe "string.h strlen" c_strlen
170170unsafeFreeze :: MA.Array a -> Array a
171171unsafeFreeze (MA.Array as ae _) = Array as ae
172172
173−-- | Similar to 'unsafeFreeze' but uses 'MA.shrinkToFit' on the mutable array
173+-- | Similar to 'unsafeFreeze' but uses 'MA.rightSize' on the mutable array
174174-- first.
175175{-# INLINE unsafeFreezeWithShrink #-}
176176unsafeFreezeWithShrink :: Storable a => MA.Array a -> Array a
177177unsafeFreezeWithShrink arr = unsafePerformIO $ do
178− MA.Array as ae _ <- MA.shrinkToFit arr
178+ MA.Array as ae _ <- MA.rightSize arr
179179 return $ Array as ae
180180
181181-- | Makes a mutable array using the underlying memory of the immutable array.
src/Streamly/Internal/Data/Array/Stream/Foreign.hs+1−1
@@ -474,7 +474,7 @@ spliceArraysRealloced s = do
474474 (mkChunkSizeKB 4))
475475
476476 arr <- S.foldlM' MA.spliceExp idst (S.map A.unsafeThaw s)
477− liftIO $ A.unsafeFreeze <$> MA.shrinkToFit arr
477+ liftIO $ A.unsafeFreeze <$> MA.rightSize arr
478478
479479-- XXX This should just be "fold A.write"
480480--