mirror of
https://github.com/facebook/sapling.git
synced 2025-01-07 14:10:42 +03:00
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:
parent
34732ab62c
commit
58f352b807
@ -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.
|
||||
|
@ -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;
|
||||
});
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
53
eden/fs/store/StatsFetchContext.cpp
Normal file
53
eden/fs/store/StatsFetchContext.cpp
Normal 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
|
36
eden/fs/store/StatsFetchContext.h
Normal file
36
eden/fs/store/StatsFetchContext.h
Normal 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
|
Loading…
Reference in New Issue
Block a user