@@ -86,7 +86,8 @@ module Streamly.FileSystem.Handle
86 -- -- * Array Write
86 -- -- * Array Write
87 , writeArray
87 , writeArray
88 , writeArrays
88 , writeArrays
89− , writeArraysPackedUpto
89+ -- , writeArraysPackedUpto
90+ , writeArraysInChunksOf
91 -- -- * Random Access (Seek)
92 -- -- * Random Access (Seek)
92 -- -- | Unlike the streaming APIs listed above, these APIs apply to devices or
93 -- -- | Unlike the streaming APIs listed above, these APIs apply to devices or
@@ -122,10 +123,12 @@ import Prelude hiding (read)
122import Streamly.Memory.Array.Types (Array(..))
123import Streamly.Memory.Array.Types (Array(..))
123import Streamly.Streams.Serial (SerialT)
124import Streamly.Streams.Serial (SerialT)
124import Streamly.Streams.StreamK.Type (IsStream, mkStream)
125import Streamly.Streams.StreamK.Type (IsStream, mkStream)
125−import Streamly.Memory.Array.Types (defaultChunkSize, shrinkToFit)
126+import Streamly.Memory.Array.Types (defaultChunkSize, shrinkToFit, lpackArraysChunksOf)
126−-- import Streamly.Fold (Fold)
127+import Streamly.Fold (Fold)
127-- import Streamly.String (encodeUtf8, decodeUtf8, foldLines)
128-- import Streamly.String (encodeUtf8, decodeUtf8, foldLines)
130+import qualified Streamly.Fold as FL
131+import qualified Streamly.Fold.Types as FL
129import qualified Streamly.Memory.Array as A
132import qualified Streamly.Memory.Array as A
130import qualified Streamly.Memory.ArrayStream as AS
133import qualified Streamly.Memory.ArrayStream as AS
131import qualified Streamly.Prelude as S
134import qualified Streamly.Prelude as S
@@ -265,12 +268,20 @@ read = AS.flatten . readArrays
265-- Writing
268-- Writing
266-------------------------------------------------------------------------------
269-------------------------------------------------------------------------------
271+-- | Write a stream of arrays to a handle.
274+{-# INLINE writeArraysS #-}
275+writeArraysS :: (MonadIO m, Storable a)
276+ => Handle -> SerialT m (Array a) -> m ()
277+writeArraysS h m = S.mapM_ (liftIO . writeArray h) m
268-- | Write a stream of arrays to a handle.
279-- | Write a stream of arrays to a handle.
270-- @since 0.7.0
281-- @since 0.7.0
271{-# INLINE writeArrays #-}
282{-# INLINE writeArrays #-}
272−writeArrays :: (MonadIO m, Storable a) => Handle -> SerialT m (Array a) -> m ()
283+writeArrays :: (MonadIO m, Storable a) => Handle -> Fold m (Array a) ()
273−writeArrays h m = S.mapM_ (liftIO . writeArray h) m
284+writeArrays h = FL.drainBy (liftIO . writeArray h)
275-- | @writeArraysPackedUpto chunkSize handle stream@ writes a stream of arrays
286-- | @writeArraysPackedUpto chunkSize handle stream@ writes a stream of arrays
276-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
287-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
@@ -278,10 +289,22 @@ writeArrays h m = S.mapM_ (liftIO . writeArray h) m
278-- we do not split the arrays to fit exactly to the specified size.
289-- we do not split the arrays to fit exactly to the specified size.
280-- @since 0.7.0
291-- @since 0.7.0
281−{-# INLINE writeArraysPackedUpto #-}
292+{-# INLINE _writeArraysPackedUpto #-}
282−writeArraysPackedUpto :: (MonadIO m, Storable a)
293+_writeArraysPackedUpto :: (MonadIO m, Storable a)
283 => Int -> Handle -> SerialT m (Array a) -> m ()
294 => Int -> Handle -> SerialT m (Array a) -> m ()
284−writeArraysPackedUpto n h xs = writeArrays h $ AS.compact n xs
295+_writeArraysPackedUpto n h xs = writeArraysS h $ AS.compact n xs
297+-- | @writeArraysInChunksOf chunkSize handle@ writes a stream of arrays
298+-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
299+-- We never split an array, if a single array is bigger than the specified size
300+-- it emitted as it is. Multiple arrays are coalesed as long as the total size
301+-- remains below the specified size.
304+{-# INLINE writeArraysInChunksOf #-}
305+writeArraysInChunksOf :: (MonadIO m, Storable a)
306+ => Int -> Handle -> Fold m (Array a) ()
307+writeArraysInChunksOf n h = lpackArraysChunksOf n (writeArrays h)
286-- GHC buffer size dEFAULT_FD_BUFFER_SIZE=8192 bytes.
309-- GHC buffer size dEFAULT_FD_BUFFER_SIZE=8192 bytes.
@@ -296,18 +319,37 @@ writeArraysPackedUpto n h xs = writeArrays h $ AS.compact n xs
296-- collect the required input size.
319-- collect the required input size.
298-- @since 0.7.0
321-- @since 0.7.0
322+{-# INLINE writeInChunksOfS #-}
323+writeInChunksOfS :: MonadIO m => Int -> Handle -> SerialT m Word8 -> m ()
324+writeInChunksOfS n h m = writeArraysS h $ AS.arraysOf n m
326+-- | @writeInChunksOf chunkSize handle@ writes the input stream to @handle@ in
327+-- chunks of @chunkSize@. A write is performed to the IO device as soon as we
328+-- collect the required input size.
299{-# INLINE writeInChunksOf #-}
331{-# INLINE writeInChunksOf #-}
300−writeInChunksOf :: MonadIO m => Int -> Handle -> SerialT m Word8 -> m ()
332+writeInChunksOf :: MonadIO m => Int -> Handle -> Fold m Word8 ()
301−writeInChunksOf n h m = writeArrays h $ AS.arraysOf n m
333+writeInChunksOf n h = FL.lchunksOf n A.write (writeArrays h)
335+-- > write = 'writeInChunksOf' A.defaultChunkSize
337+-- | Write a byte stream to a file handle. Accumulates the input in chunks of
338+-- up to 'A.defaultChunkSize' before writing.
341+{-# INLINE _writeS #-}
342+_writeS :: MonadIO m => Handle -> SerialT m Word8 -> m ()
343+_writeS = writeInChunksOfS defaultChunkSize
303-- > write = 'writeInChunksOf' A.defaultChunkSize
345-- > write = 'writeInChunksOf' A.defaultChunkSize
305−-- | Write a byte stream to a file handle. Combines the bytes in chunks of
347+-- | Write a byte stream to a file handle. Accumulates the input in chunks of
306-- up to 'A.defaultChunkSize' before writing.
348-- up to 'A.defaultChunkSize' before writing.
308-- @since 0.7.0
350-- @since 0.7.0
309{-# INLINE write #-}
351{-# INLINE write #-}
310−write :: MonadIO m => Handle -> SerialT m Word8 -> m ()
352+write :: MonadIO m => Handle -> Fold m Word8 ()
311write = writeInChunksOf defaultChunkSize
353write = writeInChunksOf defaultChunkSize