count fetch statistics during diff and checkout

Summary:
During checkout and stats, count every object fetch and which level of
cache it was served from.

Reviewed By: simpkins

Differential Revision: D19186333

fbshipit-source-id: fc0a74db297b9c723682e245996a7befd762f933
This commit is contained in:
Chad Austin 2020-02-05 16:01:36 -08:00 committed by Facebook Github Bot
parent 34732ab62c
commit 58f352b807
6 changed files with 103 additions and 14 deletions

View File

@ -13,7 +13,7 @@
#include "eden/fs/inodes/EdenMount.h"
#include "eden/fs/inodes/InodePtrFwd.h"
#include "eden/fs/service/gen-cpp2/eden_types.h"
#include "eden/fs/store/IObjectStore.h"
#include "eden/fs/store/StatsFetchContext.h"
#include "eden/fs/utils/PathFuncs.h"
namespace folly {
@ -102,7 +102,7 @@ class CheckoutContext {
/**
* Return the fetch context associated with this checkout context.
*/
ObjectFetchContext& getFetchContext() {
StatsFetchContext& getFetchContext() {
return fetchContext_;
}
@ -111,7 +111,7 @@ class CheckoutContext {
EdenMount* const mount_;
folly::Synchronized<EdenMount::ParentInfo>::LockedPtr parentsLock_;
RenameLock renameLock_;
ObjectFetchContext fetchContext_;
StatsFetchContext fetchContext_;
// The checkout processing may occur across many threads,
// if some data load operations complete asynchronously on other threads.

View File

@ -113,7 +113,7 @@ class EdenMount::JournalDiffCallback : public DiffCallback {
<< folly::exceptionStr(ew);
}
FOLLY_NODISCARD Future<folly::Unit> performDiff(
FOLLY_NODISCARD Future<StatsFetchContext> performDiff(
EdenMount* mount,
TreeInodePtr rootInode,
std::shared_ptr<const Tree> rootTree) {
@ -127,7 +127,8 @@ class EdenMount::JournalDiffCallback : public DiffCallback {
std::move(rootTree),
rawContext->getToplevelIgnore(),
false)
.ensure([diffContext = std::move(diffContext), rootInode]() {});
.thenValue([diffContext = std::move(diffContext), rootInode](
folly::Unit) { return diffContext->getFetchContext(); });
}
/** moves the Unclean Path information out of this diff callback instance,
@ -798,10 +799,9 @@ folly::Future<CheckoutResult> EdenMount::checkout(
auto& fromTree = std::get<0>(treeResults);
return journalDiffCallback->performDiff(this, getRootInode(), fromTree)
.thenValue([ctx, journalDiffCallback, treeResults](Unit) {
// TODO: Merge results from JournalDiffCallback into ctx
(void)ctx;
(void)journalDiffCallback;
.thenValue([ctx, journalDiffCallback, treeResults](
const StatsFetchContext& diffFetchContext) {
ctx->getFetchContext().merge(diffFetchContext);
return treeResults;
});
})

View File

@ -10,7 +10,7 @@
#include <folly/Range.h>
#include <folly/futures/Future.h>
#include "eden/fs/store/IObjectStore.h"
#include "eden/fs/store/StatsFetchContext.h"
#include "eden/fs/utils/PathFuncs.h"
namespace folly {
@ -77,7 +77,7 @@ class DiffContext {
const GitIgnoreStack* getToplevelIgnore() const;
bool isCancelled() const;
LoadFileFunction getLoadFileContentsFromPath() const;
ObjectFetchContext& getFetchContext() {
StatsFetchContext& getFetchContext() {
return fetchContext_;
}
@ -85,7 +85,7 @@ class DiffContext {
std::unique_ptr<TopLevelIgnores> topLevelIgnores_;
const LoadFileFunction loadFileContentsFromPath_;
apache::thrift::ResponseChannelRequest* const FOLLY_NULLABLE request_;
ObjectFetchContext fetchContext_;
StatsFetchContext fetchContext_;
};
} // namespace eden
} // namespace facebook

View File

@ -35,7 +35,7 @@ class ObjectFetchContext {
*
* Suitable for use as an index into an array of size kObjectTypeEnumMax
*/
enum ObjectType {
enum ObjectType : unsigned {
Blob,
BlobMetadata,
Tree,
@ -47,7 +47,7 @@ class ObjectFetchContext {
*
* Suitable for use as an index into an array of size kOriginEnumMax.
*/
enum Origin {
enum Origin : unsigned {
FromMemoryCache,
FromDiskCache,
FromBackingStore,

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "eden/fs/store/StatsFetchContext.h"
#include <folly/logging/xlog.h>
namespace facebook {
namespace eden {
StatsFetchContext::StatsFetchContext(const StatsFetchContext& other) {
for (size_t y = 0; y < ObjectFetchContext::kObjectTypeEnumMax; ++y) {
for (size_t x = 0; x < ObjectFetchContext::kOriginEnumMax; ++x) {
// This could almost certainly use a more relaxed memory ordering.
counts_[y][x] = other.counts_[y][x].load();
}
}
}
void StatsFetchContext::didFetch(ObjectType type, const Hash&, Origin origin) {
XCHECK(type < ObjectFetchContext::kObjectTypeEnumMax)
<< "type is out of range: " << type;
XCHECK(origin < ObjectFetchContext::kOriginEnumMax)
<< "origin is out of range: " << type;
counts_[type][origin].fetch_add(1, std::memory_order_acq_rel);
}
uint64_t StatsFetchContext::countFetchesOfType(ObjectType type) const {
XCHECK(type < ObjectFetchContext::kObjectTypeEnumMax)
<< "type is out of range: " << type;
uint64_t result = 0;
for (unsigned origin = 0; origin < ObjectFetchContext::kOriginEnumMax;
++origin) {
result += counts_[type][origin].load(std::memory_order_acquire);
}
return result;
}
void StatsFetchContext::merge(const StatsFetchContext& other) {
for (unsigned type = 0; type < ObjectFetchContext::kObjectTypeEnumMax;
++type) {
for (unsigned origin = 0; origin < ObjectFetchContext::kOriginEnumMax;
++origin) {
counts_[type][origin] += other.counts_[type][origin];
}
}
}
} // namespace eden
} // namespace facebook

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#pragma once
#include <atomic>
#include "eden/fs/store/IObjectStore.h"
namespace facebook {
namespace eden {
class StatsFetchContext : public ObjectFetchContext {
public:
StatsFetchContext() = default;
StatsFetchContext(const StatsFetchContext& other);
void didFetch(ObjectType type, const Hash& id, Origin origin) override;
uint64_t countFetchesOfType(ObjectType type) const;
/**
* Sums the counts from another fetch context into this one.
*/
void merge(const StatsFetchContext& other);
private:
std::atomic<uint64_t> counts_[ObjectFetchContext::kObjectTypeEnumMax]
[ObjectFetchContext::kOriginEnumMax] = {};
};
} // namespace eden
} // namespace facebook