summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Command.hs2
-rw-r--r--Command/Status.hs78
-rw-r--r--debian/changelog2
-rw-r--r--doc/devblog/day_10__lazy_Sunday.mdwn23
-rw-r--r--doc/git-annex.mdwn4
5 files changed, 92 insertions, 17 deletions
diff --git a/Command.hs b/Command.hs
index fec733f72..2c157304f 100644
--- a/Command.hs
+++ b/Command.hs
@@ -111,7 +111,7 @@ numCopies file = do
Just n -> return $ Just n
Nothing -> readish <$> checkAttr "annex.numcopies" file
-numCopiesCheck :: FilePath -> Key -> (Int -> Int -> Bool) -> Annex Bool
+numCopiesCheck :: FilePath -> Key -> (Int -> Int -> v) -> Annex v
numCopiesCheck file key vs = do
numcopiesattr <- numCopies file
needed <- getNumCopies numcopiesattr
diff --git a/Command/Status.hs b/Command/Status.hs
index af85fcc2a..8872747fb 100644
--- a/Command/Status.hs
+++ b/Command/Status.hs
@@ -13,6 +13,7 @@ import "mtl" Control.Monad.State.Strict
import qualified Data.Map as M
import Text.JSON
import Data.Tuple
+import Data.Ord
import System.PosixCompat.Files
import Common.Annex
@@ -49,10 +50,23 @@ data KeyData = KeyData
, backendsKeys :: M.Map String Integer
}
+data NumCopiesStats = NumCopiesStats
+ { numCopiesVarianceMap :: M.Map Variance Integer
+ }
+
+newtype Variance = Variance Int
+ deriving (Eq, Ord)
+
+instance Show Variance where
+ show (Variance n)
+ | n >= 0 = "numcopies +" ++ show n
+ | otherwise = "numcopies " ++ show n
+
-- cached info that multiple Stats use
data StatInfo = StatInfo
{ presentData :: Maybe KeyData
, referencedData :: Maybe KeyData
+ , numCopiesStats :: Maybe NumCopiesStats
}
-- a state monad for running Stats in
@@ -77,19 +91,25 @@ start ps = do
globalStatus :: Annex ()
globalStatus = do
- fast <- Annex.getState Annex.fast
- let stats = if fast
- then global_fast_stats
- else global_fast_stats ++ global_slow_stats
+ stats <- selStats global_fast_stats global_slow_stats
showCustom "status" $ do
- evalStateT (mapM_ showStat stats) (StatInfo Nothing Nothing)
+ evalStateT (mapM_ showStat stats) (StatInfo Nothing Nothing Nothing)
return True
localStatus :: FilePath -> Annex ()
localStatus dir = showCustom (unwords ["status", dir]) $ do
- let stats = map (\s -> s dir) local_stats
+ stats <- selStats (tostats local_fast_stats) (tostats local_slow_stats)
evalStateT (mapM_ showStat stats) =<< getLocalStatInfo dir
return True
+ where
+ tostats = map (\s -> s dir)
+
+selStats :: [Stat] -> [Stat] -> Annex [Stat]
+selStats fast_stats slow_stats = do
+ fast <- Annex.getState Annex.fast
+ return $ if fast
+ then fast_stats
+ else fast_stats ++ slow_stats
{- Order is significant. Less expensive operations, and operations
- that share data go together.
@@ -116,14 +136,18 @@ global_slow_stats =
, bloom_info
, backend_usage
]
-local_stats :: [FilePath -> Stat]
-local_stats =
+local_fast_stats :: [FilePath -> Stat]
+local_fast_stats =
[ local_dir
, const local_annex_keys
, const local_annex_size
, const known_annex_keys
, const known_annex_size
]
+local_slow_stats :: [FilePath -> Stat]
+local_slow_stats =
+ [ const numcopies_stats
+ ]
stat :: String -> (String -> StatState String) -> Stat
stat desc a = return $ Just (desc, a desc)
@@ -255,6 +279,14 @@ backend_usage = stat "backend usage" $ nojson $
reverse $ sort $ map swap $ M.toList $
M.unionWith (+) x y
+numcopies_stats :: Stat
+numcopies_stats = stat "numcopies stats" $ nojson $
+ calc <$> (maybe M.empty numCopiesVarianceMap <$> cachedNumCopiesStats)
+ where
+ calc = multiLine
+ . map (\(variance, count) -> show variance ++ ": " ++ show count)
+ . reverse . sortBy (comparing snd) . M.toList
+
cachedPresentData :: StatState KeyData
cachedPresentData = do
s <- get
@@ -276,29 +308,40 @@ cachedReferencedData = do
put s { referencedData = Just v }
return v
+-- currently only available for local status
+cachedNumCopiesStats :: StatState (Maybe NumCopiesStats)
+cachedNumCopiesStats = numCopiesStats <$> get
+
getLocalStatInfo :: FilePath -> Annex StatInfo
getLocalStatInfo dir = do
+ fast <- Annex.getState Annex.fast
matcher <- Limit.getMatcher
- (presentdata, referenceddata) <-
+ (presentdata, referenceddata, numcopiesstats) <-
Command.Unused.withKeysFilesReferencedIn dir initial
- (update matcher)
- return $ StatInfo (Just presentdata) (Just referenceddata)
+ (update matcher fast)
+ return $ StatInfo (Just presentdata) (Just referenceddata) (Just numcopiesstats)
where
- initial = (emptyKeyData, emptyKeyData)
- update matcher key file vs@(presentdata, referenceddata) =
+ initial = (emptyKeyData, emptyKeyData, emptyNumCopiesStats)
+ update matcher fast key file vs@(presentdata, referenceddata, numcopiesstats) =
ifM (matcher $ FileInfo file file)
- ( (,)
+ ( (,,)
<$> ifM (inAnnex key)
( return $ addKey key presentdata
, return presentdata
)
<*> pure (addKey key referenceddata)
+ <*> if fast
+ then return numcopiesstats
+ else updateNumCopiesStats key file numcopiesstats
, return vs
)
emptyKeyData :: KeyData
emptyKeyData = KeyData 0 0 0 M.empty
+emptyNumCopiesStats :: NumCopiesStats
+emptyNumCopiesStats = NumCopiesStats $ M.empty
+
foldKeys :: [Key] -> KeyData
foldKeys = foldl' (flip addKey) emptyKeyData
@@ -314,6 +357,13 @@ addKey key (KeyData count size unknownsize backends) =
!unknownsize' = maybe (unknownsize + 1) (const unknownsize) ks
ks = keySize key
+updateNumCopiesStats :: Key -> FilePath -> NumCopiesStats -> Annex NumCopiesStats
+updateNumCopiesStats key file stats = do
+ variance <- Variance <$> numCopiesCheck file key (-)
+ return $ stats { numCopiesVarianceMap = update (numCopiesVarianceMap stats) variance }
+ where
+ update m variance = M.insertWith' (+) variance 1 m
+
showSizeKeys :: KeyData -> String
showSizeKeys d = total ++ missingnote
where
diff --git a/debian/changelog b/debian/changelog
index 26ee074ba..4ccf72e91 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,6 +11,8 @@ git-annex (4.20130912) UNRELEASED; urgency=low
* sync: Don't fail if the directory it is run in gets removed by the
sync.
* addurl: Fix quvi audodetection, broken in last release.
+ * status: In local mode, displays information about variance from configured
+ numcopies levels. (--fast avoids calculating these)
-- Joey Hess <joeyh@debian.org> Thu, 12 Sep 2013 12:14:46 -0400
diff --git a/doc/devblog/day_10__lazy_Sunday.mdwn b/doc/devblog/day_10__lazy_Sunday.mdwn
new file mode 100644
index 000000000..aa6a70918
--- /dev/null
+++ b/doc/devblog/day_10__lazy_Sunday.mdwn
@@ -0,0 +1,23 @@
+Fixed a typo that broke automatic youtube video support in `addurl`.
+
+----
+
+Now there's an easy way to get an overview of how close your repository
+is to meeting the configured numcopies settings (or when it exceeds them).
+
+<pre>
+# time git annex status .
+[...]
+numcopies stats:
+ numcopies +0: 6686
+ numcopies +1: 3793
+ numcopies +3: 3156
+ numcopies +2: 2743
+ numcopies -1: 1242
+ numcopies -4: 1098
+ numcopies -3: 1009
+ numcopies +4: 372
+</pre>
+
+This does make `git annex status` slow when run on a large directory tree,
+so --fast disables that.
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 3ce7b37f7..8eb633f75 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -577,7 +577,7 @@ subdirectories).
To only show the data that can be gathered quickly, use `--fast`.
- When a directory is specified, shows only an abbreviated status
+ When a directory is specified, shows a differently formatted status
display for that directory. In this mode, all of the file matching
options can be used to filter the files that will be included in
the status.
@@ -586,7 +586,7 @@ subdirectories).
would first like to see how much disk space that will use.
Then run:
- git annex status . --not --in here
+ git annex status --fast . --not --in here
* `map`