aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2009-11-20 17:12:38 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2009-11-20 17:12:38 +0000
commit8824d60fe549e2fc9b5a852fc1b967eca241ea77 (patch)
treebf0f96064f5b77dd11bdcf0cf9bee58c03d3bda5 /src/libstore
parent997db91e07882f0555e224a2687189a362567577 (diff)
* Remove the --use-atime / --max-atime garbage collector flags. Many
(Linux) machines no longer maintain the atime because it's too expensive, and on the machines where --use-atime is useful (like the buildfarm), reading the atimes on the entire Nix store takes way too much time to make it practical.
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/gc.cc136
-rw-r--r--src/libstore/remote-store.cc5
-rw-r--r--src/libstore/store-api.cc2
-rw-r--r--src/libstore/store-api.hh16
4 files changed, 8 insertions, 151 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 3415c1cb4..1d4099620 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -439,30 +439,6 @@ Paths topoSortPaths(const PathSet & paths)
}
-static time_t lastFileAccessTime(const Path & path)
-{
- checkInterrupt();
-
- struct stat st;
- if (lstat(path.c_str(), &st) == -1)
- throw SysError(format("statting `%1%'") % path);
-
- if (S_ISDIR(st.st_mode)) {
- time_t last = 0;
- Strings names = readDirectory(path);
- foreach (Strings::iterator, i, names) {
- time_t t = lastFileAccessTime(path + "/" + *i);
- if (t > last) last = t;
- }
- return last;
- }
-
- else if (S_ISLNK(st.st_mode)) return 0;
-
- else return st.st_atime;
-}
-
-
struct GCLimitReached { };
@@ -522,35 +498,6 @@ void LocalStore::gcPathRecursive(const GCOptions & options,
}
-struct CachingAtimeComparator : public std::binary_function<Path, Path, bool>
-{
- std::map<Path, time_t> cache;
-
- time_t lookup(const Path & p)
- {
- std::map<Path, time_t>::iterator i = cache.find(p);
- if (i != cache.end()) return i->second;
- debug(format("computing atime of `%1%'") % p);
- cache[p] = lastFileAccessTime(p);
- assert(cache.find(p) != cache.end());
- return cache[p];
- }
-
- bool operator () (const Path & p1, const Path & p2)
- {
- return lookup(p2) < lookup(p1);
- }
-};
-
-
-static string showTime(const string & format, time_t t)
-{
- char s[128];
- strftime(s, sizeof s, format.c_str(), localtime(&t));
- return string(s);
-}
-
-
static bool isLive(const Path & path, const PathSet & livePaths,
const PathSet & tempRoots, const PathSet & tempRootsClosed)
{
@@ -699,87 +646,14 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
}
/* Delete all dead store paths (or until one of the stop
- conditions is reached). */
+ conditions is reached), respecting the partial ordering
+ determined by the references graph. */
PathSet done;
try {
-
- if (!options.useAtime) {
- /* Delete the paths, respecting the partial ordering
- determined by the references graph. */
- printMsg(lvlError, format("deleting garbage..."));
- foreach (PathSet::iterator, i, storePaths)
- gcPathRecursive(options, results, done, *i);
- }
-
- else {
-
- /* Delete in order of ascending last access time, still
- maintaining the partial ordering of the reference
- graph. Note that we can't use a topological sort for
- this because that takes time O(V+E), and in this case
- E=O(V^2) (i.e. the graph is dense because of the edges
- due to the atime ordering). So instead we put all
- deletable paths in a priority queue (ordered by atime),
- and after deleting a path, add additional paths that
- have become deletable to the priority queue. */
-
- CachingAtimeComparator atimeComp;
-
- /* Create a priority queue that orders paths by ascending
- atime. This is why C++ needs type inferencing... */
- std::priority_queue<Path, vector<Path>, binary_function_ref_adapter<CachingAtimeComparator> > prioQueue =
- std::priority_queue<Path, vector<Path>, binary_function_ref_adapter<CachingAtimeComparator> >(binary_function_ref_adapter<CachingAtimeComparator>(&atimeComp));
-
- /* Initially put the paths that are invalid or have no
- referrers into the priority queue. */
- printMsg(lvlError, format("finding deletable paths..."));
- foreach (PathSet::iterator, i, storePaths) {
- checkInterrupt();
- /* We can safely delete a path if it's invalid or
- it has no referrers. Note that all the invalid
- paths will be deleted in the first round. */
- if (isValidPath(*i)) {
- if (queryReferrersNoSelf(*i).empty()) prioQueue.push(*i);
- } else prioQueue.push(*i);
- }
-
- debug(format("%1% initially deletable paths") % prioQueue.size());
-
- /* Now delete everything in the order of the priority
- queue until nothing is left. */
- printMsg(lvlError, format("deleting garbage..."));
- while (!prioQueue.empty()) {
- checkInterrupt();
- Path path = prioQueue.top(); prioQueue.pop();
-
- 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;
- if (isValidPath(path)) references = queryReferencesNoSelf(path);
-
- gcPath(options, results, path);
-
- /* For each reference of the current path, see if the
- reference has now become deletable (i.e. is in the
- set of dead paths and has no referrers left). If
- so add it to the priority queue. */
- foreach (PathSet::iterator, i, references) {
- if (storePaths.find(*i) != storePaths.end() &&
- queryReferrersNoSelf(*i).empty())
- {
- debug(format("path `%1%' has become deletable") % *i);
- prioQueue.push(*i);
- }
- }
- }
-
- }
-
+ printMsg(lvlError, format("deleting garbage..."));
+ foreach (PathSet::iterator, i, storePaths)
+ gcPathRecursive(options, results, done, *i);
} catch (GCLimitReached & e) {
}
}
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index f54281e0d..5143143f5 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -426,8 +426,9 @@ void RemoteStore::collectGarbage(const GCOptions & options, GCResults & results)
writeLongLong(options.maxFreed, to);
writeInt(options.maxLinks, to);
if (GET_PROTOCOL_MINOR(daemonVersion) >= 5) {
- writeInt(options.useAtime, to);
- writeInt(options.maxAtime, to);
+ /* removed options */
+ writeInt(0, to);
+ writeInt(0, to);
}
processStderr();
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 08ee922ef..01dd51621 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -14,8 +14,6 @@ GCOptions::GCOptions()
ignoreLiveness = false;
maxFreed = 0;
maxLinks = 0;
- useAtime = false;
- maxAtime = (time_t) -1;
}
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index bac2f6b9a..d827dff84 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -64,22 +64,6 @@ struct GCOptions
has dropped below `maxLinks'. */
unsigned int maxLinks;
- /* Delete paths in order of ascending last access time. I.e.,
- prefer deleting unrecently used paths. Useful in conjunction
- with `maxFreed' and `maxLinks' (or manual interruption). The
- access time of a path is defined as the highest atime of any
- non-directory, non-symlink file under that path. Directories
- and symlinks are ignored because their atimes are frequently
- mass-updated, e.g. by `locate'. Note that optimiseStore()
- somewhat reduces the usefulness of this option: it hard-links
- regular files and symlink together, giving them a "shared"
- atime. */
- bool useAtime;
-
- /* Do not delete paths newer than `maxAtime'. -1 means no age
- limit. */
- time_t maxAtime;
-
GCOptions();
};