add back git-annex branch read cache

The cache was removed way back in 2012,
commit 3417c55189

Then I forgot I had removed it! I remember clearly multiple times when I
thought, "this reads the same data twice, but the cache will avoid that
being very expensive".

The reason it was removed was it messed up the assistant noticing when
other processes made changes. That same kind of problem has recently
been addressed when adding the optimisation to avoid reading the journal
unnecessarily.

Indeed, enableInteractiveJournalAccess is run in just the
right places, so can just piggyback on it to know when it's not safe
to use the cache.
This commit is contained in:
Joey Hess 2020-07-06 12:09:53 -04:00
parent 9a2fbc2ea8
commit e72ec8b9b2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
8 changed files with 68 additions and 19 deletions

View file

@ -1,6 +1,6 @@
{- git-annex branch state management
-
- Runtime state about the git-annex branch.
- Runtime state about the git-annex branch, and a small cache.
-
- Copyright 2011-2020 Joey Hess <id@joeyh.name>
-
@ -13,6 +13,8 @@ import Annex.Common
import Types.BranchState
import qualified Annex
import qualified Data.ByteString.Lazy as L
getState :: Annex BranchState
getState = Annex.getState Annex.branchstate
@ -45,7 +47,7 @@ runUpdateOnce a = do
let stf = \st' -> st'
{ branchUpdated = True
, journalIgnorable = journalstaged
&& not (journalNeverIgnorable st')
&& not (needInteractiveAccess st')
}
changeState stf
return (stf st)
@ -76,7 +78,32 @@ journalChanged = do
- and needs to always notice changes made to the journal by other
- processes, this disables optimisations that avoid normally reading the
- journal.
-
- It also avoids using the cache, so changes committed by other processes
- will be seen.
-}
enableInteractiveJournalAccess :: Annex ()
enableInteractiveJournalAccess = changeState $
\s -> s { journalNeverIgnorable = True }
enableInteractiveBranchAccess :: Annex ()
enableInteractiveBranchAccess = changeState $
\s -> s { needInteractiveAccess = True }
setCache :: RawFilePath -> L.ByteString -> Annex ()
setCache file content = changeState $ \s -> s
{ cachedFile = Just file
, cachedContent = content
}
getCache :: RawFilePath -> Annex (Maybe L.ByteString)
getCache file = go <$> getState
where
go state
| cachedFile state == Just file
&& not (needInteractiveAccess state) =
Just (cachedContent state)
| otherwise = Nothing
invalidateCache :: Annex ()
invalidateCache = changeState $ \s -> s
{ cachedFile = Nothing
, cachedContent = mempty
}