diff options
-rw-r--r-- | Command.hs | 2 | ||||
-rw-r--r-- | Command/Status.hs | 78 | ||||
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | doc/devblog/day_10__lazy_Sunday.mdwn | 23 | ||||
-rw-r--r-- | doc/git-annex.mdwn | 4 |
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` |