summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-11-15 22:01:32 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-11-15 22:19:12 -0400
commitb76dc2d210889a77160a834e3849e3040ef69b12 (patch)
tree5a7903663715fdca64591957e46a3b776b16ccd4
parent5c5ff2cb78230ca6311d49dc2573579af49d8c37 (diff)
avoid space leak writing merge
This reduces the memory use of a merge by 1/3rd. The space leak was apparently because the whole update-index input was generated strictly, not lazily. I wondered if the change to ByteStrings contributed to this, due to the need to convert with L.pack here. But going back to the old code, I still see a much similar leak, and worse performance besides due to it not using ByteStrings. The fix is to just hPutStr the lines repeatedly. (Note the \0 is written separately, to avoid allocation overheads in adding it to the string.) The Git.pipeWrite interface is probably just wrong for any large inputs to git. This was the only place using it for input of any size. There is still at least one other space leak in the merge code.
-rw-r--r--Git/UnionMerge.hs9
1 files changed, 6 insertions, 3 deletions
diff --git a/Git/UnionMerge.hs b/Git/UnionMerge.hs
index 67e6fd951..460c76716 100644
--- a/Git/UnionMerge.hs
+++ b/Git/UnionMerge.hs
@@ -46,10 +46,13 @@ merge_index h repo bs =
- earlier ones, so the list can be generated from any combination of
- ls_tree, merge_trees, and merge_tree_index. -}
update_index :: Repo -> [String] -> IO ()
-update_index repo l = togit ["update-index", "-z", "--index-info"] (join "\0" l)
+update_index repo l = do
+ (p, h) <- hPipeTo "git" (toCommand $ Git.gitCommandLine params repo)
+ mapM_ (\s -> hPutStr h s >> hPutStr h "\0") l
+ hClose h
+ forceSuccess p
where
- togit ps content = pipeWrite (map Param ps) (L.pack content) repo
- >>= forceSuccess
+ params = map Param ["update-index", "-z", "--index-info"]
{- Generates a line suitable to be fed into update-index, to add
- a given file with a given sha. -}