Skip to content

Commit

Permalink
Use fetchToStore() instead of computeStorePath()
Browse files Browse the repository at this point in the history
This enables caching of repeated hashing of the same path.
  • Loading branch information
edolstra committed May 14, 2024
1 parent e255be6 commit a33aad3
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 16 deletions.
20 changes: 10 additions & 10 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2431,16 +2431,7 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
*store,
path.resolveSymlinks(),
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
/* For backwards compatibility, if the path is the
root of a tree, we need to construct a
"double-copied" store path like
/nix/store/<hash1>-<hash2>-source. We don't need to
materialize /nix/store/<hash2>-source
though. Still, this requires reading/hashing the
path twice. */
path.path.isRoot()
? store->computeStorePath("source", path).first.to_string()
: path.baseName(),
computeBaseName(path),
FileIngestionMethod::Recursive,
nullptr,
repair);
Expand All @@ -2457,6 +2448,15 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
}


std::string EvalState::computeBaseName(const SourcePath & path)
{
return std::string(
path.path.isRoot()
? fetchToStore(*store, path, FetchMode::DryRun).to_string()
: path.baseName());
}


SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext & context, std::string_view errorCtx)
{
try {
Expand Down
12 changes: 12 additions & 0 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,18 @@ public:

StorePath copyPathToStore(NixStringContext & context, const SourcePath & path);

/**
* Compute the base name for a `SourcePath`. For non-root paths,
* this is just `SourcePath::baseName()`. But for root paths, for
* backwards compatibility, it needs to be `<hash>-source`,
* i.e. as if the path were copied to the Nix store. This results
* in a "double-copied" store path like
* `/nix/store/<hash1>-<hash2>-source`. We don't need to
* materialize /nix/store/<hash2>-source though. Still, this
* requires reading/hashing the path twice.
*/
std::string computeBaseName(const SourcePath & path);

/**
* Path coercion.
*
Expand Down
5 changes: 2 additions & 3 deletions src/libexpr/paths.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "eval.hh"
#include "util.hh"
#include "store-api.hh"
#include "fetch-to-store.hh"

namespace nix {

Expand Down Expand Up @@ -123,8 +123,7 @@ std::string EvalState::rewriteVirtualPaths(std::string_view s, std::string_view
std::string(warning), // FIXME: should accept a string_view
positions[pos], accessor->second->showPath(CanonPath::root));

// FIXME: cache this.
res.append(store->computeStorePath("source", {accessor->second}).first.hashPart());
res.append(fetchToStore(*store, {accessor->second}, FetchMode::DryRun).hashPart());
} catch (...) {
ignoreException();
res.append(s.substr(m, end - m));
Expand Down
4 changes: 1 addition & 3 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2395,9 +2395,7 @@ static void prim_filterSource(EvalState & state, const PosIdx pos, Value * * arg
addPath(
state,
pos,
path.path.isRoot()
? state.store->computeStorePath("source", path).first.to_string()
: path.baseName(),
state.computeBaseName(path),
path,
args[0],
FileIngestionMethod::Recursive,
Expand Down

0 comments on commit a33aad3

Please sign in to comment.