Separate FUSE and Hg counter structs

Summary:
Some threads update FUSE counters, some threads update HgBackingStore counters, and some threads update HgImporter counters. No thread updates all of FUSE counters, HgBackingStore counters, and HgImporter counters. FUSE threads and HgImporter threads allocate the full set of counters (EdenThreadStats), even though many of the allocated counters can never be used during the thread's lifetime.

Reduce redundant allocation (and overhead during counter aggregation): split EdenThreadStats into three classes (FuseThreadStats, HgBackingStoreThreadStats, and HgImporterThreadStats) so different threads can allocate different sets of counters.

This diff should not change observable behavior.

Reviewed By: simpkins

Differential Revision: D14822273

fbshipit-source-id: cfd238187d20a0b8d3959673401ecad894e2095b
This commit is contained in:
Matt Glazar 2019-05-29 18:08:03 -07:00 committed by Facebook Github Bot
parent 5436028259
commit 761d5d2c8e
11 changed files with 154 additions and 101 deletions

View File

@ -175,45 +175,45 @@ void installSignalHandler() {
struct FuseChannel::HandlerEntry {
Handler handler;
EdenThreadStats::HistogramPtr histogram;
FuseThreadStats::HistogramPtr histogram;
};
const FuseChannel::HandlerMap FuseChannel::handlerMap_ = {
{FUSE_READ, {&FuseChannel::fuseRead, &EdenThreadStats::read}},
{FUSE_WRITE, {&FuseChannel::fuseWrite, &EdenThreadStats::write}},
{FUSE_LOOKUP, {&FuseChannel::fuseLookup, &EdenThreadStats::lookup}},
{FUSE_FORGET, {&FuseChannel::fuseForget, &EdenThreadStats::forget}},
{FUSE_GETATTR, {&FuseChannel::fuseGetAttr, &EdenThreadStats::getattr}},
{FUSE_SETATTR, {&FuseChannel::fuseSetAttr, &EdenThreadStats::setattr}},
{FUSE_READLINK, {&FuseChannel::fuseReadLink, &EdenThreadStats::readlink}},
{FUSE_SYMLINK, {&FuseChannel::fuseSymlink, &EdenThreadStats::symlink}},
{FUSE_MKNOD, {&FuseChannel::fuseMknod, &EdenThreadStats::mknod}},
{FUSE_MKDIR, {&FuseChannel::fuseMkdir, &EdenThreadStats::mkdir}},
{FUSE_UNLINK, {&FuseChannel::fuseUnlink, &EdenThreadStats::unlink}},
{FUSE_RMDIR, {&FuseChannel::fuseRmdir, &EdenThreadStats::rmdir}},
{FUSE_RENAME, {&FuseChannel::fuseRename, &EdenThreadStats::rename}},
{FUSE_LINK, {&FuseChannel::fuseLink, &EdenThreadStats::link}},
{FUSE_OPEN, {&FuseChannel::fuseOpen, &EdenThreadStats::open}},
{FUSE_STATFS, {&FuseChannel::fuseStatFs, &EdenThreadStats::statfs}},
{FUSE_RELEASE, {&FuseChannel::fuseRelease, &EdenThreadStats::release}},
{FUSE_FSYNC, {&FuseChannel::fuseFsync, &EdenThreadStats::fsync}},
{FUSE_SETXATTR, {&FuseChannel::fuseSetXAttr, &EdenThreadStats::setxattr}},
{FUSE_GETXATTR, {&FuseChannel::fuseGetXAttr, &EdenThreadStats::getxattr}},
{FUSE_READ, {&FuseChannel::fuseRead, &FuseThreadStats::read}},
{FUSE_WRITE, {&FuseChannel::fuseWrite, &FuseThreadStats::write}},
{FUSE_LOOKUP, {&FuseChannel::fuseLookup, &FuseThreadStats::lookup}},
{FUSE_FORGET, {&FuseChannel::fuseForget, &FuseThreadStats::forget}},
{FUSE_GETATTR, {&FuseChannel::fuseGetAttr, &FuseThreadStats::getattr}},
{FUSE_SETATTR, {&FuseChannel::fuseSetAttr, &FuseThreadStats::setattr}},
{FUSE_READLINK, {&FuseChannel::fuseReadLink, &FuseThreadStats::readlink}},
{FUSE_SYMLINK, {&FuseChannel::fuseSymlink, &FuseThreadStats::symlink}},
{FUSE_MKNOD, {&FuseChannel::fuseMknod, &FuseThreadStats::mknod}},
{FUSE_MKDIR, {&FuseChannel::fuseMkdir, &FuseThreadStats::mkdir}},
{FUSE_UNLINK, {&FuseChannel::fuseUnlink, &FuseThreadStats::unlink}},
{FUSE_RMDIR, {&FuseChannel::fuseRmdir, &FuseThreadStats::rmdir}},
{FUSE_RENAME, {&FuseChannel::fuseRename, &FuseThreadStats::rename}},
{FUSE_LINK, {&FuseChannel::fuseLink, &FuseThreadStats::link}},
{FUSE_OPEN, {&FuseChannel::fuseOpen, &FuseThreadStats::open}},
{FUSE_STATFS, {&FuseChannel::fuseStatFs, &FuseThreadStats::statfs}},
{FUSE_RELEASE, {&FuseChannel::fuseRelease, &FuseThreadStats::release}},
{FUSE_FSYNC, {&FuseChannel::fuseFsync, &FuseThreadStats::fsync}},
{FUSE_SETXATTR, {&FuseChannel::fuseSetXAttr, &FuseThreadStats::setxattr}},
{FUSE_GETXATTR, {&FuseChannel::fuseGetXAttr, &FuseThreadStats::getxattr}},
{FUSE_LISTXATTR,
{&FuseChannel::fuseListXAttr, &EdenThreadStats::listxattr}},
{&FuseChannel::fuseListXAttr, &FuseThreadStats::listxattr}},
{FUSE_REMOVEXATTR,
{&FuseChannel::fuseRemoveXAttr, &EdenThreadStats::removexattr}},
{FUSE_FLUSH, {&FuseChannel::fuseFlush, &EdenThreadStats::flush}},
{FUSE_OPENDIR, {&FuseChannel::fuseOpenDir, &EdenThreadStats::opendir}},
{FUSE_READDIR, {&FuseChannel::fuseReadDir, &EdenThreadStats::readdir}},
{&FuseChannel::fuseRemoveXAttr, &FuseThreadStats::removexattr}},
{FUSE_FLUSH, {&FuseChannel::fuseFlush, &FuseThreadStats::flush}},
{FUSE_OPENDIR, {&FuseChannel::fuseOpenDir, &FuseThreadStats::opendir}},
{FUSE_READDIR, {&FuseChannel::fuseReadDir, &FuseThreadStats::readdir}},
{FUSE_RELEASEDIR,
{&FuseChannel::fuseReleaseDir, &EdenThreadStats::releasedir}},
{FUSE_FSYNCDIR, {&FuseChannel::fuseFsyncDir, &EdenThreadStats::fsyncdir}},
{FUSE_ACCESS, {&FuseChannel::fuseAccess, &EdenThreadStats::access}},
{FUSE_CREATE, {&FuseChannel::fuseCreate, &EdenThreadStats::create}},
{FUSE_BMAP, {&FuseChannel::fuseBmap, &EdenThreadStats::bmap}},
{&FuseChannel::fuseReleaseDir, &FuseThreadStats::releasedir}},
{FUSE_FSYNCDIR, {&FuseChannel::fuseFsyncDir, &FuseThreadStats::fsyncdir}},
{FUSE_ACCESS, {&FuseChannel::fuseAccess, &FuseThreadStats::access}},
{FUSE_CREATE, {&FuseChannel::fuseCreate, &FuseThreadStats::create}},
{FUSE_BMAP, {&FuseChannel::fuseBmap, &FuseThreadStats::bmap}},
{FUSE_BATCH_FORGET,
{&FuseChannel::fuseBatchForget, &EdenThreadStats::forgetmulti}},
{&FuseChannel::fuseBatchForget, &FuseThreadStats::forgetmulti}},
};
static iovec inline make_iovec(const void* addr, size_t len) {

View File

@ -53,7 +53,7 @@ RequestData& RequestData::create(
void RequestData::startRequest(
EdenStats* stats,
EdenThreadStats::HistogramPtr histogram) {
FuseThreadStats::HistogramPtr histogram) {
startTime_ = steady_clock::now();
DCHECK(latencyHistogram_ == nullptr);
latencyHistogram_ = histogram;
@ -64,7 +64,7 @@ void RequestData::finishRequest() {
const auto now = steady_clock::now();
const auto now_since_epoch = duration_cast<seconds>(now.time_since_epoch());
const auto diff = duration_cast<microseconds>(now - startTime_);
stats_->getStatsForCurrentThread().recordLatency(
stats_->getFuseStatsForCurrentThread().recordLatency(
latencyHistogram_, diff, now_since_epoch);
latencyHistogram_ = nullptr;
stats_ = nullptr;

View File

@ -26,7 +26,7 @@ class RequestData : public folly::RequestData {
fuse_in_header fuseHeader_;
// Needed to track stats
std::chrono::time_point<std::chrono::steady_clock> startTime_;
EdenThreadStats::HistogramPtr latencyHistogram_{nullptr};
FuseThreadStats::HistogramPtr latencyHistogram_{nullptr};
EdenStats* stats_{nullptr};
Dispatcher* dispatcher_{nullptr};
@ -56,7 +56,7 @@ class RequestData : public folly::RequestData {
// a FUSE request, false otherwise.
static bool isFuseRequest();
void startRequest(EdenStats* stats, EdenThreadStats::HistogramPtr histogram);
void startRequest(EdenStats* stats, FuseThreadStats::HistogramPtr histogram);
void finishRequest();
// Returns the associated dispatcher instance

View File

@ -116,7 +116,9 @@ class HgImporterThreadFactory : public folly::ThreadFactory {
std::thread newThread(folly::Func&& func) override {
return delegate_.newThread([this, func = std::move(func)]() mutable {
threadLocalImporter.reset(new HgImporterManager(
repository_, localStore_, getSharedStatsForCurrentThread(stats_)));
repository_,
localStore_,
getSharedHgImporterStatsForCurrentThread(stats_)));
func();
});
}
@ -252,7 +254,7 @@ HgBackingStore::HgBackingStore(
initializeDatapackImport(repository);
#endif
HgImporter importer(
repository, localStore, getSharedStatsForCurrentThread(stats));
repository, localStore, getSharedHgImporterStatsForCurrentThread(stats));
const auto& options = importer.getOptions();
initializeTreeManifestImport(options, repository);
repoName_ = options.repoName;
@ -473,8 +475,8 @@ Future<unique_ptr<Tree>> HgBackingStore::getTree(const Hash& id) {
batch = std::move(writeBatch),
watch = std::move(watch)](auto tree) {
batch->flush();
stats->getStatsForCurrentThread().hgBackingStoreGetTree.addValue(
watch.elapsed().count());
stats->getHgBackingStoreStatsForCurrentThread()
.hgBackingStoreGetTree.addValue(watch.elapsed().count());
return tree;
});
}
@ -541,7 +543,7 @@ Future<unique_ptr<Tree>> HgBackingStore::importTreeImpl(
writeBatch->put(
KeySpace::TreeFamily, edenTreeID, serialized.second.coalesce());
auto count = watch.elapsed().count();
stats->getStatsForCurrentThread()
stats->getHgBackingStoreStatsForCurrentThread()
.mononokeBackingStoreGetTree.addValue(count);
return makeFuture(std::move(tree));
})
@ -768,7 +770,7 @@ Future<unique_ptr<Blob>> HgBackingStore::getBlob(const Hash& id) {
return mononoke->getBlob(revHashCopy)
.ensure([stats = stats_, watch = std::move(watch)]() {
auto count = watch.elapsed().count();
stats->getStatsForCurrentThread()
stats->getHgBackingStoreStatsForCurrentThread()
.mononokeBackingStoreGetBlob.addValue(count);
})
.thenError([this,

View File

@ -250,7 +250,7 @@ class HgImporterEofError : public HgImporterError {
HgImporter::HgImporter(
AbsolutePathPiece repoPath,
LocalStore* store,
std::shared_ptr<EdenThreadStats> stats,
std::shared_ptr<HgImporterThreadStats> stats,
std::optional<AbsolutePath> importHelperScript)
: repoPath_{repoPath}, store_{store}, stats_{std::move(stats)} {
std::vector<string> cmd;
@ -706,7 +706,7 @@ HgImporter::ChunkHeader HgImporter::readChunkHeader(
HgImporter::TransactionID HgImporter::sendManifestRequest(
folly::StringPiece revName) {
#if defined(EDEN_HAVE_STATS)
stats_->hgImporterManifest.addValue(1);
stats_->manifest.addValue(1);
#endif
auto txnID = nextRequestID_++;
@ -729,7 +729,7 @@ HgImporter::TransactionID HgImporter::sendManifestRequest(
HgImporter::TransactionID HgImporter::sendManifestNodeRequest(
folly::StringPiece revName) {
#if defined(EDEN_HAVE_STATS)
stats_->hgImporterManifestNodeForCommit.addValue(1);
stats_->manifestNodeForCommit.addValue(1);
#endif
auto txnID = nextRequestID_++;
@ -753,7 +753,7 @@ HgImporter::TransactionID HgImporter::sendFileRequest(
RelativePathPiece path,
Hash revHash) {
#if defined(EDEN_HAVE_STATS)
stats_->hgImporterCatFile.addValue(1);
stats_->catFile.addValue(1);
#endif
auto txnID = nextRequestID_++;
@ -779,7 +779,7 @@ HgImporter::TransactionID HgImporter::sendFileRequest(
HgImporter::TransactionID HgImporter::sendPrefetchFilesRequest(
const std::vector<std::pair<RelativePath, Hash>>& files) {
#if defined(EDEN_HAVE_STATS)
stats_->hgImporterPrefetchFiles.addValue(1);
stats_->prefetchFiles.addValue(1);
#endif
auto txnID = nextRequestID_++;
@ -838,7 +838,7 @@ HgImporter::TransactionID HgImporter::sendFetchTreeRequest(
RelativePathPiece path,
Hash pathManifestNode) {
#if defined(EDEN_HAVE_STATS)
stats_->hgImporterFetchTree.addValue(1);
stats_->fetchTree.addValue(1);
#endif
auto txnID = nextRequestID_++;
@ -945,7 +945,7 @@ const ImporterOptions& HgImporter::getOptions() const {
HgImporterManager::HgImporterManager(
AbsolutePathPiece repoPath,
LocalStore* store,
std::shared_ptr<EdenThreadStats> stats,
std::shared_ptr<HgImporterThreadStats> stats,
std::optional<AbsolutePath> importHelperScript)
: repoPath_{repoPath},
store_{store},

View File

@ -124,7 +124,8 @@ class Importer {
* the following reasons:
*
* * HgImporter does not synchronize its own members.
* * HgImporter accesses EdenThreadStats, and EdenThreadStats is thread-bound.
* * HgImporter accesses HgImporterThreadStats, and HgImporterThreadStats is
* thread-bound.
*/
class HgImporter : public Importer {
public:
@ -138,7 +139,7 @@ class HgImporter : public Importer {
HgImporter(
AbsolutePathPiece repoPath,
LocalStore* store,
std::shared_ptr<EdenThreadStats>,
std::shared_ptr<HgImporterThreadStats>,
std::optional<AbsolutePath> importHelperScript = std::nullopt);
virtual ~HgImporter();
@ -298,7 +299,7 @@ class HgImporter : public Importer {
#endif
const AbsolutePath repoPath_;
LocalStore* const store_{nullptr};
std::shared_ptr<EdenThreadStats> const stats_;
std::shared_ptr<HgImporterThreadStats> const stats_;
ImporterOptions options_;
uint32_t nextRequestID_{0};
/**
@ -339,7 +340,7 @@ class HgImporterManager : public Importer {
HgImporterManager(
AbsolutePathPiece repoPath,
LocalStore* store,
std::shared_ptr<EdenThreadStats>,
std::shared_ptr<HgImporterThreadStats>,
std::optional<AbsolutePath> importHelperScript = std::nullopt);
Hash importFlatManifest(folly::StringPiece revName) override;
@ -361,7 +362,7 @@ class HgImporterManager : public Importer {
const AbsolutePath repoPath_;
LocalStore* const store_{nullptr};
std::shared_ptr<EdenThreadStats> const stats_;
std::shared_ptr<HgImporterThreadStats> const stats_;
const std::optional<AbsolutePath> importHelperScript_;
};

View File

@ -50,7 +50,7 @@ struct HgBackingStoreTest : TestRepo, ::testing::Test {
std::shared_ptr<EdenStats> stats{std::make_shared<EdenStats>()};
HgImporter importer{repo.path(),
localStore.get(),
getSharedStatsForCurrentThread(stats)};
getSharedHgImporterStatsForCurrentThread(stats)};
std::shared_ptr<HgBackingStore> backingStore{
std::make_shared<HgBackingStore>(&importer, localStore.get(), stats)};
std::shared_ptr<ObjectStore> objectStore{

View File

@ -158,7 +158,7 @@ class HgImportErrorTest : public ::testing::Test {
importer_ = make_unique<ImporterType>(
testPath_,
localStore_.get(),
getSharedStatsForCurrentThread(stats_),
getSharedHgImporterStatsForCurrentThread(stats_),
fakeImportHelper);
backingStore_ =
make_shared<HgBackingStore>(importer_.get(), localStore_.get(), stats_);

View File

@ -47,7 +47,8 @@ class HgImportTest : public ::testing::Test {
AbsolutePath testPath_{testDir_.path().string()};
HgRepo repo_{testPath_ + "repo"_pc};
MemoryLocalStore localStore_;
std::shared_ptr<EdenThreadStats> stats_ = std::make_shared<EdenThreadStats>();
std::shared_ptr<HgImporterThreadStats> stats_ =
std::make_shared<HgImporterThreadStats>();
};
} // namespace

View File

@ -27,25 +27,39 @@ constexpr std::chrono::microseconds kBucketSize{1000};
namespace facebook {
namespace eden {
EdenThreadStats& EdenStats::getStatsForCurrentThread() {
return *threadLocalStats_.get();
FuseThreadStats& EdenStats::getFuseStatsForCurrentThread() {
return *threadLocalFuseStats_.get();
}
HgBackingStoreThreadStats& EdenStats::getHgBackingStoreStatsForCurrentThread() {
return *threadLocalHgBackingStoreStats_.get();
}
HgImporterThreadStats& EdenStats::getHgImporterStatsForCurrentThread() {
return *threadLocalHgImporterStats_.get();
}
void EdenStats::aggregate() {
for (auto& stats : threadLocalStats_.accessAllThreads()) {
for (auto& stats : threadLocalFuseStats_.accessAllThreads()) {
stats.aggregate();
}
for (auto& stats : threadLocalHgBackingStoreStats_.accessAllThreads()) {
stats.aggregate();
}
for (auto& stats : threadLocalHgImporterStats_.accessAllThreads()) {
stats.aggregate();
}
}
std::shared_ptr<EdenThreadStats> getSharedStatsForCurrentThread(
std::shared_ptr<HgImporterThreadStats> getSharedHgImporterStatsForCurrentThread(
std::shared_ptr<EdenStats> stats) {
return std::shared_ptr<EdenThreadStats>(
stats, &stats->getStatsForCurrentThread());
return std::shared_ptr<HgImporterThreadStats>(
stats, &stats->getHgImporterStatsForCurrentThread());
}
EdenThreadStats::EdenThreadStats() {}
EdenThreadStatsBase::EdenThreadStatsBase() {}
EdenThreadStats::Histogram EdenThreadStats::createHistogram(
EdenThreadStatsBase::Histogram EdenThreadStatsBase::createHistogram(
const std::string& name) {
return Histogram{this,
name,
@ -59,7 +73,7 @@ EdenThreadStats::Histogram EdenThreadStats::createHistogram(
}
#if defined(EDEN_HAVE_STATS)
EdenThreadStats::Timeseries EdenThreadStats::createTimeseries(
EdenThreadStatsBase::Timeseries EdenThreadStatsBase::createTimeseries(
const std::string& name) {
auto timeseries = Timeseries{this, name};
timeseries.exportStat(facebook::stats::COUNT);
@ -67,7 +81,7 @@ EdenThreadStats::Timeseries EdenThreadStats::createTimeseries(
}
#endif
void EdenThreadStats::recordLatency(
void FuseThreadStats::recordLatency(
HistogramPtr item,
std::chrono::microseconds elapsed,
std::chrono::seconds now) {

View File

@ -17,7 +17,9 @@
namespace facebook {
namespace eden {
class EdenThreadStats;
class FuseThreadStats;
class HgBackingStoreThreadStats;
class HgImporterThreadStats;
class EdenStats {
public:
@ -26,7 +28,21 @@ class EdenStats {
*
* The returned object can be used only on the current thread.
*/
EdenThreadStats& getStatsForCurrentThread();
FuseThreadStats& getFuseStatsForCurrentThread();
/**
* This function can be called on any thread.
*
* The returned object can be used only on the current thread.
*/
HgBackingStoreThreadStats& getHgBackingStoreStatsForCurrentThread();
/**
* This function can be called on any thread.
*
* The returned object can be used only on the current thread.
*/
HgImporterThreadStats& getHgImporterStatsForCurrentThread();
/**
* This function can be called on any thread.
@ -36,29 +52,44 @@ class EdenStats {
private:
class ThreadLocalTag {};
folly::ThreadLocal<EdenThreadStats, ThreadLocalTag, void> threadLocalStats_;
folly::ThreadLocal<FuseThreadStats, ThreadLocalTag, void>
threadLocalFuseStats_;
folly::ThreadLocal<HgBackingStoreThreadStats, ThreadLocalTag, void>
threadLocalHgBackingStoreStats_;
folly::ThreadLocal<HgImporterThreadStats, ThreadLocalTag, void>
threadLocalHgImporterStats_;
};
std::shared_ptr<EdenThreadStats> getSharedStatsForCurrentThread(
std::shared_ptr<HgImporterThreadStats> getSharedHgImporterStatsForCurrentThread(
std::shared_ptr<EdenStats>);
/**
* EdenThreadStats contains various thread-local stats structures.
* EdenThreadStatsBase is a base class for a group of thread-local stats
* structures.
*
* Each EdenThreadStats object should only be used from a single thread.
* The EdenStats object should be used to maintain one EdenThreadStats object
* Each EdenThreadStatsBase object should only be used from a single thread. The
* EdenStats object should be used to maintain one EdenThreadStatsBase object
* for each thread that needs to access/update the stats.
*/
class EdenThreadStats : public facebook::stats::ThreadLocalStatsT<
facebook::stats::TLStatsThreadSafe> {
class EdenThreadStatsBase : public facebook::stats::ThreadLocalStatsT<
facebook::stats::TLStatsThreadSafe> {
public:
using Histogram = TLHistogram;
#if defined(EDEN_HAVE_STATS)
using Timeseries = TLTimeseries;
#endif
explicit EdenThreadStats();
explicit EdenThreadStatsBase();
protected:
Histogram createHistogram(const std::string& name);
#if defined(EDEN_HAVE_STATS)
Timeseries createTimeseries(const std::string& name);
#endif
};
class FuseThreadStats : public EdenThreadStatsBase {
public:
// We track latency in units of microseconds, hence the _us suffix
// in the histogram names below.
@ -96,31 +127,11 @@ class EdenThreadStats : public facebook::stats::ThreadLocalStatsT<
Histogram poll{createHistogram("fuse.poll_us")};
Histogram forgetmulti{createHistogram("fuse.forgetmulti_us")};
#if defined(EDEN_HAVE_STATS)
/**
* @see HgImporter
*/
Timeseries hgImporterCatFile{createTimeseries("hg_importer.cat_file")};
Timeseries hgImporterFetchTree{createTimeseries("hg_importer.fetch_tree")};
Timeseries hgImporterManifest{createTimeseries("hg_importer.manifest")};
Timeseries hgImporterManifestNodeForCommit{
createTimeseries("hg_importer.manifest_node_for_commit")};
Timeseries hgImporterPrefetchFiles{
createTimeseries("hg_importer.prefetch_files")};
#endif
Histogram hgBackingStoreGetTree{createHistogram("store.hg.get_tree")};
Histogram hgBackingStoreGetBlob{createHistogram("store.hg.get_file")};
Histogram mononokeBackingStoreGetTree{
createHistogram("store.mononoke.get_tree")};
Histogram mononokeBackingStoreGetBlob{
createHistogram("store.mononoke.get_blob")};
// Since we can potentially finish a request in a different
// thread from the one used to initiate it, we use HistogramPtr
// as a helper for referencing the pointer-to-member that we
// want to update at the end of the request.
using HistogramPtr = Histogram EdenThreadStats::*;
using HistogramPtr = Histogram FuseThreadStats::*;
/** Record a the latency for an operation.
* item is the pointer-to-member for one of the histograms defined
@ -133,11 +144,35 @@ class EdenThreadStats : public facebook::stats::ThreadLocalStatsT<
HistogramPtr item,
std::chrono::microseconds elapsed,
std::chrono::seconds now);
};
/**
* @see HgBackingStore
*/
class HgBackingStoreThreadStats : public EdenThreadStatsBase {
public:
Histogram hgBackingStoreGetTree{createHistogram("store.hg.get_tree")};
Histogram mononokeBackingStoreGetTree{
createHistogram("store.mononoke.get_tree")};
Histogram mononokeBackingStoreGetBlob{
createHistogram("store.mononoke.get_blob")};
};
/**
* @see HgImporter
* @see HgBackingStore
*/
class HgImporterThreadStats : public EdenThreadStatsBase {
public:
Histogram hgBackingStoreGetBlob{createHistogram("store.hg.get_file")};
private:
Histogram createHistogram(const std::string& name);
#if defined(EDEN_HAVE_STATS)
Timeseries createTimeseries(const std::string& name);
Timeseries catFile{createTimeseries("hg_importer.cat_file")};
Timeseries fetchTree{createTimeseries("hg_importer.fetch_tree")};
Timeseries manifest{createTimeseries("hg_importer.manifest")};
Timeseries manifestNodeForCommit{
createTimeseries("hg_importer.manifest_node_for_commit")};
Timeseries prefetchFiles{createTimeseries("hg_importer.prefetch_files")};
#endif
};