optimize index updating

The last branch ref that the index was updated to is stored in
.git/annex/index.lck, and the index only updated when the current
branch ref differs.

(The .lck file should later be used for locking too.)

Some more optimization is still needed, since there is some redundancy in
calls to git show-ref.
This commit is contained in:
Joey Hess 2011-12-11 16:11:13 -04:00
parent 8680c415de
commit cfbbda99f4
4 changed files with 52 additions and 14 deletions

View file

@ -61,9 +61,26 @@ mergeIndex branches = do
inRepo $ \g -> Git.UnionMerge.merge_index h g branches inRepo $ \g -> Git.UnionMerge.merge_index h g branches
{- Updates the branch's index to reflect the current contents of the branch. {- Updates the branch's index to reflect the current contents of the branch.
- Any changes staged in the index will be preserved. -} - Any changes staged in the index will be preserved.
-
- Compares the ref stored in the lock file with the current
- ref of the branch to see if an update is needed.
-}
updateIndex :: Annex () updateIndex :: Annex ()
updateIndex = withIndex $ mergeIndex [fullname] updateIndex = do
lock <- fromRepo gitAnnexIndexLock
lockref <- firstRef <$> liftIO (catchDefaultIO (readFileStrict lock) "")
branchref <- getRef fullname
when (lockref /= branchref) $ do
withIndex $ mergeIndex [fullname]
setIndexRef branchref
{- Record that the branch's index has been updated to correspond to a
- given ref of the branch. -}
setIndexRef :: Git.Ref -> Annex ()
setIndexRef ref = do
lock <- fromRepo gitAnnexIndexLock
liftIO $ writeFile lock $ show ref ++ "\n"
{- Runs an action using the branch's index file. -} {- Runs an action using the branch's index file. -}
withIndex :: Annex a -> Annex a withIndex :: Annex a -> Annex a
@ -109,12 +126,13 @@ getCache file = getState >>= go
{- Creates the branch, if it does not already exist. -} {- Creates the branch, if it does not already exist. -}
create :: Annex () create :: Annex ()
create = unlessM hasBranch $ do create = unlessM hasBranch $ hasOrigin >>= go >>= setIndexRef
e <- hasOrigin where
if e go True = do
then inRepo $ Git.run "branch" inRepo $ Git.run "branch"
[Param $ show name, Param $ show originname] [Param $ show name, Param $ show originname]
else withIndex' True $ getRef fullname
go False = withIndex' True $
inRepo $ Git.commit "branch created" fullname [] inRepo $ Git.commit "branch created" fullname []
{- Stages the journal, and commits staged changes to the branch. -} {- Stages the journal, and commits staged changes to the branch. -}
@ -122,7 +140,8 @@ commit :: String -> Annex ()
commit message = whenM journalDirty $ lockJournal $ do commit message = whenM journalDirty $ lockJournal $ do
updateIndex updateIndex
stageJournalFiles stageJournalFiles
withIndex $ inRepo $ Git.commit message fullname [fullname] withIndex $
setIndexRef =<< inRepo (Git.commit message fullname [fullname])
{- Ensures that the branch and index are is up-to-date; should be {- Ensures that the branch and index are is up-to-date; should be
- called before data is read from it. Runs only once per git-annex run. - called before data is read from it. Runs only once per git-annex run.
@ -159,8 +178,9 @@ update = onceonly $ do
showSideAction merge_desc showSideAction merge_desc
mergeIndex branches mergeIndex branches
ff <- if dirty then return False else tryFastForwardTo refs ff <- if dirty then return False else tryFastForwardTo refs
unless ff $ inRepo $ unless ff $
Git.commit merge_desc fullname (nub $ fullname:refs) setIndexRef =<<
inRepo (Git.commit merge_desc fullname (nub $ fullname:refs))
invalidateCache invalidateCache
where where
onceonly a = unlessM (branchUpdated <$> getState) $ do onceonly a = unlessM (branchUpdated <$> getState) $ do
@ -253,6 +273,18 @@ siblingBranches = do
gen l = (Git.Ref $ head l, Git.Ref $ last l) gen l = (Git.Ref $ head l, Git.Ref $ last l)
uref (a, _) (b, _) = a == b uref (a, _) (b, _) = a == b
{- Get the ref of a branch. -}
getRef :: Git.Ref -> Annex Git.Ref
getRef branch = firstRef . L.unpack <$> showref
where
showref = inRepo $ Git.pipeRead [Param "show-ref",
Param "--hash", -- get the hash
Param "--verify", -- only exact match
Param $ show branch]
firstRef :: String-> Git.Ref
firstRef = Git.Ref . takeWhile (/= '\n')
{- Applies a function to modifiy the content of a file. {- Applies a function to modifiy the content of a file.
- -
- Note that this does not cause the branch to be merged, it only - Note that this does not cause the branch to be merged, it only

5
Git.hs
View file

@ -463,8 +463,8 @@ shaSize :: Int
shaSize = 40 shaSize = 40
{- Commits the index into the specified branch (or other ref), {- Commits the index into the specified branch (or other ref),
- with the specified parent refs. -} - with the specified parent refs, and returns the new ref -}
commit :: String -> Ref -> [Ref] -> Repo -> IO () commit :: String -> Ref -> [Ref] -> Repo -> IO Ref
commit message newref parentrefs repo = do commit message newref parentrefs repo = do
tree <- getSha "write-tree" $ asString $ tree <- getSha "write-tree" $ asString $
pipeRead [Param "write-tree"] repo pipeRead [Param "write-tree"] repo
@ -473,6 +473,7 @@ commit message newref parentrefs repo = do
(map Param $ ["commit-tree", show tree] ++ ps) (map Param $ ["commit-tree", show tree] ++ ps)
(L.pack message) repo (L.pack message) repo
run "update-ref" [Param $ show newref, Param $ show sha] repo run "update-ref" [Param $ show newref, Param $ show sha] repo
return sha
where where
ignorehandle a = snd <$> a ignorehandle a = snd <$> a
asString a = L.unpack <$> a asString a = L.unpack <$> a

View file

@ -21,6 +21,7 @@ module Locations (
gitAnnexJournalDir, gitAnnexJournalDir,
gitAnnexJournalLock, gitAnnexJournalLock,
gitAnnexIndex, gitAnnexIndex,
gitAnnexIndexLock,
isLinkToAnnex, isLinkToAnnex,
annexHashes, annexHashes,
hashDirMixed, hashDirMixed,
@ -136,6 +137,10 @@ gitAnnexJournalLock r = gitAnnexDir r </> "journal.lck"
gitAnnexIndex :: Git.Repo -> FilePath gitAnnexIndex :: Git.Repo -> FilePath
gitAnnexIndex r = gitAnnexDir r </> "index" gitAnnexIndex r = gitAnnexDir r </> "index"
{- Lock file for .git/annex/index. -}
gitAnnexIndexLock :: Git.Repo -> FilePath
gitAnnexIndexLock r = gitAnnexDir r </> "index.lck"
{- Checks a symlink target to see if it appears to point to annexed content. -} {- Checks a symlink target to see if it appears to point to annexed content. -}
isLinkToAnnex :: FilePath -> Bool isLinkToAnnex :: FilePath -> Bool
isLinkToAnnex s = ("/.git/" ++ objectDir) `isInfixOf` s isLinkToAnnex s = ("/.git/" ++ objectDir) `isInfixOf` s

View file

@ -42,5 +42,5 @@ main = do
_ <- Git.useIndex (tmpIndex g) _ <- Git.useIndex (tmpIndex g)
setup g setup g
Git.UnionMerge.merge aref bref g Git.UnionMerge.merge aref bref g
Git.commit "union merge" newref [aref, bref] g _ <- Git.commit "union merge" newref [aref, bref] g
cleanup g cleanup g