aboutsummaryrefslogtreecommitdiff
path: root/Assistant
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-03-11 12:56:47 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-03-11 12:56:47 -0400
commit8c5d75f6fbde080f3e3ad0766b5f3a1d4cee8d81 (patch)
treea74c92d131733dc0df454f71c6372edacc745aa8 /Assistant
parentde5c24518b878322cd883ab4d4cfb46d07dbdce3 (diff)
detect renames during commit, and .. um, do nothing special because it's lunch time
But I'm well set up to fast-track direct mode adds for renames now.
Diffstat (limited to 'Assistant')
-rw-r--r--Assistant/Threads/Committer.hs53
1 files changed, 51 insertions, 2 deletions
diff --git a/Assistant/Threads/Committer.hs b/Assistant/Threads/Committer.hs
index b336f650b..5be190c4a 100644
--- a/Assistant/Threads/Committer.hs
+++ b/Assistant/Threads/Committer.hs
@@ -32,11 +32,15 @@ import Config
import Annex.Exception
import Annex.Content
import Annex.Link
+import Annex.CatFile
import qualified Annex
+import Utility.InodeCache
+import Annex.Content.Direct
import Data.Time.Clock
import Data.Tuple.Utils
import qualified Data.Set as S
+import qualified Data.Map as M
import Data.Either
import Control.Concurrent
@@ -90,9 +94,13 @@ waitChangeTime a = runEvery (Seconds 1) <~> do
{- Did we perhaps only get one of the AddChange and RmChange pair
- that make up a rename? -}
lonelychange [(PendingAddChange _ _)] = True
- lonelychange [(Change { changeInfo = i })] | i == RmChange = True
+ lonelychange [c] | isRmChange c = True
lonelychange _ = False
+isRmChange :: Change -> Bool
+isRmChange (Change { changeInfo = i }) | i == RmChange = True
+isRmChange _ = False
+
{- An amount of time that is hopefully imperceptably short for humans,
- while long enough for a computer to get some work done.
- Note that 0.001 is a little too short for rename change batching to
@@ -200,7 +208,9 @@ handleAdds delayadd cs = returnWhen (null incomplete) $ do
refillChanges postponed
returnWhen (null toadd) $ do
- added <- catMaybes <$> forM toadd add
+ added <- catMaybes <$> if direct
+ then adddirect toadd
+ else forM toadd add
if DirWatcher.eventsCoalesce || null added || direct
then return $ added ++ otherchanges
else do
@@ -238,6 +248,45 @@ handleAdds delayadd cs = returnWhen (null incomplete) $ do
ret _ = (True, Nothing)
add _ = return Nothing
+ {- In direct mode, avoid overhead of re-injesting a renamed
+ - file, by examining the other Changes to see if a removed
+ - file has the same InodeCache as the new file. If so,
+ - we can just update bookkeeping, and stage the file in git.
+ -}
+ adddirect :: [Change] -> Assistant [Maybe Change]
+ adddirect toadd = do
+ ct <- liftAnnex compareInodeCachesWith
+ m <- liftAnnex $ removedKeysMap ct cs
+ if M.null m
+ then forM toadd add
+ else forM toadd $ \c -> do
+ mcache <- liftIO $ genInodeCache $ changeFile c
+ case mcache of
+ Nothing -> add c
+ Just cache ->
+ case M.lookup (inodeCacheToKey ct cache) m of
+ Nothing -> add c
+ Just k -> fastadd c k cache
+
+ fastadd :: Change -> Key -> InodeCache -> Assistant (Maybe Change)
+ fastadd change key cache = do
+ -- TODO do fast method
+ debug ["rename detected", show change, show key, show cache]
+ add change
+ --return $ Just $ finishedChange change key
+
+ removedKeysMap :: InodeComparisonType -> [Change] -> Annex (M.Map InodeCacheKey Key)
+ removedKeysMap ct l = do
+ mks <- forM (filter isRmChange l) $ \c ->
+ catKeyFile $ changeFile c
+ M.fromList . catMaybes <$> forM (catMaybes mks) mkpair
+ where
+ mkpair k = do
+ mcache <- recordedInodeCache k
+ case mcache of
+ Just cache -> return $ Just (inodeCacheToKey ct cache, k)
+ Nothing -> return Nothing
+
failedingest = do
liftAnnex showEndFail
return Nothing