@@ -22,19 +22,19 @@ module Streamly.Internal.FileSystem.Handle
22 -- , readUtf8
22 -- , readUtf8
23 -- , readLines
23 -- , readLines
24 -- , readFrames
24 -- , readFrames
25− , readInChunksOf
25+ , readRequestsOf
27 , toStream
27 , toStream
28− , toStreamInChunksOf
28+ , toStreamRequestsOf
30 -- -- * Array Read
30 -- -- * Array Read
31 -- , readArrayUpto
31 -- , readArrayUpto
32 -- , readArrayOf
32 -- , readArrayOf
33− , readArraysOf
33+ , readChunks
34− , readArrays
34+ , readChunksRequestsOf
36− , toStreamArraysOf
36+ , toChunksRequestsOf
37− , toStreamArrays
37+ , toChunks
39 -- ** Write to Handle
39 -- ** Write to Handle
40 -- Byte stream write (Folds)
40 -- Byte stream write (Folds)
@@ -42,7 +42,7 @@ module Streamly.Internal.FileSystem.Handle
42 -- , writeUtf8
42 -- , writeUtf8
43 -- , writeUtf8ByLines
43 -- , writeUtf8ByLines
44 -- , writeByFrames
44 -- , writeByFrames
45− , writeInChunksOf
45+ , writeRequestsOf
47 -- Byte stream write (Streams)
47 -- Byte stream write (Streams)
48 , fromStream
48 , fromStream
@@ -50,8 +50,8 @@ module Streamly.Internal.FileSystem.Handle
51 -- -- * Array Write
51 -- -- * Array Write
52 , writeArray
52 , writeArray
53− , writeArrays
53+ , writeChunks
54− , writeArraysInChunksOf
54+ , writeChunksRequestsOf
56 -- -- * Array stream Write
56 -- -- * Array stream Write
57 , fromStreamArrays
57 , fromStreamArrays
@@ -63,18 +63,37 @@ module Streamly.Internal.FileSystem.Handle
63 -- include disks, files, memory devices and exclude terminals, pipes,
63 -- include disks, files, memory devices and exclude terminals, pipes,
64 -- sockets and fifos.
64 -- sockets and fifos.
66+ -- XXX need to decide whether to use readFromStepN style or readFromThenTo
67+ -- style. The latter is consistent with list enumeration. The former may be
68+ -- more unambiguous and it is easier and clearer to specify 0 elements.
70+ -- We can also generate the request pattern using a funciton.
66 -- , readIndex
72 -- , readIndex
67− -- , readSlice
73+ -- , readFrom -- read from a given position to the end of file
68− -- , readSliceRev
74+ -- , readFromRev -- read from a given position the beginning of file
69− -- , readAt -- read from a given position to th end of file
75+ -- , readTo -- read from beginning up to the given position
70− -- , readSliceArrayUpto
76+ -- , readToRev -- read from end to the given position in file
71− -- , readSliceArrayOf
77+ -- , readFromTo
81+ -- , readChunksFromTo
82+ -- , readChunksFromToRequestsOf
83+ -- , readChunksFromThenToRequestsOf
73 -- , writeIndex
85 -- , writeIndex
76− -- , writeAt -- start writing at the given position
86+ -- , writeFrom -- start writing at the given position
77− -- , writeSliceArray
87+ -- , writeFromRev
88+ -- , writeTo -- write from beginning up to the given position
94+ -- , writeChunksFromTo
95+ -- , writeChunksFromToRequestsOf
96+ -- , writeChunksFromThenToRequestsOf
@@ -145,13 +164,13 @@ readArrayUpto size h = do
145-- Stream of Arrays IO
164-- Stream of Arrays IO
146-------------------------------------------------------------------------------
165-------------------------------------------------------------------------------
148−-- | @toStreamArraysOf size h@ reads a stream of arrays from file handle @h@.
167+-- | @toChunksRequestsOf size h@ reads a stream of arrays from file handle @h@.
149-- The maximum size of a single array is specified by @size@. The actual size
168-- The maximum size of a single array is specified by @size@. The actual size
150-- read may be less than or equal to @size@.
169-- read may be less than or equal to @size@.
151−{-# INLINABLE _toStreamArraysOf #-}
170+{-# INLINABLE _toChunksRequestsOf #-}
152−_toStreamArraysOf :: (IsStream t, MonadIO m)
171+_toChunksRequestsOf :: (IsStream t, MonadIO m)
153 => Int -> Handle -> t m (Array Word8)
172 => Int -> Handle -> t m (Array Word8)
154−_toStreamArraysOf size h = go
173+_toChunksRequestsOf size h = go
156 -- XXX use cons/nil instead
175 -- XXX use cons/nil instead
157 go = mkStream $ \_ yld _ stp -> do
176 go = mkStream $ \_ yld _ stp -> do
@@ -160,14 +179,14 @@ _toStreamArraysOf size h = go
161 else yld arr go
180 else yld arr go
163−-- | @toStreamArraysOf size handle@ reads a stream of arrays from the file
182+-- | @toChunksRequestsOf size handle@ reads a stream of arrays from the file
164-- handle @handle@. The maximum size of a single array is limited to @size@.
183-- handle @handle@. The maximum size of a single array is limited to @size@.
165-- The actual size read may be less than or equal to @size@.
184-- The actual size read may be less than or equal to @size@.
167-- @since 0.7.0
186-- @since 0.7.0
168−{-# INLINE_NORMAL toStreamArraysOf #-}
187+{-# INLINE_NORMAL toChunksRequestsOf #-}
169−toStreamArraysOf :: (IsStream t, MonadIO m) => Int -> Handle -> t m (Array Word8)
188+toChunksRequestsOf :: (IsStream t, MonadIO m) => Int -> Handle -> t m (Array Word8)
170−toStreamArraysOf size h = D.fromStreamD (D.Stream step ())
189+toChunksRequestsOf size h = D.fromStreamD (D.Stream step ())
172 {-# INLINE_LATE step #-}
191 {-# INLINE_LATE step #-}
173 step _ _ = do
192 step _ _ = do
@@ -179,12 +198,12 @@ toStreamArraysOf size h = D.fromStreamD (D.Stream step ())
180-- | Unfold the tuple @(size, handle)@ into a stream of 'Word8' arrays. The
199-- | Unfold the tuple @(size, handle)@ into a stream of 'Word8' arrays. The
181-- stream consists of arrays representing chunks of data read from the handle.
200-- stream consists of arrays representing chunks of data read from the handle.
182−-- The maximum size of a single array is limited to @size@.
201+-- The size of an array in the stream is less than or equal to @size@.
184-- @since 0.7.0
203-- @since 0.7.0
185−{-# INLINE_NORMAL readArraysOf #-}
204+{-# INLINE_NORMAL readChunksRequestsOf #-}
186−readArraysOf :: MonadIO m => Unfold m (Int, Handle) (Array Word8)
205+readChunksRequestsOf :: MonadIO m => Unfold m (Int, Handle) (Array Word8)
187−readArraysOf = Unfold step return
206+readChunksRequestsOf = Unfold step return
189 {-# INLINE_LATE step #-}
208 {-# INLINE_LATE step #-}
190 step (size, h) = do
209 step (size, h) = do
@@ -196,25 +215,28 @@ readArraysOf = Unfold step return
197-- XXX read 'Array a' instead of Word8
216-- XXX read 'Array a' instead of Word8
199−-- | @toStreamArrays handle@ reads a stream of arrays from the specified file
218+-- | @toChunks handle@ reads a stream of arrays from the specified file
200-- handle. The maximum size of a single array is limited to
219-- handle. The maximum size of a single array is limited to
201-- @defaultChunkSize@. The actual size read may be less than or equal to
220-- @defaultChunkSize@. The actual size read may be less than or equal to
202-- @defaultChunkSize@.
221-- @defaultChunkSize@.
204−-- > toStreamArrays = toStreamArraysOf defaultChunkSize
223+-- > toChunks = toChunksRequestsOf defaultChunkSize
206-- @since 0.7.0
225-- @since 0.7.0
207−{-# INLINE toStreamArrays #-}
226+{-# INLINE toChunks #-}
208−toStreamArrays :: (IsStream t, MonadIO m) => Handle -> t m (Array Word8)
227+toChunks :: (IsStream t, MonadIO m) => Handle -> t m (Array Word8)
209−toStreamArrays = toStreamArraysOf defaultChunkSize
228+toChunks = toChunksRequestsOf defaultChunkSize
211−-- | Unfolds a handle into a stream of 'Word8' arrays. The maximum size of a
230+-- | Unfolds a handle into a stream of 'Word8' arrays. Requests to the IO
212−-- single array is limited to @defaultChunkSize@.
231+-- device are performed using a buffer of size
232+-- 'Streamly.Internal.Memory.Array.Types.defaultChunkSize'. The
233+-- size of arrays in the resulting stream are therefore less than or equal to
234+-- 'Streamly.Internal.Memory.Array.Types.defaultChunkSize'.
214-- @since 0.7.0
236-- @since 0.7.0
215−{-# INLINE readArrays #-}
237+{-# INLINE readChunks #-}
216−readArrays :: MonadIO m => Unfold m Handle (Array Word8)
238+readChunks :: MonadIO m => Unfold m Handle (Array Word8)
217−readArrays = UF.supplyFirst readArraysOf defaultChunkSize
239+readChunks = UF.supplyFirst readChunksRequestsOf defaultChunkSize
219-------------------------------------------------------------------------------
241-------------------------------------------------------------------------------
220-- Read File to Stream
242-- Read File to Stream
@@ -224,40 +246,41 @@ readArrays = UF.supplyFirst readArraysOf defaultChunkSize
224-- read requests at the same time. For serial case we can use async IO. We can
246-- read requests at the same time. For serial case we can use async IO. We can
225-- also control the read throughput in mbps or IOPS.
247-- also control the read throughput in mbps or IOPS.
227−-- | @readInChunksOf@ unfolds @(chunksize, handle)@ into a byte stream, reads
249+-- | Unfolds the tuple @(chunksize, handle)@ into a byte stream, read requests
228−-- are performed in chunks of up to @chunkSize@.
250+-- to the IO device are performed using buffers of @chunkSize@.
230-- @since 0.7.0
252-- @since 0.7.0
231−{-# INLINE readInChunksOf #-}
253+{-# INLINE readRequestsOf #-}
232−readInChunksOf :: MonadIO m => Unfold m (Int, Handle) Word8
254+readRequestsOf :: MonadIO m => Unfold m (Int, Handle) Word8
233−readInChunksOf = UF.concat readArraysOf A.read
255+readRequestsOf = UF.concat readChunksRequestsOf A.read
235−-- | @toStreamInChunksOf chunkSize handle@ reads a byte stream from a file
257+-- | @toStreamRequestsOf chunkSize handle@ reads a byte stream from a file
236-- handle, reads are performed in chunks of up to @chunkSize@.
258-- handle, reads are performed in chunks of up to @chunkSize@.
238-- /Internal/
260-- /Internal/
239−{-# INLINE toStreamInChunksOf #-}
261+{-# INLINE toStreamRequestsOf #-}
240−toStreamInChunksOf :: (IsStream t, MonadIO m) => Int -> Handle -> t m Word8
262+toStreamRequestsOf :: (IsStream t, MonadIO m) => Int -> Handle -> t m Word8
241−toStreamInChunksOf chunkSize h = AS.concat $ toStreamArraysOf chunkSize h
263+toStreamRequestsOf chunkSize h = AS.concat $ toChunksRequestsOf chunkSize h
244-- Generate a stream of elements of the given type from a file 'Handle'.
266-- Generate a stream of elements of the given type from a file 'Handle'.
245-- read :: (IsStream t, MonadIO m, Storable a) => Handle -> t m a
267-- read :: (IsStream t, MonadIO m, Storable a) => Handle -> t m a
247−-- > read = 'readInChunksOf' A.defaultChunkSize
248−-- | Unfolds a file handle into a byte stream.
269+-- | Unfolds a file handle into a byte stream. IO requests to the device are
270+-- performed in sizes of
271+-- 'Streamly.Internal.Memory.Array.Types.defaultChunkSize'.
250-- @since 0.7.0
273-- @since 0.7.0
251{-# INLINE read #-}
274{-# INLINE read #-}
252read :: MonadIO m => Unfold m Handle Word8
275read :: MonadIO m => Unfold m Handle Word8
253−read = UF.supplyFirst readInChunksOf defaultChunkSize
276+read = UF.supplyFirst readRequestsOf defaultChunkSize
255-- | Generate a byte stream from a file 'Handle'.
278-- | Generate a byte stream from a file 'Handle'.
257-- /Internal/
280-- /Internal/
258{-# INLINE toStream #-}
281{-# INLINE toStream #-}
259toStream :: (IsStream t, MonadIO m) => Handle -> t m Word8
282toStream :: (IsStream t, MonadIO m) => Handle -> t m Word8
260−toStream = AS.concat . toStreamArrays
283+toStream = AS.concat . toChunks
262-------------------------------------------------------------------------------
285-------------------------------------------------------------------------------
263-- Writing
286-- Writing
@@ -316,10 +339,10 @@ fromStreamInChunksOf :: MonadIO m => Int -> Handle -> SerialT m Word8 -> m ()
316fromStreamInChunksOf n h m = fromStreamArrays h $ S.arraysOf n m
339fromStreamInChunksOf n h m = fromStreamArrays h $ S.arraysOf n m
317-- fromStreamInChunksOf n h m = fromStreamArrays h $ AS.arraysOf n m
340-- fromStreamInChunksOf n h m = fromStreamArrays h $ AS.arraysOf n m
319−-- > write = 'writeInChunksOf' A.defaultChunkSize
342+-- > write = 'writeRequestsOf' A.defaultChunkSize
321-- | Write a byte stream to a file handle. Accumulates the input in chunks of
344-- | Write a byte stream to a file handle. Accumulates the input in chunks of
322−-- up to 'A.defaultChunkSize' before writing.
345+-- up to 'Streamly.Internal.Memory.Array.Types.defaultChunkSize' before writing.
324-- NOTE: This may perform better than the 'write' fold, you can try this if you
347-- NOTE: This may perform better than the 'write' fold, you can try this if you
325-- need some extra perf boost.
348-- need some extra perf boost.
@@ -329,24 +352,25 @@ fromStreamInChunksOf n h m = fromStreamArrays h $ S.arraysOf n m
329fromStream :: MonadIO m => Handle -> SerialT m Word8 -> m ()
352fromStream :: MonadIO m => Handle -> SerialT m Word8 -> m ()
330fromStream = fromStreamInChunksOf defaultChunkSize
353fromStream = fromStreamInChunksOf defaultChunkSize
332−-- | Write a stream of arrays to a handle.
355+-- | Write a stream of arrays to a handle. Each array in the stream is written
356+-- to the device as a separate IO request.
334-- @since 0.7.0
358-- @since 0.7.0
335−{-# INLINE writeArrays #-}
359+{-# INLINE writeChunks #-}
336−writeArrays :: (MonadIO m, Storable a) => Handle -> Fold m (Array a) ()
360+writeChunks :: (MonadIO m, Storable a) => Handle -> Fold m (Array a) ()
337−writeArrays h = FL.drainBy (liftIO . writeArray h)
361+writeChunks h = FL.drainBy (liftIO . writeArray h)
339−-- | @writeArraysInChunksOf chunkSize handle@ writes a stream of arrays
363+-- | @writeChunksRequestsOf chunkSize handle@ writes a stream of arrays
340-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
364-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
341-- We never split an array, if a single array is bigger than the specified size
365-- We never split an array, if a single array is bigger than the specified size
342-- it emitted as it is. Multiple arrays are coalesed as long as the total size
366-- it emitted as it is. Multiple arrays are coalesed as long as the total size
343-- remains below the specified size.
367-- remains below the specified size.
345-- @since 0.7.0
369-- @since 0.7.0
346−{-# INLINE writeArraysInChunksOf #-}
370+{-# INLINE writeChunksRequestsOf #-}
347−writeArraysInChunksOf :: (MonadIO m, Storable a)
371+writeChunksRequestsOf :: (MonadIO m, Storable a)
348 => Int -> Handle -> Fold m (Array a) ()
372 => Int -> Handle -> Fold m (Array a) ()
349−writeArraysInChunksOf n h = lpackArraysChunksOf n (writeArrays h)
373+writeChunksRequestsOf n h = lpackArraysChunksOf n (writeChunks h)
351-- GHC buffer size dEFAULT_FD_BUFFER_SIZE=8192 bytes.
375-- GHC buffer size dEFAULT_FD_BUFFER_SIZE=8192 bytes.
@@ -356,24 +380,25 @@ writeArraysInChunksOf n h = lpackArraysChunksOf n (writeArrays h)
356-- do not want buffering to occur at GHC level as well. Same thing applies to
380-- do not want buffering to occur at GHC level as well. Same thing applies to
357-- writes as well.
381-- writes as well.
359−-- | @writeInChunksOf chunkSize handle@ writes the input stream to @handle@ in
383+-- | @writeRequestsOf reqSize handle@ writes the input stream to @handle@.
360−-- chunks of @chunkSize@. A write is performed to the IO device as soon as we
384+-- Bytes in the input stream are collected into a buffer until we have a chunk
361−-- collect the required input size.
385+-- of @reqSize@ and then written to the IO device.
363-- @since 0.7.0
387-- @since 0.7.0
364−{-# INLINE writeInChunksOf #-}
388+{-# INLINE writeRequestsOf #-}
365−writeInChunksOf :: MonadIO m => Int -> Handle -> Fold m Word8 ()
389+writeRequestsOf :: MonadIO m => Int -> Handle -> Fold m Word8 ()
366−writeInChunksOf n h = FL.lchunksOf n (writeNUnsafe n) (writeArrays h)
390+writeRequestsOf n h = FL.lchunksOf n (writeNUnsafe n) (writeChunks h)
368−-- > write = 'writeInChunksOf' A.defaultChunkSize
392+-- > write = 'writeRequestsOf' A.defaultChunkSize
370-- | Write a byte stream to a file handle. Accumulates the input in chunks of
394-- | Write a byte stream to a file handle. Accumulates the input in chunks of
371−-- up to 'A.defaultChunkSize' before writing.
395+-- up to 'Streamly.Internal.Memory.Array.Types.defaultChunkSize' before writing
373-- @since 0.7.0
398-- @since 0.7.0
374{-# INLINE write #-}
399{-# INLINE write #-}
375write :: MonadIO m => Handle -> Fold m Word8 ()
400write :: MonadIO m => Handle -> Fold m Word8 ()
376−write = writeInChunksOf defaultChunkSize
401+write = writeRequestsOf defaultChunkSize
379{-# INLINE write #-}
404{-# INLINE write #-}