Skip to content

Commit

Permalink
Refactor GCOptions and GCAction, add recursive flag
Browse files Browse the repository at this point in the history
  • Loading branch information
balsoft committed May 30, 2023
1 parent 68b94d2 commit fd071dc
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 167 deletions.
26 changes: 22 additions & 4 deletions src/libstore/daemon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -708,18 +708,36 @@ static void performOp(TunnelLogger * logger, ref<Store> store,

case wopCollectGarbage: {
GCOptions options;
options.action = (GCOptions::GCAction) readInt(from);
options.pathsToDelete = WorkerProto<StorePathSet>::read(*store, from);
from >> options.ignoreLiveness >> options.maxFreed;
int action;
bool ignoreLiveness;
StorePathSet pathsToDelete;
bool recursive {false};
action = readInt(from);
pathsToDelete = WorkerProto<StorePathSet>::read(*store, from);
from >> ignoreLiveness >> options.maxFreed;
// obsolete fields
readInt(from);
readInt(from);
readInt(from);
if (GET_PROTOCOL_MINOR(clientVersion) >= 31) {
from >> recursive;
};

switch (action) {
case 0:
options.action = GCReturn::Live; break;
case 1:
options.action = GCReturn::Dead; break;
case 2:
options.action = GCDelete { .ignoreLiveness = ignoreLiveness }; break;
case 3:
options.action = GCDelete { .pathsToDelete = GCPathsToDelete { .paths = pathsToDelete, .recursive = recursive }, .ignoreLiveness = ignoreLiveness, }; break;
};

GCResults results;

logger->startWork();
if (options.ignoreLiveness)
if (ignoreLiveness)
throw Error("you are not allowed to ignore liveness");
auto & gcStore = require<GcStore>(*store);
gcStore.collectGarbage(options, results);
Expand Down
68 changes: 24 additions & 44 deletions src/libstore/gc-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,35 @@ namespace nix {

typedef std::unordered_map<StorePath, std::unordered_set<std::string>> Roots;

/* Return either live (reachable) or dead (unreachable) paths */
enum class GCReturn { Live, Dead };

struct GCOptions
{
/**
* Garbage collector operation:
*
* - `gcReturnLive`: return the set of paths reachable from
* (i.e. in the closure of) the roots.
*
* - `gcReturnDead`: return the set of paths not reachable from
* the roots.
*
* - `gcDeleteDead`: actually delete the latter set.
*
* - `gcDeleteSpecific`: delete the paths listed in
* `pathsToDelete`, insofar as they are not reachable.
*/
typedef enum {
gcReturnLive,
gcReturnDead,
gcDeleteDead,
gcDeleteSpecific,
} GCAction;
/* Set of paths to delete, and whether their transitive closures should be deleted as well */
struct GCPathsToDelete {
StorePathSet paths;
bool recursive;
};

GCAction action{gcDeleteDead};
/* Delete either a given set of paths, or all dead paths */
struct GCDelete {
/* Delete this set, or all dead paths if it is std::nullopt */
std::optional<GCPathsToDelete> pathsToDelete;
/* If `ignoreLiveness' is set, then reachability from the roots is
ignored (dangerous!). However, the paths must still be
unreferenced *within* the store (i.e., there can be no other
store paths that depend on them). */
bool ignoreLiveness{false};
};

/**
* If `ignoreLiveness` is set, then reachability from the roots is
* ignored (dangerous!). However, the paths must still be
* unreferenced *within* the store (i.e., there can be no other
* store paths that depend on them).
*/
bool ignoreLiveness{false};
/* Garbage collection action: either return paths, or delete them */
using GCAction = std::variant<GCReturn, GCDelete>;

/**
* For `gcDeleteSpecific`, the paths to delete.
*/
StorePathSet pathsToDelete;

/**
* Stop after at least `maxFreed` bytes have been freed.
*/
uint64_t maxFreed{std::numeric_limits<uint64_t>::max()};
struct GCOptions {
GCAction action;
/* Stop after at least `maxFreed' bytes have been freed. */
uint64_t maxFreed{std::numeric_limits<uint64_t>::max()};
};


struct GCResults
{
/**
Expand All @@ -63,10 +46,7 @@ struct GCResults
*/
PathSet paths;

/**
* For `gcReturnDead`, `gcDeleteDead` and `gcDeleteSpecific`, the
* number of bytes that would be or was freed.
*/
/* For `GCDelete', the number of bytes that would be or was freed. */
uint64_t bytesFreed = 0;
};

Expand Down
Loading

0 comments on commit fd071dc

Please sign in to comment.