* GC option `--max-atime' that specifies an upper limit to the last

accessed time of paths that may be deleted.  Anything more recently
  used won't be deleted.  The time is specified in time_t,
  e.g. seconds since 1970-01-01 00:00:00 UTC; use `date +%s' to
  convert to time_t from the command line. 

  Example: to delete everything that hasn't been used in the last two
  months:

  $ nix-store --gc -v --max-atime $(date +%s -d "2 months ago")
This commit is contained in:
Eelco Dolstra 2008-09-17 14:52:35 +00:00
parent 4af2fdba6d
commit f32fef1b07
4 changed files with 24 additions and 7 deletions

View file

@ -531,10 +531,11 @@ void LocalStore::gcPathRecursive(const GCOptions & options,
startNest(nest, lvlDebug, format("looking at `%1%'") % path); startNest(nest, lvlDebug, format("looking at `%1%'") % path);
/* Delete all the referrers first. They must be garbage too, /* Delete all the referrers first. They must be garbage too,
since if they were in the closure of some live path, then this since if they were live, then the current path would also be
path would also be in the closure. Note that live. Note that deleteFromStore() below still makes sure that
deleteFromStore() below still makes sure that the referrer set the referrer set has become empty, just in case. (However that
has become empty, just in case. */ doesn't guard against deleting top-level paths that are only
reachable from GC roots.) */
PathSet referrers; PathSet referrers;
if (isValidPath(path)) if (isValidPath(path))
queryReferrers(path, referrers); queryReferrers(path, referrers);
@ -571,7 +572,7 @@ struct CachingAtimeComparator : public std::binary_function<Path, Path, bool>
string showTime(const string & format, time_t t) string showTime(const string & format, time_t t)
{ {
char s[128]; char s[128];
strftime(s, sizeof s, format.c_str(), gmtime(&t)); strftime(s, sizeof s, format.c_str(), localtime(&t));
return string(s); return string(s);
} }
@ -766,7 +767,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
while (!prioQueue.empty()) { while (!prioQueue.empty()) {
checkInterrupt(); checkInterrupt();
Path path = prioQueue.top(); prioQueue.pop(); Path path = prioQueue.top(); prioQueue.pop();
printMsg(lvlInfo, format("deleting `%1%' (last accessed %2%)") % path % showTime("%F %H:%M:%S", atimeComp.cache[path]));
if (options.maxAtime != (time_t) -1 &&
atimeComp.lookup(path) > options.maxAtime)
continue;
printMsg(lvlInfo, format("deleting `%1%' (last accessed %2%)") % path % showTime("%F %H:%M:%S", atimeComp.lookup(path)));
PathSet references; PathSet references;
if (isValidPath(path)) references = queryReferencesNoSelf(path); if (isValidPath(path)) references = queryReferencesNoSelf(path);

View file

@ -15,6 +15,7 @@ GCOptions::GCOptions()
maxFreed = ULLONG_MAX; maxFreed = ULLONG_MAX;
maxLinks = 0; maxLinks = 0;
useAtime = false; useAtime = false;
maxAtime = (time_t) -1;
} }

View file

@ -75,6 +75,10 @@ struct GCOptions
atime. */ atime. */
bool useAtime; bool useAtime;
/* Do not delete paths newer than `maxAtime'. -1 means no age
limit. */
time_t maxAtime;
GCOptions(); GCOptions();
}; };

View file

@ -531,8 +531,14 @@ static void opGC(Strings opFlags, Strings opArgs)
else if (*i == "--max-freed") options.maxFreed = getIntArg(*i, i, opFlags.end()); else if (*i == "--max-freed") options.maxFreed = getIntArg(*i, i, opFlags.end());
else if (*i == "--max-links") options.maxLinks = getIntArg(*i, i, opFlags.end()); else if (*i == "--max-links") options.maxLinks = getIntArg(*i, i, opFlags.end());
else if (*i == "--use-atime") options.useAtime = true; else if (*i == "--use-atime") options.useAtime = true;
else if (*i == "--max-atime") {
options.useAtime = true;
options.maxAtime = getIntArg(*i, i, opFlags.end());
}
else throw UsageError(format("bad sub-operation `%1%' in GC") % *i); else throw UsageError(format("bad sub-operation `%1%' in GC") % *i);
if (!opArgs.empty()) throw UsageError("no arguments expected");
PrintFreed freed(options.action == GCOptions::gcDeleteDead, results); PrintFreed freed(options.action == GCOptions::gcDeleteDead, results);
store->collectGarbage(options, results); store->collectGarbage(options, results);
@ -745,7 +751,7 @@ void run(Strings args)
indirectRoot = true; indirectRoot = true;
else if (arg[0] == '-') { else if (arg[0] == '-') {
opFlags.push_back(arg); opFlags.push_back(arg);
if (arg == "--max-freed" || arg == "--max-links") { /* !!! hack */ if (arg == "--max-freed" || arg == "--max-links" || arg == "--max-atime") { /* !!! hack */
if (i != args.end()) opFlags.push_back(*i++); if (i != args.end()) opFlags.push_back(*i++);
} }
} }