mirror of
https://github.com/NixOS/nix
synced 2025-06-25 14:51:16 +02:00
Cache calls to GitRepo::getWorkdirInfo()
A command like `nix flake metadata` was causing about 4 calls to getWorkdirInfo(), which is slow for large repos (even when they're not dirty).
This commit is contained in:
parent
f469bc2ae4
commit
7ba933e989
3 changed files with 17 additions and 1 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include "signals.hh"
|
#include "signals.hh"
|
||||||
#include "users.hh"
|
#include "users.hh"
|
||||||
#include "fs-sink.hh"
|
#include "fs-sink.hh"
|
||||||
|
#include "sync.hh"
|
||||||
|
|
||||||
#include <git2/attr.h>
|
#include <git2/attr.h>
|
||||||
#include <git2/blob.h>
|
#include <git2/blob.h>
|
||||||
|
@ -1276,4 +1277,17 @@ ref<GitRepo> getTarballCache()
|
||||||
return GitRepo::openRepo(repoDir, true, true);
|
return GitRepo::openRepo(repoDir, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path & path)
|
||||||
|
{
|
||||||
|
static Sync<std::unordered_map<std::filesystem::path, WorkdirInfo>> _cache;
|
||||||
|
{
|
||||||
|
auto cache(_cache.lock());
|
||||||
|
auto i = cache->find(path);
|
||||||
|
if (i != cache->end()) return i->second;
|
||||||
|
}
|
||||||
|
auto workdirInfo = GitRepo::openRepo(path)->getWorkdirInfo();
|
||||||
|
_cache.lock()->emplace(path, workdirInfo);
|
||||||
|
return workdirInfo;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,8 @@ struct GitRepo
|
||||||
|
|
||||||
virtual WorkdirInfo getWorkdirInfo() = 0;
|
virtual WorkdirInfo getWorkdirInfo() = 0;
|
||||||
|
|
||||||
|
static WorkdirInfo getCachedWorkdirInfo(const std::filesystem::path & path);
|
||||||
|
|
||||||
/* Get the ref that HEAD points to. */
|
/* Get the ref that HEAD points to. */
|
||||||
virtual std::optional<std::string> getWorkdirRef() = 0;
|
virtual std::optional<std::string> getWorkdirRef() = 0;
|
||||||
|
|
||||||
|
|
|
@ -431,7 +431,7 @@ struct GitInputScheme : InputScheme
|
||||||
// If this is a local directory and no ref or revision is
|
// If this is a local directory and no ref or revision is
|
||||||
// given, then allow the use of an unclean working tree.
|
// given, then allow the use of an unclean working tree.
|
||||||
if (!input.getRef() && !input.getRev() && repoInfo.isLocal)
|
if (!input.getRef() && !input.getRev() && repoInfo.isLocal)
|
||||||
repoInfo.workdirInfo = GitRepo::openRepo(repoInfo.url)->getWorkdirInfo();
|
repoInfo.workdirInfo = GitRepo::getCachedWorkdirInfo(repoInfo.url);
|
||||||
|
|
||||||
return repoInfo;
|
return repoInfo;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue