Skip to content

Commit 11d2199

Browse files
committed
Refactor GCOptions and GCAction, add recursive flag
1 parent 68b94d2 commit 11d2199

File tree

8 files changed

+216
-167
lines changed

8 files changed

+216
-167
lines changed

src/libstore/daemon.cc

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -708,18 +708,36 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
708708

709709
case wopCollectGarbage: {
710710
GCOptions options;
711-
options.action = (GCOptions::GCAction) readInt(from);
712-
options.pathsToDelete = WorkerProto<StorePathSet>::read(*store, from);
713-
from >> options.ignoreLiveness >> options.maxFreed;
711+
int action;
712+
bool ignoreLiveness;
713+
StorePathSet pathsToDelete;
714+
bool recursive {false};
715+
action = readInt(from);
716+
pathsToDelete = WorkerProto<StorePathSet>::read(*store, from);
717+
from >> ignoreLiveness >> options.maxFreed;
714718
// obsolete fields
715719
readInt(from);
716720
readInt(from);
717721
readInt(from);
722+
if (GET_PROTOCOL_MINOR(clientVersion) >= 31) {
723+
from >> recursive;
724+
};
725+
726+
switch (action) {
727+
case 0:
728+
options.action = GCReturn::Live; break;
729+
case 1:
730+
options.action = GCReturn::Dead; break;
731+
case 2:
732+
options.action = GCDelete { .ignoreLiveness = ignoreLiveness }; break;
733+
case 3:
734+
options.action = GCDelete { .pathsToDelete = GCPathsToDelete { .paths = pathsToDelete, .recursive = recursive }, .ignoreLiveness = ignoreLiveness, }; break;
735+
};
718736

719737
GCResults results;
720738

721739
logger->startWork();
722-
if (options.ignoreLiveness)
740+
if (ignoreLiveness)
723741
throw Error("you are not allowed to ignore liveness");
724742
auto & gcStore = require<GcStore>(*store);
725743
gcStore.collectGarbage(options, results);

src/libstore/gc-store.hh

Lines changed: 24 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,52 +9,35 @@ namespace nix {
99

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

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

13-
struct GCOptions
14-
{
15-
/**
16-
* Garbage collector operation:
17-
*
18-
* - `gcReturnLive`: return the set of paths reachable from
19-
* (i.e. in the closure of) the roots.
20-
*
21-
* - `gcReturnDead`: return the set of paths not reachable from
22-
* the roots.
23-
*
24-
* - `gcDeleteDead`: actually delete the latter set.
25-
*
26-
* - `gcDeleteSpecific`: delete the paths listed in
27-
* `pathsToDelete`, insofar as they are not reachable.
28-
*/
29-
typedef enum {
30-
gcReturnLive,
31-
gcReturnDead,
32-
gcDeleteDead,
33-
gcDeleteSpecific,
34-
} GCAction;
15+
/* Set of paths to delete, and whether their transitive closures should be deleted as well */
16+
struct GCPathsToDelete {
17+
StorePathSet paths;
18+
bool recursive;
19+
};
3520

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

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

46-
/**
47-
* For `gcDeleteSpecific`, the paths to delete.
48-
*/
49-
StorePathSet pathsToDelete;
50-
51-
/**
52-
* Stop after at least `maxFreed` bytes have been freed.
53-
*/
54-
uint64_t maxFreed{std::numeric_limits<uint64_t>::max()};
35+
struct GCOptions {
36+
GCAction action;
37+
/* Stop after at least `maxFreed' bytes have been freed. */
38+
uint64_t maxFreed{std::numeric_limits<uint64_t>::max()};
5539
};
5640

57-
5841
struct GCResults
5942
{
6043
/**
@@ -63,10 +46,7 @@ struct GCResults
6346
*/
6447
PathSet paths;
6548

66-
/**
67-
* For `gcReturnDead`, `gcDeleteDead` and `gcDeleteSpecific`, the
68-
* number of bytes that would be or was freed.
69-
*/
49+
/* For `GCDelete', the number of bytes that would be or was freed. */
7050
uint64_t bytesFreed = 0;
7151
};
7252

0 commit comments

Comments
 (0)