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] then Database.Keys.addInodeCaches key [srcic, destic]
else Database.Keys.addInodeCaches key [srcic] else Database.Keys.addInodeCaches key [srcic]
return LinkAnnexNoop return LinkAnnexNoop
Nothing -> ifM (linkOrCopy key src dest destmode) Nothing -> linkOrCopy key src dest destmode >>= \case
( do Nothing -> failed
Just r -> do
case fromto of case fromto of
From -> thawContent dest From -> thawContent dest
To -> do To -> case r of
s <- liftIO $ getFileStatus dest Copied -> freezeContent dest
unless (linkCount s > 1) $ Linked -> noop
freezeContent dest
checksrcunchanged checksrcunchanged
, failed
)
where where
failed = do failed = do
Database.Keys.addInodeCaches key [srcic] 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] boolSystem "sh" [Param "-c", Param $ gencmd basecmd]
gencmd = massReplace [ ("%file", shellEscape file) ] gencmd = massReplace [ ("%file", shellEscape file) ]
data LinkedOrCopied = Linked | Copied
{- Hard links or copies src to dest, which must not already exist. {- 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 - 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 - execute bit will be set. The mode is not fully copied over because
- git doesn't support file modes beyond execute. - 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 = 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 linkOrCopy' canhardlink key src dest destmode
| maybe False isExecutable destmode = copy =<< getstat | maybe False isExecutable destmode = copy =<< getstat
| otherwise = catchBoolIO $ | otherwise = catchDefaultIO Nothing $
ifM canhardlink ifM canhardlink
( hardlink ( hardlink
, copy =<< getstat , copy =<< getstat
@ -58,9 +60,12 @@ linkOrCopy' canhardlink key src dest destmode
s <- getstat s <- getstat
if linkCount s > 1 if linkCount s > 1
then copy s 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) `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 getstat = liftIO $ getFileStatus src
{- Checks disk space before copying. -} {- 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 destmode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus f
liftIO $ nukeFile f liftIO $ nukeFile f
(ic, populated) <- replaceFile f $ \tmp -> do (ic, populated) <- replaceFile f $ \tmp -> do
ok <- linkOrCopy k obj tmp destmode ok <- linkOrCopy k obj tmp destmode >>= \case
if ok Just _ -> thawContent tmp >> return True
then thawContent tmp Nothing -> liftIO (writePointerFile tmp k destmode) >> return False
else liftIO $ writePointerFile tmp k destmode
ic <- withTSDelta (liftIO . genInodeCache tmp) ic <- withTSDelta (liftIO . genInodeCache tmp)
return (ic, ok) return (ic, ok)
maybe noop (restagePointerFile restage f) ic maybe noop (restagePointerFile restage f) ic

View file

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