summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2010-10-10 12:31:14 -0400
committerGravatar Joey Hess <joey@kitenet.net>2010-10-10 12:32:15 -0400
commit7ad4a0bb7d4beb469f0aba017fae1ac48060e862 (patch)
tree72b2b1636baef54d17f36f27c196dec810a5fc66
parentf98fa53d7f6d851b8a1ae804c02780769c98e07c (diff)
log compaction
-rw-r--r--LocationLog.hs44
-rw-r--r--demo.log7
-rw-r--r--git-annex.hs2
3 files changed, 41 insertions, 12 deletions
diff --git a/LocationLog.hs b/LocationLog.hs
index 1523901df..028ceed5f 100644
--- a/LocationLog.hs
+++ b/LocationLog.hs
@@ -7,21 +7,19 @@
-
- Location tracking information is stored in `.git-annex/filename.log`.
- Repositories record their name and the date when they --get or --drop
- - a file's content. (Git is configured to use a union merge for this file,
- - so the lines may be in arbitrary order, but it will never conflict.)
+ - a file's content.
-
- A line of the log will look like: "date N reponame"
- Where N=1 when the repo has the file, and 0 otherwise.
- -
- - TOOD: compact logs, by storing only current presence infomation when
- - writing them.
- -
- - TODO: use ByteString
+ -
+ - Git is configured to use a union merge for this file,
+ - so the lines may be in arbitrary order, but it will never conflict.
-}
module LocationLog where
import Data.DateTime
+import qualified Data.Map as Map
import System.IO
import System.Directory
import Data.Char
@@ -81,12 +79,19 @@ readLog file = do
return []
{- Adds a LogLine to a log file -}
-writeLog :: String -> LogLine -> IO ()
-writeLog file line = do
+appendLog :: String -> LogLine -> IO ()
+appendLog file line = do
createDirectoryIfMissing True (parentDir file)
withFileLocked file AppendMode $ \h ->
hPutStrLn h $ show line
+{- Writes a set of lines to a log file -}
+writeLog :: String -> [LogLine] -> IO ()
+writeLog file lines = do
+ createDirectoryIfMissing True (parentDir file)
+ withFileLocked file WriteMode $ \h ->
+ hPutStr h $ unlines $ map show lines
+
{- Generates a new LogLine with the current date. -}
logNow :: LogStatus -> String -> IO LogLine
logNow status repo = do
@@ -112,3 +117,24 @@ fileLocations file = do
- is (or should still be) present. -}
filterPresent :: [LogLine] -> [LogLine]
filterPresent lines = error "unimplimented" -- TODO
+
+{- Compacts a set of logs, returning a subset that contains the current
+ - status. -}
+compactLog :: [LogLine] -> [LogLine]
+compactLog lines = compactLog' Map.empty lines
+compactLog' map [] = Map.elems map
+compactLog' map (l:ls) = compactLog' (mapLog map l) ls
+
+{- Inserts a log into a map of logs, if the log has better (ie, newer)
+ - information about a repo than the other logs in the map -}
+mapLog map log =
+ if (better)
+ then Map.insert (repo log) log map
+ else map
+ where
+ better = case (Map.lookup (repo log) map) of
+ -- <= used because two log entries could
+ -- have the same timestamp; if so the one that
+ -- is seen last should win.
+ Just l -> (date l <= date log)
+ Nothing -> True
diff --git a/demo.log b/demo.log
index 251a84c52..7a4263056 100644
--- a/demo.log
+++ b/demo.log
@@ -1,8 +1,11 @@
1286654242 1 repo
1286652724 0 foo
+1286656282 1 foo
+1286656282 0 repo
+1286656281 0 foo
+# some garbage, should be ignored
a a a
+
a 1 a
-1 a a
1286652724 1 foo
-1286656282 1 foo
-1286656282 0 repo
diff --git a/git-annex.hs b/git-annex.hs
index 66b9491bd..cae72f00d 100644
--- a/git-annex.hs
+++ b/git-annex.hs
@@ -7,4 +7,4 @@ import GitRepo
main = do
gitPrep
l <- readLog "demo.log"
- writeLog "demo2.log" $ l !! 0
+ writeLog "demo2.log" $ compactLog l