optimisation: avoid stat call

This commit was sponsored by Paul Walmsley on Patreon.
This commit is contained in:
Joey Hess 2018-09-05 17:26:12 -04:00
parent 7407a80c27
commit fcff64f8bb
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 20 additions and 18 deletions

View file

@ -583,17 +583,15 @@ linkAnnex fromto key src (Just srcic) dest destmode =
then Database.Keys.addInodeCaches key [srcic, destic]
else Database.Keys.addInodeCaches key [srcic]
return LinkAnnexNoop
Nothing -> ifM (linkOrCopy key src dest destmode)
( do
Nothing -> linkOrCopy key src dest destmode >>= \case
Nothing -> failed
Just r -> do
case fromto of
From -> thawContent dest
To -> do
s <- liftIO $ getFileStatus dest
unless (linkCount s > 1) $
freezeContent dest
To -> case r of
Copied -> freezeContent dest
Linked -> noop
checksrcunchanged
, failed
)
where
failed = do
Database.Keys.addInodeCaches key [srcic]

View file

@ -29,6 +29,8 @@ secureErase file = maybe noop go =<< annexSecureEraseCommand <$> Annex.getGitCon
boolSystem "sh" [Param "-c", Param $ gencmd basecmd]
gencmd = massReplace [ ("%file", shellEscape file) ]
data LinkedOrCopied = Linked | Copied
{- Hard links or copies src to dest, which must not already exist.
-
- Only uses a hard link when annex.thin is enabled and when src is
@ -42,13 +44,13 @@ secureErase file = maybe noop go =<< annexSecureEraseCommand <$> Annex.getGitCon
- execute bit will be set. The mode is not fully copied over because
- git doesn't support file modes beyond execute.
-}
linkOrCopy :: Key -> FilePath -> FilePath -> Maybe FileMode -> Annex Bool
linkOrCopy :: Key -> FilePath -> FilePath -> Maybe FileMode -> Annex (Maybe LinkedOrCopied)
linkOrCopy = linkOrCopy' (annexThin <$> Annex.getGitConfig)
linkOrCopy' :: Annex Bool -> Key -> FilePath -> FilePath -> Maybe FileMode -> Annex Bool
linkOrCopy' :: Annex Bool -> Key -> FilePath -> FilePath -> Maybe FileMode -> Annex (Maybe LinkedOrCopied)
linkOrCopy' canhardlink key src dest destmode
| maybe False isExecutable destmode = copy =<< getstat
| otherwise = catchBoolIO $
| otherwise = catchDefaultIO Nothing $
ifM canhardlink
( hardlink
, copy =<< getstat
@ -58,9 +60,12 @@ linkOrCopy' canhardlink key src dest destmode
s <- getstat
if linkCount s > 1
then copy s
else liftIO (createLink src dest >> preserveGitMode dest destmode >> return True)
else liftIO (createLink src dest >> preserveGitMode dest destmode >> return (Just Linked))
`catchIO` const (copy s)
copy = checkedCopyFile' key src dest destmode
copy s = ifM (checkedCopyFile' key src dest destmode s)
( return (Just Copied)
, return Nothing
)
getstat = liftIO $ getFileStatus src
{- Checks disk space before copying. -}

View file

@ -32,10 +32,9 @@ populatePointerFile restage k obj f = go =<< liftIO (isPointerFile f)
destmode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus f
liftIO $ nukeFile f
(ic, populated) <- replaceFile f $ \tmp -> do
ok <- linkOrCopy k obj tmp destmode
if ok
then thawContent tmp
else liftIO $ writePointerFile tmp k destmode
ok <- linkOrCopy k obj tmp destmode >>= \case
Just _ -> thawContent tmp >> return True
Nothing -> liftIO (writePointerFile tmp k destmode) >> return False
ic <- withTSDelta (liftIO . genInodeCache tmp)
return (ic, ok)
maybe noop (restagePointerFile restage f) ic

View file

@ -85,7 +85,7 @@ linkKey file oldkey newkey = ifM (isJust <$> isAnnexLink file)
- and vulnerable to corruption. -}
( getViaTmpFromDisk RetrievalAllKeysSecure DefaultVerify newkey $ \tmp -> unVerified $ do
oldobj <- calcRepo (gitAnnexLocation oldkey)
linkOrCopy' (return True) newkey oldobj tmp Nothing
isJust <$> linkOrCopy' (return True) newkey oldobj tmp Nothing
, do
ic <- withTSDelta (liftIO . genInodeCache file)
{- The file being rekeyed is itself an unlocked file, so if