on master help sign in
Refactor "reader" in Dir module
d45b17cHarendra Kumar
core/src/Streamly/Internal/FileSystem/Dir.hs+42−40
@@ -92,9 +92,11 @@ import Streamly.Internal.Data.Unfold (Step(..))
92import Streamly.Internal.Data.Unfold.Type (Unfold(..))
92import Streamly.Internal.Data.Unfold.Type (Unfold(..))
93import System.FilePath ((</>))
93import System.FilePath ((</>))
94#if (defined linux_HOST_OS) || (defined darwin_HOST_OS)
94#if (defined linux_HOST_OS) || (defined darwin_HOST_OS)
95−import System.Posix (openDirStream, readDirStream, closeDirStream)
95+import System.Posix (DirStream, openDirStream, readDirStream, closeDirStream)
96#elif defined(mingw32_HOST_OS)
96#elif defined(mingw32_HOST_OS)
97import qualified System.Win32 as Win32
97import qualified System.Win32 as Win32
98+#else
99+#error "Unsupported architecture"
98#endif
100#endif
99import qualified Streamly.Data.Unfold as UF
101import qualified Streamly.Data.Unfold as UF
100import qualified Streamly.Internal.Data.Unfold as UF (mapM2, bracketIO)
102import qualified Streamly.Internal.Data.Unfold as UF (mapM2, bracketIO)
@@ -237,57 +239,57 @@ toStreamWithBufferOf chunkSize h = AS.concat $ toChunksWithBufferOf chunkSize h
237
239
238-- XXX exception handling
240-- XXX exception handling
239
241
240−-- | Read a directory emitting a stream with names of the children. Filter out
241−-- "." and ".." entries.
242−--
243−-- /Internal/
244−--
245−{-# INLINE reader #-}
246−reader :: (MonadIO m, MonadCatch m) => Unfold m FilePath FilePath
247−reader =
248#if (defined linux_HOST_OS) || (defined darwin_HOST_OS)
242#if (defined linux_HOST_OS) || (defined darwin_HOST_OS)
249− UF.bracketIO openDirStream closeDirStream childOf
243+{-# INLINE streamReader #-}
250− & UF.filter (\x -> x /= "." && x /= "..")
244+streamReader :: MonadIO m => Unfold m DirStream FilePath
245+streamReader = Unfold step return
251
246
252 where
247 where
253
248
254− {-# INLINABLE childOf #-}
249+ step strm = do
255− childOf = Unfold step inject
250+ -- XXX Use readDirStreamMaybe
256−
251+ file <- liftIO $ readDirStream strm
257− where
252+ case file of
253+ [] -> return Stop
254+ _ -> return $ Yield file strm
258
255
259− inject = return
260−
261− step strm = do
262− file <- liftIO $ readDirStream strm
263− case file of
264− [] -> return Stop
265− _ -> return $ Yield file strm
266#elif defined(mingw32_HOST_OS)
256#elif defined(mingw32_HOST_OS)
267− UF.bracketIO
257+openDirStream :: String -> IO (Win32.HANDLE, Win32.FindData)
268− Win32.findFirstFile
258+openDirStream = Win32.findFirstFile
269− (\(h, _) -> liftIO $ Win32.findClose h)
270− childOf
271− & UF.filter (\x -> x /= "." && x /= "..")
272
259
273− where
260+closeDirStream :: (Win32.HANDLE, Win32.FindData) -> IO ()
261+closeDirStream (h, _) = Win32.findClose h
274
262
275− {-# INLINABLE childOf #-}
263+{-# INLINE streamReader #-}
276− childOf = Unfold step inject
264+streamReader :: MonadIO m => Unfold m (Win32.HANDLE, Win32.FindData) FilePath
265+streamReader = Unfold step return
277
266
278− where
267+ where
279−
280− inject = return
281
268
282− step (h, fdat) = do
269+ step (h, fdat) = do
283− more <- liftIO $ Win32.findNextFile h fdat
270+ more <- liftIO $ Win32.findNextFile h fdat
284− if more
271+ if more
285− then do
272+ then do
286− file <- liftIO $ Win32.getFindDataFileName fdat
273+ file <- liftIO $ Win32.getFindDataFileName fdat
287− return $ Yield file (h, fdat)
274+ return $ Yield file (h, fdat)
288− else return Stop
275+ else return Stop
289#endif
276#endif
290
277
278+-- | Read a directory emitting a stream with names of the children. Filter out
279+-- "." and ".." entries.
280+--
281+-- /Internal/
282+--
283+{-# INLINE reader #-}
284+reader :: (MonadIO m, MonadCatch m) => Unfold m FilePath FilePath
285+reader =
286+-- XXX Instead of using bracketIO for each iteration of the loop we should
287+-- instead yield a buffer of dir entries in each iteration and then use an
288+-- unfold and concat to flatten those entries. That should improve the
289+-- performance.
290+ UF.bracketIO openDirStream closeDirStream streamReader
291+ & UF.filter (\x -> x /= "." && x /= "..")
292+
291-- XXX We can use a more general mechanism to filter the contents of a
293-- XXX We can use a more general mechanism to filter the contents of a
292-- directory. We can just stat each child and pass on the stat information. We
294-- directory. We can just stat each child and pass on the stat information. We
293-- can then use that info to do a general filtering. "find" like filters can be
295-- can then use that info to do a general filtering. "find" like filters can be