work around catObjectStream polymorism perf
Breaking it up like this doesn't change perf, and lets another version be written in just a couple lines.
This commit is contained in:
parent
9f6bd6cc05
commit
cb6e19f4c5
1 changed files with 45 additions and 20 deletions
|
@ -21,6 +21,7 @@ module Git.CatFile (
|
||||||
catObjectDetails,
|
catObjectDetails,
|
||||||
catObjectMetaData,
|
catObjectMetaData,
|
||||||
catObjectStream,
|
catObjectStream,
|
||||||
|
catObjectStream',
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import System.IO
|
import System.IO
|
||||||
|
@ -283,12 +284,8 @@ parseCommit b = Commit
|
||||||
lt = fromIntegral (ord '<')
|
lt = fromIntegral (ord '<')
|
||||||
gt = fromIntegral (ord '>')
|
gt = fromIntegral (ord '>')
|
||||||
|
|
||||||
{- Uses cat-file to stream the contents of the files listed by lstree
|
{- Uses cat-file to stream the contents of the files as efficiently
|
||||||
- as efficiently as possible. This is much faster than querying it
|
- as possible. This is much faster than querying it repeatedly per file.
|
||||||
- repeatedly per file.
|
|
||||||
-
|
|
||||||
- (Note that, while a more polymorphic version of this can be written,
|
|
||||||
- this version is faster, possibly due to being less polymorphic.)
|
|
||||||
-}
|
-}
|
||||||
catObjectStream
|
catObjectStream
|
||||||
:: (MonadMask m, MonadIO m)
|
:: (MonadMask m, MonadIO m)
|
||||||
|
@ -297,8 +294,8 @@ catObjectStream
|
||||||
-> Repo
|
-> Repo
|
||||||
-> (IO (Maybe (TopFilePath, Maybe L.ByteString)) -> m ())
|
-> (IO (Maybe (TopFilePath, Maybe L.ByteString)) -> m ())
|
||||||
-> m ()
|
-> m ()
|
||||||
catObjectStream l want repo a = assertLocal repo $ do
|
catObjectStream l want repo a = withCatObjectStream repo feeder $
|
||||||
bracketIO start stop $ \(mv, _, _, hout, _) -> a (reader mv hout)
|
\mv hout -> a (catObjectReader mv hout)
|
||||||
where
|
where
|
||||||
feeder mv h = do
|
feeder mv h = do
|
||||||
forM_ l $ \ti ->
|
forM_ l $ \ti ->
|
||||||
|
@ -309,7 +306,26 @@ catObjectStream l want repo a = assertLocal repo $ do
|
||||||
S8.hPutStrLn h (fromRef' sha)
|
S8.hPutStrLn h (fromRef' sha)
|
||||||
hClose h
|
hClose h
|
||||||
|
|
||||||
reader mv h = ifM (hIsEOF h)
|
{- While this variant could be combined with catObjectStream into a
|
||||||
|
- more polymorphic function, the specialization of both is important for
|
||||||
|
- performance. -}
|
||||||
|
catObjectStream'
|
||||||
|
:: (MonadMask m, MonadIO m)
|
||||||
|
=> [(RawFilePath, Sha, FileMode)]
|
||||||
|
-> Repo
|
||||||
|
-> (IO (Maybe (RawFilePath, Maybe L.ByteString)) -> m ())
|
||||||
|
-> m ()
|
||||||
|
catObjectStream' l repo a = withCatObjectStream repo feeder $
|
||||||
|
\mv hout -> a (catObjectReader mv hout)
|
||||||
|
where
|
||||||
|
feeder mv h = do
|
||||||
|
forM_ l $ \(f, sha, _) -> do
|
||||||
|
liftIO $ atomically $ snocTList mv (sha, f)
|
||||||
|
S8.hPutStrLn h (fromRef' sha)
|
||||||
|
hClose h
|
||||||
|
|
||||||
|
catObjectReader :: TList (Ref, a) -> Handle -> IO (Maybe (a, Maybe L.ByteString))
|
||||||
|
catObjectReader mv h = ifM (hIsEOF h)
|
||||||
( return Nothing
|
( return Nothing
|
||||||
, do
|
, do
|
||||||
(sha, f) <- liftIO $ atomically $ headTList mv
|
(sha, f) <- liftIO $ atomically $ headTList mv
|
||||||
|
@ -322,6 +338,15 @@ catObjectStream l want repo a = assertLocal repo $ do
|
||||||
Nothing -> error $ "unknown response from git cat-file " ++ show resp
|
Nothing -> error $ "unknown response from git cat-file " ++ show resp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
withCatObjectStream
|
||||||
|
:: (MonadMask m, MonadIO m)
|
||||||
|
=> Repo
|
||||||
|
-> (TList a -> Handle -> IO ())
|
||||||
|
-> (TList a -> Handle -> m ())
|
||||||
|
-> m ()
|
||||||
|
withCatObjectStream repo feeder reader = assertLocal repo $
|
||||||
|
bracketIO start stop $ \(mv, _, _, hout, _) -> reader mv hout
|
||||||
|
where
|
||||||
params =
|
params =
|
||||||
[ Param "cat-file"
|
[ Param "cat-file"
|
||||||
, Param ("--batch=" ++ batchFormat)
|
, Param ("--batch=" ++ batchFormat)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue