2-- Module : Streamly.Benchmark.FileIO.Array
3-- Copyright : (c) 2019 Composewell Technologies
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
12#ifdef __HADDOCK_VERSION__
17{-# LANGUAGE TemplateHaskell #-}
18{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
21module Streamly.Benchmark.FileIO.Array
38 , copyCodecUtf8Lenient
42import Data.Functor.Identity (runIdentity)
43import Data.Word (Word8)
44import System.IO (Handle, hClose)
45import Prelude hiding (last)
47import qualified Streamly.FileSystem.Handle as FH
48import qualified Streamly.Memory.Array as A
49import qualified Streamly.Prelude as S
50import qualified Streamly.Data.Unicode.Stream as SS
51import qualified Streamly.Internal.Data.Unicode.Stream as IUS
53import qualified Streamly.Internal.FileSystem.Handle as IFH
54import qualified Streamly.Internal.Memory.Array as IA
55import qualified Streamly.Internal.Memory.ArrayStream as AS
56import qualified Streamly.Internal.Data.Unfold as IUF
57import qualified Streamly.Internal.Prelude as IP
60import Foreign.Storable (Storable)
61import Streamly.Internal.Data.Stream.StreamD.Type (Step(..))
65-- | Get the last byte from a file bytestream.
67last :: Handle -> IO (Maybe Word8)
69 let s = IFH.toChunks inh
73 Just arr -> IA.readIndex arr (A.length arr - 1)
76inspect $ hasNoTypeClasses 'last
77inspect $ 'last `hasNoType` ''Step
80-- | Count the number of bytes in a file.
81{-# INLINE countBytes #-}
82countBytes :: Handle -> IO Int
84 let s = IFH.toChunks inh
85 in S.sum (S.map A.length s)
88inspect $ hasNoTypeClasses 'countBytes
89inspect $ 'countBytes `hasNoType` ''Step
92-- | Count the number of lines in a file.
93{-# INLINE countLines #-}
94countLines :: Handle -> IO Int
95countLines = S.length . AS.splitOnSuffix 10 . IFH.toChunks
98inspect $ hasNoTypeClasses 'countLines
99inspect $ 'countLines `hasNoType` ''Step
102-- XXX use a word splitting combinator instead of splitOn and test it.
103-- | Count the number of lines in a file.
104{-# INLINE countWords #-}
105countWords :: Handle -> IO Int
106countWords = S.length . AS.splitOn 32 . IFH.toChunks
109inspect $ hasNoTypeClasses 'countWords
110inspect $ 'countWords `hasNoType` ''Step
113-- | Sum the bytes in a file.
114{-# INLINE sumBytes #-}
115sumBytes :: Handle -> IO Word8
117 let foldlArr' f z = runIdentity . S.foldl' f z . IA.toStream
118 let s = IFH.toChunks inh
119 S.foldl' (\acc arr -> acc + foldlArr' (+) 0 arr) 0 s
122inspect $ hasNoTypeClasses 'sumBytes
123inspect $ 'sumBytes `hasNoType` ''Step
126-- | Send the file contents to /dev/null
128cat :: Handle -> Handle -> IO ()
130 S.fold (IFH.writeChunks devNull) $ IFH.toChunksWithBufferOf (256*1024) inh
133inspect $ hasNoTypeClasses 'cat
134inspect $ 'cat `hasNoType` ''Step
137-- | Send the file contents to /dev/null with exception handling
138{-# INLINE catBracket #-}
139catBracket :: Handle -> Handle -> IO ()
140catBracket devNull inh =
141 let readEx = IUF.bracket return (\_ -> hClose inh)
142 (IUF.supplyFirst FH.readChunksWithBufferOf (256*1024))
143 in IUF.fold readEx (IFH.writeChunks devNull) inh
146inspect $ hasNoTypeClasses 'catBracket
147-- inspect $ 'catBracket `hasNoType` ''Step
150{-# INLINE catBracketIO #-}
151catBracketIO :: Handle -> Handle -> IO ()
152catBracketIO devNull inh =
153 let readEx = IUF.bracketIO return (\_ -> hClose inh)
154 (IUF.supplyFirst FH.readChunksWithBufferOf (256*1024))
155 in IUF.fold readEx (IFH.writeChunks devNull) inh
157-- | Send the file contents to /dev/null with exception handling
158{-# INLINE catBracketStream #-}
159catBracketStream :: Handle -> Handle -> IO ()
160catBracketStream devNull inh =
161 let readEx = S.bracket (return ()) (\_ -> hClose inh)
162 (\_ -> IFH.toChunksWithBufferOf (256*1024) inh)
163 in S.fold (IFH.writeChunks devNull) $ readEx
166inspect $ hasNoTypeClasses 'catBracketStream
167-- inspect $ 'catBracketStream `hasNoType` ''Step
170{-# INLINE catBracketStreamIO #-}
171catBracketStreamIO :: Handle -> Handle -> IO ()
172catBracketStreamIO devNull inh =
173 let readEx = IP.bracketIO (return ()) (\_ -> hClose inh)
174 (\_ -> IFH.toChunksWithBufferOf (256*1024) inh)
175 in S.fold (IFH.writeChunks devNull) $ readEx
177-- | Send the file contents to /dev/null with exception handling
178{-# INLINE catOnException #-}
179catOnException :: Handle -> Handle -> IO ()
180catOnException devNull inh =
181 let readEx = IUF.onException (\_ -> hClose inh)
182 (IUF.supplyFirst FH.readChunksWithBufferOf (256*1024))
183 in IUF.fold readEx (IFH.writeChunks devNull) inh
186inspect $ hasNoTypeClasses 'catOnException
187-- inspect $ 'catOnException `hasNoType` ''Step
192copy :: Handle -> Handle -> IO ()
194 let s = IFH.toChunks inh
195 in S.fold (IFH.writeChunks outh) s
198inspect $ hasNoTypeClasses 'copy
199inspect $ 'copy `hasNoType` ''Step
202-- | Lines and unlines
203{-# INLINE linesUnlinesCopy #-}
204linesUnlinesCopy :: Handle -> Handle -> IO ()
205linesUnlinesCopy inh outh =
206 S.fold (IFH.writeWithBufferOf (1024*1024) outh)
207 $ AS.interposeSuffix 10
208 $ AS.splitOnSuffix 10
209 $ IFH.toChunksWithBufferOf (1024*1024) inh
212inspect $ hasNoTypeClassesExcept 'linesUnlinesCopy [''Storable]
213-- inspect $ 'linesUnlinesCopy `hasNoType` ''Step
216-- | Words and unwords
217{-# INLINE wordsUnwordsCopy #-}
218wordsUnwordsCopy :: Handle -> Handle -> IO ()
219wordsUnwordsCopy inh outh =
220 S.fold (IFH.writeWithBufferOf (1024*1024) outh)
222 -- XXX this is not correct word splitting combinator
224 $ IFH.toChunksWithBufferOf (1024*1024) inh
227inspect $ hasNoTypeClassesExcept 'wordsUnwordsCopy [''Storable]
228-- inspect $ 'wordsUnwordsCopy `hasNoType` ''Step
231{-# INLINE decodeUtf8Lenient #-}
232decodeUtf8Lenient :: Handle -> IO ()
233decodeUtf8Lenient inh =
235 $ IUS.decodeUtf8ArraysLenient
236 $ IFH.toChunksWithBufferOf (1024*1024) inh
239inspect $ hasNoTypeClasses 'decodeUtf8Lenient
240-- inspect $ 'decodeUtf8Lenient `hasNoType` ''Step
241-- inspect $ 'decodeUtf8Lenient `hasNoType` ''AT.FlattenState
242-- inspect $ 'decodeUtf8Lenient `hasNoType` ''D.ConcatMapUState
246{-# INLINE copyCodecUtf8Lenient #-}
247copyCodecUtf8Lenient :: Handle -> Handle -> IO ()
248copyCodecUtf8Lenient inh outh =
249 S.fold (FH.write outh)
251 $ IUS.decodeUtf8ArraysLenient
252 $ IFH.toChunksWithBufferOf (1024*1024) inh
255inspect $ hasNoTypeClasses 'copyCodecUtf8Lenient
256-- inspect $ 'copyCodecUtf8Lenient `hasNoType` ''Step
257-- inspect $ 'copyCodecUtf8Lenient `hasNoType` ''AT.FlattenState
258-- inspect $ 'copyCodecUtf8Lenient `hasNoType` ''D.ConcatMapUState
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list