diff options
author | Joey Hess <joeyh@joeyh.name> | 2015-04-14 15:35:15 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2015-04-14 15:35:15 -0400 |
commit | 513b3a639796b06828570b6da6b049095abd5b83 (patch) | |
tree | adc204e55854d1d5d4f75689ea17fa9624142872 /Command | |
parent | cd4304b64943ba55ffc8beac47796affc5405fd8 (diff) | |
parent | 1029cba6ac006b34053f3f96cbee9ecafe8cc1ae (diff) |
Merge branch 'master' into concurrentprogress
Conflicts:
debian/changelog
Diffstat (limited to 'Command')
-rw-r--r-- | Command/Info.hs | 124 |
1 files changed, 87 insertions, 37 deletions
diff --git a/Command/Info.hs b/Command/Info.hs index db5953050..b7cb3232f 100644 --- a/Command/Info.hs +++ b/Command/Info.hs @@ -10,7 +10,7 @@ module Command.Info where import "mtl" Control.Monad.State.Strict -import qualified Data.Map as M +import qualified Data.Map.Strict as M import Text.JSON import Data.Tuple import Data.Ord @@ -66,7 +66,7 @@ instance Show Variance where data StatInfo = StatInfo { presentData :: Maybe KeyData , referencedData :: Maybe KeyData - , remoteData :: M.Map UUID KeyData + , repoData :: M.Map UUID KeyData , numCopiesStats :: Maybe NumCopiesStats } @@ -77,7 +77,7 @@ emptyStatInfo = StatInfo Nothing Nothing M.empty Nothing type StatState = StateT StatInfo Annex cmd :: [Command] -cmd = [noCommit $ dontCheck repoExists $ withOptions (jsonOption : annexedMatchingOptions) $ +cmd = [noCommit $ dontCheck repoExists $ withOptions (jsonOption : bytesOption : annexedMatchingOptions) $ command "info" (paramOptional $ paramRepeating paramItem) seek SectionQuery "shows information about the specified item or the repository as a whole"] @@ -156,9 +156,9 @@ selStats fast_stats slow_stats = do global_fast_stats :: [Stat] global_fast_stats = [ repository_mode - , remote_list Trusted - , remote_list SemiTrusted - , remote_list UnTrusted + , repo_list Trusted + , repo_list SemiTrusted + , repo_list UnTrusted , transfer_list , disk_size ] @@ -184,6 +184,7 @@ dir_fast_stats = dir_slow_stats :: [FilePath -> Stat] dir_slow_stats = [ const numcopies_stats + , const reposizes_stats ] file_stats :: FilePath -> Key -> [Stat] @@ -245,8 +246,8 @@ repository_mode = simpleStat "repository mode" $ lift $ ) ) -remote_list :: TrustLevel -> Stat -remote_list level = stat n $ nojson $ lift $ do +repo_list :: TrustLevel -> Stat +repo_list level = stat n $ nojson $ lift $ do us <- filter (/= NoUUID) . M.keys <$> (M.union <$> uuidMap <*> remoteMap Remote.name) rs <- fst <$> trustPartition level us @@ -290,7 +291,7 @@ local_annex_keys = stat "local annex keys" $ json show $ local_annex_size :: Stat local_annex_size = simpleStat "local annex size" $ - showSizeKeys <$> cachedPresentData + lift . showSizeKeys =<< cachedPresentData remote_annex_keys :: UUID -> Stat remote_annex_keys u = stat "remote annex keys" $ json show $ @@ -298,7 +299,7 @@ remote_annex_keys u = stat "remote annex keys" $ json show $ remote_annex_size :: UUID -> Stat remote_annex_size u = simpleStat "remote annex size" $ - showSizeKeys <$> cachedRemoteData u + lift . showSizeKeys =<< cachedRemoteData u known_annex_files :: Stat known_annex_files = stat "annexed files in working tree" $ json show $ @@ -306,7 +307,7 @@ known_annex_files = stat "annexed files in working tree" $ json show $ known_annex_size :: Stat known_annex_size = simpleStat "size of annexed files in working tree" $ - showSizeKeys <$> cachedReferencedData + lift . showSizeKeys =<< cachedReferencedData tmp_size :: Stat tmp_size = staleSize "temporary object directory size" gitAnnexTmpObjectDir @@ -315,7 +316,7 @@ bad_data_size :: Stat bad_data_size = staleSize "bad keys size" gitAnnexBadDir key_size :: Key -> Stat -key_size k = simpleStat "size" $ pure $ showSizeKeys $ foldKeys [k] +key_size k = simpleStat "size" $ lift $ showSizeKeys $ foldKeys [k] key_name :: Key -> Stat key_name k = simpleStat "key" $ pure $ key2file k @@ -331,7 +332,8 @@ bloom_info = simpleStat "bloom filter size" $ do -- Two bloom filters are used at the same time, so double the size -- of one. - size <- roughSize memoryUnits False . (* 2) . fromIntegral . fst <$> + sizer <- lift mkSizer + size <- sizer memoryUnits False . (* 2) . fromIntegral . fst <$> lift Command.Unused.bloomBitsHashes return $ size ++ note @@ -358,13 +360,14 @@ disk_size = simpleStat "available local disk space" $ lift $ calcfree <$> (annexDiskReserve <$> Annex.getGitConfig) <*> inRepo (getDiskFree . gitAnnexDir) + <*> mkSizer where - calcfree reserve (Just have) = unwords - [ roughSize storageUnits False $ nonneg $ have - reserve - , "(+" ++ roughSize storageUnits False reserve + calcfree reserve (Just have) sizer = unwords + [ sizer storageUnits False $ nonneg $ have - reserve + , "(+" ++ sizer storageUnits False reserve , "reserved)" ] - calcfree _ _ = "unknown" + calcfree _ _ _ = "unknown" nonneg x | x >= 0 = x @@ -389,6 +392,26 @@ numcopies_stats = stat "numcopies stats" $ nojson $ . map (\(variance, count) -> show variance ++ ": " ++ show count) . sortBy (flip (comparing snd)) . M.toList +reposizes_stats :: Stat +reposizes_stats = stat "repositories containing these files" $ nojson $ + calc + <$> lift uuidDescriptions + <*> lift mkSizer + <*> cachedRepoData + where + calc descm sizer = multiLine + . format + . map (\(u, d) -> line descm sizer u d) + . sortBy (flip (comparing (sizeKeys . snd))) . M.toList + line descm sizer u d = (sz, fromUUID u ++ " -- " ++ desc) + where + sz = sizer storageUnits True (sizeKeys d) + desc = fromMaybe "" (M.lookup u descm) + format l = map (\(c1, c2) -> lpad maxc1 c1 ++ ": " ++ c2 ) l + where + maxc1 = maximum (map (length . fst) l) + lpad n s = (replicate (n - length s) ' ') ++ s + cachedPresentData :: StatState KeyData cachedPresentData = do s <- get @@ -402,11 +425,11 @@ cachedPresentData = do cachedRemoteData :: UUID -> StatState KeyData cachedRemoteData u = do s <- get - case M.lookup u (remoteData s) of + case M.lookup u (repoData s) of Just v -> return v Nothing -> do v <- foldKeys <$> lift (loggedKeysFor u) - put s { remoteData = M.insert u v (remoteData s) } + put s { repoData = M.insert u v (repoData s) } return v cachedReferencedData :: StatState KeyData @@ -424,17 +447,21 @@ cachedReferencedData = do cachedNumCopiesStats :: StatState (Maybe NumCopiesStats) cachedNumCopiesStats = numCopiesStats <$> get +-- currently only available for directory info +cachedRepoData :: StatState (M.Map UUID KeyData) +cachedRepoData = repoData <$> get + getDirStatInfo :: FilePath -> Annex StatInfo getDirStatInfo dir = do fast <- Annex.getState Annex.fast matcher <- Limit.getMatcher - (presentdata, referenceddata, numcopiesstats) <- + (presentdata, referenceddata, numcopiesstats, repodata) <- Command.Unused.withKeysFilesReferencedIn dir initial (update matcher fast) - return $ StatInfo (Just presentdata) (Just referenceddata) M.empty (Just numcopiesstats) + return $ StatInfo (Just presentdata) (Just referenceddata) repodata (Just numcopiesstats) where - initial = (emptyKeyData, emptyKeyData, emptyNumCopiesStats) - update matcher fast key file vs@(presentdata, referenceddata, numcopiesstats) = + initial = (emptyKeyData, emptyKeyData, emptyNumCopiesStats, M.empty) + update matcher fast key file vs@(presentdata, referenceddata, numcopiesstats, repodata) = ifM (matcher $ MatchingFile $ FileInfo file file) ( do !presentdata' <- ifM (inAnnex key) @@ -442,10 +469,13 @@ getDirStatInfo dir = do , return presentdata ) let !referenceddata' = addKey key referenceddata - !numcopiesstats' <- if fast - then return numcopiesstats - else updateNumCopiesStats key file numcopiesstats - return $! (presentdata', referenceddata', numcopiesstats') + (!numcopiesstats', !repodata') <- if fast + then return (numcopiesstats, repodata) + else do + locs <- Remote.keyLocations key + nc <- updateNumCopiesStats file numcopiesstats locs + return (nc, updateRepoData key locs repodata) + return $! (presentdata', referenceddata', numcopiesstats', repodata') , return vs ) @@ -465,22 +495,32 @@ addKey key (KeyData count size unknownsize backends) = {- All calculations strict to avoid thunks when repeatedly - applied to many keys. -} !count' = count + 1 - !backends' = M.insertWith' (+) (keyBackendName key) 1 backends + !backends' = M.insertWith (+) (keyBackendName key) 1 backends !size' = maybe size (+ size) ks !unknownsize' = maybe (unknownsize + 1) (const unknownsize) ks ks = keySize key -updateNumCopiesStats :: Key -> FilePath -> NumCopiesStats -> Annex NumCopiesStats -updateNumCopiesStats key file (NumCopiesStats m) = do - !variance <- Variance <$> numCopiesCheck file key (-) - let !m' = M.insertWith' (+) variance 1 m +updateRepoData :: Key -> [UUID] -> M.Map UUID KeyData -> M.Map UUID KeyData +updateRepoData key locs m = m' + where + !m' = M.unionWith (\_old new -> new) m $ + M.fromList $ zip locs (map update locs) + update loc = addKey key (fromMaybe emptyKeyData $ M.lookup loc m) + +updateNumCopiesStats :: FilePath -> NumCopiesStats -> [UUID] -> Annex NumCopiesStats +updateNumCopiesStats file (NumCopiesStats m) locs = do + have <- trustExclude UnTrusted locs + !variance <- Variance <$> numCopiesCheck' file (-) have + let !m' = M.insertWith (+) variance 1 m let !ret = NumCopiesStats m' return ret -showSizeKeys :: KeyData -> String -showSizeKeys d = total ++ missingnote +showSizeKeys :: KeyData -> Annex String +showSizeKeys d = do + sizer <- mkSizer + return $ total sizer ++ missingnote where - total = roughSize storageUnits False $ sizeKeys d + total sizer = sizer storageUnits False $ sizeKeys d missingnote | unknownSizeKeys d == 0 = "" | otherwise = aside $ @@ -494,8 +534,9 @@ staleSize label dirspec = go =<< lift (dirKeys dirspec) go keys = onsize =<< sum <$> keysizes keys onsize 0 = nostat onsize size = stat label $ - json (++ aside "clean up with git-annex unused") $ - return $ roughSize storageUnits False size + json (++ aside "clean up with git-annex unused") $ do + sizer <- lift mkSizer + return $ sizer storageUnits False size keysizes keys = do dir <- lift $ fromRepo dirspec liftIO $ forM keys $ \k -> catchDefaultIO 0 $ @@ -506,3 +547,12 @@ aside s = " (" ++ s ++ ")" multiLine :: [String] -> String multiLine = concatMap (\l -> "\n\t" ++ l) + +mkSizer :: Annex ([Unit] -> Bool -> ByteSize -> String) +mkSizer = ifM (getOptionFlag bytesOption) + ( return (const $ const show) + , return roughSize + ) + +bytesOption :: Option +bytesOption = flagOption [] "bytes" "display file sizes in bytes" |