guix/nix/libstore/misc.cc
Congcong Kuo 85a72ed28e
daemon: Use starts_with() and ends_with() instead of string() or hasSuffix()
* nix/libstore/build.cc (DerivationGoal::tryBuildHook): Use starts_with instead
of string()
* nix/libstore/builtins.cc (lookupBuiltinBuilder): Same.
* nix/libstore/builtins.hh (isBuiltin): Same and fix indentation of the file.
* nix/libstore/derivations.cc (DerivationOutput::parseHashInfo, isDerivation):
Same and clean header files.
* nix/libstore/gc.cc (addPermRoot, LocalStore::isActiveTempFile): Same.
* nix/libstore/globals.cc: Same.
* nix/libstore/local-store.cc: Same.
* nix/libstore/misc.cc: Same.
* nix/libstore/store-api.cc (checkStoreName): Same.
* nix/libutil/affinity.cc: Same.
* nix/libutil/archive.cc: Same.
* nix/libutil/spawn.cc: Same.
* nix/libutil/util.{cc, hh} (hasSuffix): Removed.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-11-03 17:18:37 +01:00

119 lines
3.4 KiB
C++

#include "misc.hh"
#include <math.h>
#include "store-api.hh"
#include "local-store.hh"
#include <format>
namespace nix {
Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
{
assertStorePath(drvPath);
store.ensurePath(drvPath);
return readDerivation(drvPath);
}
void computeFSClosure(StoreAPI & store, const Path & path,
PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
{
if (paths.find(path) != paths.end()) return;
paths.insert(path);
PathSet edges;
if (flipDirection) {
store.queryReferrers(path, edges);
if (includeOutputs) {
PathSet derivers = store.queryValidDerivers(path);
for (auto& i : derivers)
edges.insert(i);
}
if (includeDerivers && isDerivation(path)) {
PathSet outputs = store.queryDerivationOutputs(path);
for (auto& i : outputs)
if (store.isValidPath(i) && store.queryDeriver(i) == path)
edges.insert(i);
}
} else {
store.queryReferences(path, edges);
if (includeOutputs && isDerivation(path)) {
PathSet outputs = store.queryDerivationOutputs(path);
for (auto& i : outputs)
if (store.isValidPath(i)) edges.insert(i);
}
if (includeDerivers) {
Path deriver = store.queryDeriver(path);
if (store.isValidPath(deriver)) edges.insert(deriver);
}
}
for (auto& i : edges)
computeFSClosure(store, i, paths, flipDirection, includeOutputs, includeDerivers);
}
static void dfsVisit(StoreAPI & store, const PathSet & paths,
const Path & path, PathSet & visited, Paths & sorted,
PathSet & parents)
{
if (parents.find(path) != parents.end())
throw BuildError(std::format("cycle detected in the references of `{}'", path));
if (visited.find(path) != visited.end()) return;
visited.insert(path);
parents.insert(path);
PathSet references;
if (store.isValidPath(path))
store.queryReferences(path, references);
for (auto& i : references)
/* Don't traverse into paths that don't exist. That can
happen due to substitutes for non-existent paths. */
if (i != path && paths.find(i) != paths.end())
dfsVisit(store, paths, i, visited, sorted, parents);
sorted.push_front(path);
parents.erase(path);
}
Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
{
Paths sorted;
PathSet visited, parents;
for (const auto& i : paths)
dfsVisit(store, paths, i, visited, sorted, parents);
return sorted;
}
/* Max of LLONG_MAX is 8 EiB */
string showBytes(long long bytes)
{
if (llabs(bytes > exp2l(60))) {
return std::format("{:7.2f} EiB", bytes / exp2l(60));
} else if (llabs(bytes > exp2l(50))) {
return std::format("{:7.2f} PiB", bytes / exp2l(50));
} else if (llabs(bytes > exp2l(40))) {
return std::format("{:7.2f} TiB", bytes / exp2l(40));
} else if (llabs(bytes > exp2l(30))) {
return std::format("{:7.2f} GiB", bytes / exp2l(30));
} else if (llabs(bytes > exp2l(20))) {
return std::format("{:7.2f} MiB", bytes / exp2l(20));
} else if (llabs(bytes > exp2l(10))) {
return std::format("{:7.2f} KiB", bytes / exp2l(10));
} else {
return std::format("{:4} bytes", bytes);
}
}
}