2014-01-23 19:09:43 +00:00
|
|
|
{- git-annex assistant unused files
|
|
|
|
-
|
2015-01-21 16:50:09 +00:00
|
|
|
- Copyright 2014 Joey Hess <id@joeyh.name>
|
2014-01-23 19:09:43 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2014-01-23 19:09:43 +00:00
|
|
|
-}
|
|
|
|
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
|
|
|
module Assistant.Unused where
|
|
|
|
|
|
|
|
import qualified Data.Map as M
|
|
|
|
|
|
|
|
import Assistant.Common
|
|
|
|
import qualified Git
|
|
|
|
import Logs.Unused
|
|
|
|
import Logs.Location
|
|
|
|
import Annex.Content
|
|
|
|
import Utility.DataUnits
|
|
|
|
import Utility.DiskFree
|
|
|
|
import Utility.HumanTime
|
|
|
|
import Utility.Tense
|
|
|
|
|
|
|
|
import Data.Time.Clock.POSIX
|
|
|
|
import qualified Data.Text as T
|
|
|
|
|
|
|
|
describeUnused :: Assistant (Maybe TenseText)
|
|
|
|
describeUnused = describeUnused' False
|
|
|
|
|
|
|
|
describeUnusedWhenBig :: Assistant (Maybe TenseText)
|
|
|
|
describeUnusedWhenBig = describeUnused' True
|
|
|
|
|
|
|
|
{- This uses heuristics: 1000 unused keys, or more unused keys
|
|
|
|
- than the remaining free disk space, or more than 1/10th the total
|
|
|
|
- disk space being unused keys all suggest a problem. -}
|
|
|
|
describeUnused' :: Bool -> Assistant (Maybe TenseText)
|
|
|
|
describeUnused' whenbig = liftAnnex $ go =<< readUnusedLog ""
|
|
|
|
where
|
|
|
|
go m = do
|
|
|
|
let num = M.size m
|
|
|
|
let diskused = foldl' sumkeysize 0 (M.keys m)
|
|
|
|
df <- forpath getDiskFree
|
|
|
|
disksize <- forpath getDiskSize
|
|
|
|
return $ if num == 0
|
|
|
|
then Nothing
|
|
|
|
else if not whenbig || moreused df diskused || tenthused disksize diskused
|
|
|
|
then Just $ tenseWords
|
|
|
|
[ UnTensed $ T.pack $ roughSize storageUnits False diskused
|
|
|
|
, Tensed "are" "were"
|
|
|
|
, "taken up by unused files"
|
|
|
|
]
|
|
|
|
else if num > 1000
|
|
|
|
then Just $ tenseWords
|
|
|
|
[ UnTensed $ T.pack $ show num ++ " unused files"
|
|
|
|
, Tensed "exist" "existed"
|
|
|
|
]
|
|
|
|
else Nothing
|
|
|
|
|
|
|
|
moreused Nothing _ = False
|
|
|
|
moreused (Just df) used = df <= used
|
|
|
|
|
|
|
|
tenthused Nothing _ = False
|
|
|
|
tenthused (Just disksize) used = used >= disksize `div` 10
|
|
|
|
|
2019-11-22 20:24:04 +00:00
|
|
|
sumkeysize s k = s + fromMaybe 0 (fromKey keySize k)
|
2014-01-23 19:09:43 +00:00
|
|
|
|
2019-12-09 17:49:05 +00:00
|
|
|
forpath a = inRepo $ liftIO . a . fromRawFilePath . Git.repoPath
|
2014-01-23 19:09:43 +00:00
|
|
|
|
|
|
|
{- With a duration, expires all unused files that are older.
|
|
|
|
- With Nothing, expires *all* unused files. -}
|
|
|
|
expireUnused :: Maybe Duration -> Assistant ()
|
|
|
|
expireUnused duration = do
|
|
|
|
m <- liftAnnex $ readUnusedLog ""
|
|
|
|
now <- liftIO getPOSIXTime
|
|
|
|
let oldkeys = M.keys $ M.filter (tooold now) m
|
|
|
|
forM_ oldkeys $ \k -> do
|
2019-01-14 17:03:35 +00:00
|
|
|
debug ["removing old unused key", serializeKey k]
|
2018-11-15 19:38:55 +00:00
|
|
|
liftAnnex $ tryNonAsync $ do
|
2020-07-25 15:54:34 +00:00
|
|
|
lockContentForRemoval k noop removeAnnex
|
2024-08-23 20:35:12 +00:00
|
|
|
logStatus NoLiveUpdate k InfoMissing
|
2014-01-23 19:09:43 +00:00
|
|
|
where
|
2023-03-14 02:39:16 +00:00
|
|
|
boundary = durationToPOSIXTime <$> duration
|
|
|
|
tooold now (_, mt) = case boundary of
|
2014-01-23 19:09:43 +00:00
|
|
|
Nothing -> True
|
|
|
|
Just b -> maybe False (\t -> now - t >= b) mt
|