check-ignore resource pool

Much like check-attr before.
This commit is contained in:
Joey Hess 2020-04-21 11:20:10 -04:00
parent 45fb7af21c
commit 04352ed9c5
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
7 changed files with 66 additions and 27 deletions

View file

@ -1,37 +1,57 @@
{- git check-ignore interface, with handle automatically stored in
- the Annex monad
-
- Copyright 2013 Joey Hess <id@joeyh.name>
- Copyright 2013-2020 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
module Annex.CheckIgnore (
checkIgnored,
checkIgnoreHandle,
checkIgnoreStop
checkIgnoreStop,
mkConcurrentCheckIgnoreHandle,
) where
import Annex.Common
import qualified Git.CheckIgnore as Git
import qualified Annex
import Utility.ResourcePool
import Types.Concurrency
import Annex.Concurrent.Utility
checkIgnored :: FilePath -> Annex Bool
checkIgnored file = go =<< checkIgnoreHandle
where
go h = liftIO $ Git.checkIgnored h file
checkIgnored file = withCheckIgnoreHandle $ \h ->
liftIO $ Git.checkIgnored h file
checkIgnoreHandle :: Annex Git.CheckIgnoreHandle
checkIgnoreHandle = maybe startup return =<< Annex.getState Annex.checkignorehandle
withCheckIgnoreHandle :: (Git.CheckIgnoreHandle -> Annex a) -> Annex a
withCheckIgnoreHandle a =
maybe mkpool go =<< Annex.getState Annex.checkignorehandle
where
startup = do
h <- inRepo Git.checkIgnoreStart
Annex.changeState $ \s -> s { Annex.checkignorehandle = Just h }
return h
go p = withResourcePool p start a
start = inRepo Git.checkIgnoreStart
mkpool = do
-- This only runs in non-concurrent code paths;
-- a concurrent pool is set up earlier when needed.
p <- mkResourcePoolNonConcurrent start
Annex.changeState $ \s -> s { Annex.checkignorehandle = Just p }
go p
mkConcurrentCheckIgnoreHandle :: Concurrency -> Annex (ResourcePool Git.CheckIgnoreHandle)
mkConcurrentCheckIgnoreHandle c =
Annex.getState Annex.checkignorehandle >>= \case
Just p@(ResourcePool {}) -> return p
_ -> mkResourcePool =<< liftIO (maxCheckIgnores c)
{- git check-ignore is typically CPU bound, and is not likely to be the main
- bottleneck for any command. So limit to the number of CPU cores, maximum,
- while respecting the -Jn value.
-}
maxCheckIgnores :: Concurrency -> IO Int
maxCheckIgnores = concurrencyUpToCpus
checkIgnoreStop :: Annex ()
checkIgnoreStop = maybe noop stop =<< Annex.getState Annex.checkignorehandle
where
stop h = do
liftIO $ Git.checkIgnoreStop h
stop p = do
liftIO $ freeResourcePool p Git.checkIgnoreStop
Annex.changeState $ \s -> s { Annex.checkignorehandle = Nothing }