move root ID parsing and rendering into BackingStore

Summary:
The meaning of the root ID is defined by the BackingStore, so move
parsing and rendering into the BackingStore interface.

Reviewed By: xavierd

Differential Revision: D28560426

fbshipit-source-id: 7cfed4870d48016811b604348742754f6cdbd842
This commit is contained in:
Chad Austin 2021-06-03 11:05:25 -07:00 committed by Facebook GitHub Bot
parent ebbcef7605
commit 894eaa9840
22 changed files with 201 additions and 70 deletions

View File

@ -316,7 +316,7 @@ Future<vector<GlobNode::GlobResult>> GlobNode::evaluateImpl(
if ((!node->children_.empty() || !node->recursiveChildren_.empty()) &&
root.entryIsTree(entry)) {
if (root.entryShouldLoadChildTree(entry)) {
recurse.emplace_back(std::make_pair(name, node));
recurse.emplace_back(name, node);
} else {
futures.emplace_back(
store->getTree(root.entryHash(entry), context)

View File

@ -484,7 +484,8 @@ std::unique_ptr<JournalDeltaRange> Journal::accumulateRange(
std::vector<DebugJournalDelta> Journal::getDebugRawJournalInfo(
SequenceNumber from,
std::optional<size_t> limit,
long mountGeneration) const {
long mountGeneration,
RootIdCodec& rootIdCodec) const {
auto result = std::vector<DebugJournalDelta>();
auto deltaState = deltaState_.lock();
Hash currentHash = deltaState->currentHash;
@ -492,19 +493,18 @@ std::vector<DebugJournalDelta> Journal::getDebugRawJournalInfo(
*deltaState,
from,
limit,
[mountGeneration, &result, &currentHash](
const FileChangeJournalDelta& current) -> void {
[&](const FileChangeJournalDelta& current) -> void {
DebugJournalDelta delta;
JournalPosition fromPosition;
fromPosition.mountGeneration_ref() = mountGeneration;
fromPosition.sequenceNumber_ref() = current.sequenceID;
fromPosition.snapshotHash_ref() = thriftHash(currentHash);
fromPosition.snapshotHash_ref() = rootIdCodec.renderRootId(currentHash);
delta.fromPosition_ref() = fromPosition;
JournalPosition toPosition;
toPosition.mountGeneration_ref() = mountGeneration;
toPosition.sequenceNumber_ref() = current.sequenceID;
toPosition.snapshotHash_ref() = thriftHash(currentHash);
toPosition.snapshotHash_ref() = rootIdCodec.renderRootId(currentHash);
delta.toPosition_ref() = toPosition;
for (const auto& entry : current.getChangedFilesInOverlay()) {
@ -520,19 +520,19 @@ std::vector<DebugJournalDelta> Journal::getDebugRawJournalInfo(
result.push_back(delta);
},
[mountGeneration, &result, &currentHash](
const HashUpdateJournalDelta& current) -> void {
[&](const HashUpdateJournalDelta& current) -> void {
DebugJournalDelta delta;
JournalPosition fromPosition;
fromPosition.mountGeneration_ref() = mountGeneration;
fromPosition.sequenceNumber_ref() = current.sequenceID;
fromPosition.snapshotHash_ref() = thriftHash(current.fromHash);
fromPosition.snapshotHash_ref() =
rootIdCodec.renderRootId(current.fromHash);
delta.fromPosition_ref() = fromPosition;
JournalPosition toPosition;
toPosition.mountGeneration_ref() = mountGeneration;
toPosition.sequenceNumber_ref() = current.sequenceID;
toPosition.snapshotHash_ref() = thriftHash(currentHash);
toPosition.snapshotHash_ref() = rootIdCodec.renderRootId(currentHash);
delta.toPosition_ref() = toPosition;
currentHash = current.fromHash;

View File

@ -15,6 +15,7 @@
#include <optional>
#include <unordered_map>
#include "eden/fs/journal/JournalDelta.h"
#include "eden/fs/model/RootId.h"
#include "eden/fs/service/ThriftUtil.h"
#include "eden/fs/service/gen-cpp2/StreamingEdenService.h"
#include "eden/fs/telemetry/EdenStats.h"
@ -164,7 +165,8 @@ class Journal {
std::vector<DebugJournalDelta> getDebugRawJournalInfo(
SequenceNumber from,
std::optional<size_t> limit,
long mountGeneration) const;
long mountGeneration,
RootIdCodec& rootIdCodec) const;
/** Removes all prior contents from the journal and sets up the journal in a
* way such that when subscribers are notified they all get truncated results

View File

@ -6,9 +6,12 @@
*/
#include "eden/fs/journal/Journal.h"
#include <folly/portability/GTest.h>
#include <gmock/gmock.h>
#include "eden/fs/model/RootId.h"
using namespace facebook::eden;
namespace {
@ -16,6 +19,7 @@ namespace {
struct JournalTest : ::testing::Test {
std::shared_ptr<EdenStats> edenStats{std::make_shared<EdenStats>()};
Journal journal{edenStats};
HashRootIdCodec codec;
};
} // namespace
@ -196,7 +200,7 @@ TEST_F(JournalTest, debugRawJournalInfoRemoveCreateUpdate) {
long mountGen = 333;
auto debugDeltas = journal.getDebugRawJournalInfo(0, 3, mountGen);
auto debugDeltas = journal.getDebugRawJournalInfo(0, 3, mountGen, codec);
ASSERT_EQ(3, debugDeltas.size());
// Debug Raw Journal Info returns info from newest->latest
@ -222,7 +226,7 @@ TEST_F(JournalTest, debugRawJournalInfoRemoveCreateUpdate) {
*debugDeltas[2].fromPosition_ref()->mountGeneration_ref(), mountGen);
EXPECT_EQ(*debugDeltas[2].fromPosition_ref()->sequenceNumber_ref(), 1);
debugDeltas = journal.getDebugRawJournalInfo(0, 1, mountGen);
debugDeltas = journal.getDebugRawJournalInfo(0, 1, mountGen, codec);
ASSERT_EQ(1, debugDeltas.size());
EXPECT_TRUE(
*debugDeltas[0].changedPaths_ref()["test.txt"].existedBefore_ref());
@ -232,7 +236,7 @@ TEST_F(JournalTest, debugRawJournalInfoRemoveCreateUpdate) {
*debugDeltas[0].fromPosition_ref()->mountGeneration_ref(), mountGen);
EXPECT_EQ(*debugDeltas[0].fromPosition_ref()->sequenceNumber_ref(), 3);
debugDeltas = journal.getDebugRawJournalInfo(0, 0, mountGen);
debugDeltas = journal.getDebugRawJournalInfo(0, 0, mountGen, codec);
ASSERT_EQ(0, debugDeltas.size());
}
@ -250,7 +254,7 @@ TEST_F(JournalTest, debugRawJournalInfoHashUpdates) {
long mountGen = 333;
auto debugDeltas = journal.getDebugRawJournalInfo(0, 3, mountGen);
auto debugDeltas = journal.getDebugRawJournalInfo(0, 3, mountGen, codec);
ASSERT_EQ(3, debugDeltas.size());
// Debug Raw Journal Info returns info from newest->latest

29
eden/fs/model/RootId.h Normal file
View File

@ -0,0 +1,29 @@
/*
* 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 "eden/fs/model/Hash.h"
namespace facebook::eden {
// TODO: This will be expanded to a variable-width type soon.
using RootId = Hash;
/**
* The meaning of a RootId is defined by the BackingStore implementation. Allow
* it to also define how how root IDs are parsed and rendered at API boundaries
* such as Thrift.
*/
class RootIdCodec {
public:
virtual ~RootIdCodec() = default;
virtual RootId parseRootId(folly::StringPiece rootId) = 0;
virtual std::string renderRootId(const RootId& rootId) = 0;
};
} // namespace facebook::eden

View File

@ -446,11 +446,11 @@ void EdenServiceHandler::checkOutRevision(
*mountPoint,
logHash(*hash),
apache::thrift::util::enumName(checkoutMode, "(unknown)"));
auto hashObj = hashFromThrift(*hash);
auto edenMount = server_->getMount(*mountPoint);
auto rootId = edenMount->getObjectStore()->parseRootId(*hash);
auto checkoutFuture = edenMount->checkout(
hashObj,
rootId,
helper->getFetchContext().getClientPid(),
helper->getFunctionName(),
checkoutMode);
@ -462,8 +462,9 @@ void EdenServiceHandler::resetParentCommits(
std::unique_ptr<WorkingDirectoryParents> parents) {
auto helper = INSTRUMENT_THRIFT_CALL(
DBG1, *mountPoint, logHash(*parents->parent1_ref()));
Hash parent1 = hashFromThrift(*parents->parent1_ref());
auto edenMount = server_->getMount(*mountPoint);
auto parent1 =
edenMount->getObjectStore()->parseRootId(*parents->parent1_ref());
edenMount->resetParent(parent1);
}
@ -571,10 +572,12 @@ void EdenServiceHandler::getCurrentJournalPosition(
*out.mountGeneration_ref() = edenMount->getMountGeneration();
if (latest) {
out.sequenceNumber_ref() = latest->sequenceID;
out.snapshotHash_ref() = thriftHash(latest->toHash);
out.snapshotHash_ref() =
edenMount->getObjectStore()->renderRootId(latest->toHash);
} else {
out.sequenceNumber_ref() = 0;
out.snapshotHash_ref() = thriftHash(kZeroHash);
out.snapshotHash_ref() =
edenMount->getObjectStore()->renderRootId(kZeroHash);
}
}
@ -943,15 +946,17 @@ void EdenServiceHandler::getFilesChangedSince(
"Journal entry range has been truncated.");
}
RootIdCodec& rootIdCodec = *edenMount->getObjectStore();
out.toPosition_ref()->sequenceNumber_ref() = summed->toSequence;
out.toPosition_ref()->snapshotHash_ref() =
thriftHash(summed->snapshotTransitions.back());
rootIdCodec.renderRootId(summed->snapshotTransitions.back());
out.toPosition_ref()->mountGeneration_ref() =
edenMount->getMountGeneration();
out.fromPosition_ref()->sequenceNumber_ref() = summed->fromSequence;
out.fromPosition_ref()->snapshotHash_ref() =
thriftHash(summed->snapshotTransitions.front());
rootIdCodec.renderRootId(summed->snapshotTransitions.front());
out.fromPosition_ref()->mountGeneration_ref() =
*out.toPosition_ref()->mountGeneration_ref();
@ -971,7 +976,7 @@ void EdenServiceHandler::getFilesChangedSince(
out.snapshotTransitions_ref()->reserve(summed->snapshotTransitions.size());
for (auto& hash : summed->snapshotTransitions) {
out.snapshotTransitions_ref()->push_back(thriftHash(hash));
out.snapshotTransitions_ref()->push_back(rootIdCodec.renderRootId(hash));
}
}
}
@ -1025,7 +1030,10 @@ void EdenServiceHandler::debugGetRawJournal(
}
out.allDeltas_ref() = edenMount->getJournal().getDebugRawJournalInfo(
*params->fromSequenceNumber_ref(), limitopt, mountGeneration);
*params->fromSequenceNumber_ref(),
limitopt,
mountGeneration,
*edenMount->getObjectStore());
}
folly::SemiFuture<std::unique_ptr<std::vector<EntryInformationOrError>>>
@ -1165,8 +1173,8 @@ folly::Future<std::unique_ptr<Glob>> EdenServiceHandler::future_globFiles(
globResults.reserve(rootHashes->size());
originHashes->reserve(rootHashes->size());
for (auto& rootHash : *rootHashes) {
const Hash& originHash =
originHashes->emplace_back(hashFromThrift(rootHash));
const Hash& originHash = originHashes->emplace_back(
edenMount->getObjectStore()->parseRootId(rootHash));
globResults.emplace_back(
edenMount->getObjectStore()
@ -1369,14 +1377,14 @@ void EdenServiceHandler::async_tm_getScmStatusV2(
folly::to<string>("listIgnored=", *params->listIgnored_ref()));
auto mount = server_->getMount(*params->mountPoint_ref());
auto hash = hashFromThrift(*params->commit_ref());
auto rootId = mount->getObjectStore()->parseRootId(*params->commit_ref());
const auto& enforceParents = server_->getServerState()
->getReloadableConfig()
.getEdenConfig()
->enforceParents.getValue();
return wrapFuture(
std::move(helper),
mount->diff(hash, *params->listIgnored_ref(), enforceParents, request)
mount->diff(rootId, *params->listIgnored_ref(), enforceParents, request)
.thenValue([this, mount](std::unique_ptr<ScmStatus>&& status) {
auto result = std::make_unique<GetScmStatusResult>();
*result->status_ref() = std::move(*status);
@ -1410,7 +1418,7 @@ void EdenServiceHandler::async_tm_getScmStatus(
// want to enforce that even for this call, if we confirm that all existing
// callers of this method can deal with the error.
auto mount = server_->getMount(*mountPoint);
auto hash = hashFromThrift(*commitHash);
auto hash = mount->getObjectStore()->parseRootId(*commitHash);
return wrapFuture(
std::move(helper),
mount->diff(
@ -1432,9 +1440,9 @@ EdenServiceHandler::future_getScmStatusBetweenRevisions(
*mountPoint,
folly::to<string>("oldHash=", logHash(*oldHash)),
folly::to<string>("newHash=", logHash(*newHash)));
auto id1 = hashFromThrift(*oldHash);
auto id2 = hashFromThrift(*newHash);
auto mount = server_->getMount(*mountPoint);
auto id1 = mount->getObjectStore()->parseRootId(*oldHash);
auto id2 = mount->getObjectStore()->parseRootId(*newHash);
return wrapFuture(
std::move(helper),
diffCommitsForStatus(mount->getObjectStore(), id1, id2));
@ -1447,7 +1455,7 @@ void EdenServiceHandler::debugGetScmTree(
bool localStoreOnly) {
auto helper = INSTRUMENT_THRIFT_CALL(DBG3, *mountPoint, logHash(*idStr));
auto edenMount = server_->getMount(*mountPoint);
auto id = hashFromThrift(*idStr);
auto id = edenMount->getObjectStore()->parseRootId(*idStr);
static auto context = ObjectFetchContext::getNullContextWithCauseDetail(
"EdenServiceHandler::debugGetScmTree");
@ -1484,7 +1492,7 @@ void EdenServiceHandler::debugGetScmBlob(
bool localStoreOnly) {
auto helper = INSTRUMENT_THRIFT_CALL(DBG3, *mountPoint, logHash(*idStr));
auto edenMount = server_->getMount(*mountPoint);
auto id = hashFromThrift(*idStr);
auto id = edenMount->getObjectStore()->parseRootId(*idStr);
static auto context = ObjectFetchContext::getNullContextWithCauseDetail(
"EdenServiceHandler::debugGetScmBlob");
@ -1515,7 +1523,7 @@ void EdenServiceHandler::debugGetScmBlobMetadata(
bool localStoreOnly) {
auto helper = INSTRUMENT_THRIFT_CALL(DBG3, *mountPoint, logHash(*idStr));
auto edenMount = server_->getMount(*mountPoint);
auto id = hashFromThrift(*idStr);
auto id = edenMount->getObjectStore()->parseRootId(*idStr);
static auto context = ObjectFetchContext::getNullContextWithCauseDetail(
"EdenServiceHandler::debugGetScmBlobMetadata");

View File

@ -12,11 +12,11 @@
#include <string>
#include "eden/fs/model/Hash.h"
#include "eden/fs/model/RootId.h"
#include "eden/fs/service/gen-cpp2/eden_types.h"
#include "eden/fs/utils/EdenError.h"
namespace facebook {
namespace eden {
namespace facebook::eden {
/**
* Convert a Hash to a std::string to be returned via thrift as a thrift
@ -43,7 +43,7 @@ inline std::string thriftHash(const std::optional<Hash>& hash) {
* This allows the input to be either a 20-byte binary string, or a 40-byte
* hexadecimal string.
*/
inline Hash hashFromThrift(const std::string& commitID) {
inline Hash hashFromThrift(folly::StringPiece commitID) {
if (commitID.size() == Hash::RAW_SIZE) {
// This looks like 20 bytes of binary data.
return Hash(folly::ByteRange(folly::StringPiece(commitID)));
@ -60,5 +60,15 @@ inline Hash hashFromThrift(const std::string& commitID) {
"\"");
}
}
} // namespace eden
} // namespace facebook
class HashRootIdCodec : public RootIdCodec {
public:
Hash parseRootId(folly::StringPiece piece) override {
return hashFromThrift(piece);
}
std::string renderRootId(const Hash& rootId) override {
return thriftHash(rootId);
}
};
} // namespace facebook::eden

View File

@ -11,6 +11,7 @@
#include <folly/futures/Future.h>
#include <memory>
#include "eden/fs/model/RootId.h"
#include "eden/fs/store/ImportPriority.h"
#include "eden/fs/store/ObjectFetchContext.h"
@ -19,12 +20,12 @@ template <typename T>
class Future;
}
namespace facebook {
namespace eden {
namespace facebook::eden {
class Blob;
class Hash;
class Tree;
/**
* Abstract interface for a BackingStore.
*
@ -34,7 +35,7 @@ class Tree;
* BackingStore implementations must be thread-safe, and perform their own
* internal locking.
*/
class BackingStore {
class BackingStore : public RootIdCodec {
public:
BackingStore() {}
virtual ~BackingStore() {}
@ -81,5 +82,5 @@ class BackingStore {
BackingStore(BackingStore const&) = delete;
BackingStore& operator=(BackingStore const&) = delete;
};
} // namespace eden
} // namespace facebook
} // namespace facebook::eden

View File

@ -24,6 +24,14 @@ EmptyBackingStore::EmptyBackingStore() {}
EmptyBackingStore::~EmptyBackingStore() {}
Hash EmptyBackingStore::parseRootId(folly::StringPiece /*rootId*/) {
throw std::domain_error("empty backing store");
}
std::string EmptyBackingStore::renderRootId(const Hash& /*rootId*/) {
throw std::domain_error("empty backing store");
}
SemiFuture<unique_ptr<Tree>> EmptyBackingStore::getTree(
const Hash& /* id */,
ObjectFetchContext& /* context */) {

View File

@ -17,11 +17,14 @@ namespace eden {
* A dummy BackingStore implementation, that always throws std::domain_error
* for any ID that is looked up.
*/
class EmptyBackingStore : public BackingStore {
class EmptyBackingStore final : public BackingStore {
public:
EmptyBackingStore();
~EmptyBackingStore() override;
Hash parseRootId(folly::StringPiece rootId) override;
std::string renderRootId(const Hash& rootId) override;
folly::SemiFuture<std::unique_ptr<Tree>> getTree(
const Hash& id,
ObjectFetchContext& context) override;

View File

@ -104,6 +104,14 @@ void ObjectStore::deprioritizeWhenFetchHeavy(
}
}
Hash ObjectStore::parseRootId(folly::StringPiece rootId) {
return backingStore_->parseRootId(rootId);
}
std::string ObjectStore::renderRootId(const Hash& rootId) {
return backingStore_->renderRootId(rootId);
}
Future<shared_ptr<const Tree>> ObjectStore::getTree(
const Hash& id,
ObjectFetchContext& fetchContext) const {

View File

@ -16,6 +16,7 @@
#include <folly/logging/xlog.h>
#include "eden/fs/config/EdenConfig.h"
#include "eden/fs/model/Hash.h"
#include "eden/fs/model/RootId.h"
#include "eden/fs/store/BlobMetadata.h"
#include "eden/fs/store/IObjectStore.h"
#include "eden/fs/store/ImportPriority.h"
@ -70,6 +71,7 @@ constexpr uint64_t importPriorityDeprioritizeAmount{1};
* data, and may not be available during offline operation.
*/
class ObjectStore : public IObjectStore,
public RootIdCodec,
public std::enable_shared_from_this<ObjectStore> {
public:
static std::shared_ptr<ObjectStore> create(
@ -108,6 +110,19 @@ class ObjectStore : public IObjectStore,
*/
void deprioritizeWhenFetchHeavy(ObjectFetchContext& context) const;
/**
* Each BackingStore implementation defines its interpretation of root IDs.
* This function gives the BackingStore a chance to parse and canonicalize the
* root ID at API boundaries such as Thrift.
*/
Hash parseRootId(folly::StringPiece rootId) override;
/**
* Each BackingStore defines the meaning and encoding of its root ID. Give it
* the chance to render a root ID to Thrift.
*/
std::string renderRootId(const Hash& rootId) override;
/**
* Get a Tree by ID.
*

View File

@ -17,6 +17,7 @@
#include "eden/fs/model/Tree.h"
#include "eden/fs/model/TreeEntry.h"
#include "eden/fs/model/git/GitTree.h"
#include "eden/fs/service/ThriftUtil.h"
#include "eden/fs/store/LocalStore.h"
#include "eden/fs/store/ObjectFetchContext.h"
#include "eden/fs/utils/EnumValue.h"
@ -74,6 +75,14 @@ const char* GitBackingStore::getPath() const {
return git_repository_path(repo_);
}
Hash GitBackingStore::parseRootId(folly::StringPiece rootId) {
return hashFromThrift(rootId);
}
std::string GitBackingStore::renderRootId(const Hash& rootId) {
return thriftHash(rootId);
}
SemiFuture<unique_ptr<Tree>> GitBackingStore::getTree(
const Hash& id,
ObjectFetchContext& /*context*/) {

View File

@ -25,7 +25,7 @@ class LocalStore;
/**
* A BackingStore implementation that loads data out of a git repository.
*/
class GitBackingStore : public BackingStore {
class GitBackingStore final : public BackingStore {
public:
/**
* Create a new GitBackingStore.
@ -44,6 +44,9 @@ class GitBackingStore : public BackingStore {
*/
const char* getPath() const;
Hash parseRootId(folly::StringPiece rootId) override;
std::string renderRootId(const Hash& rootId) override;
folly::SemiFuture<std::unique_ptr<Tree>> getTree(
const Hash& id,
ObjectFetchContext& context) override;

View File

@ -21,6 +21,7 @@
#include "eden/fs/config/ReloadableConfig.h"
#include "eden/fs/model/Blob.h"
#include "eden/fs/service/ThriftUtil.h"
#include "eden/fs/store/BackingStoreLogger.h"
#include "eden/fs/store/LocalStore.h"
#include "eden/fs/store/ObjectFetchContext.h"
@ -261,6 +262,13 @@ void HgQueuedBackingStore::processRequest() {
}
}
Hash HgQueuedBackingStore::parseRootId(folly::StringPiece rootId) {
return hashFromThrift(rootId);
}
std::string HgQueuedBackingStore::renderRootId(const Hash& rootId) {
return thriftHash(rootId);
}
folly::SemiFuture<std::unique_ptr<Tree>> HgQueuedBackingStore::getTree(
const Hash& id,
ObjectFetchContext& context) {

View File

@ -96,7 +96,7 @@ struct HgImportTraceEvent : TraceEventBase {
* these requests via different methods (reading from hgcache, Mononoke,
* debugimporthelper, etc.).
*/
class HgQueuedBackingStore : public BackingStore {
class HgQueuedBackingStore final : public BackingStore {
public:
HgQueuedBackingStore(
std::shared_ptr<LocalStore> localStore,
@ -113,6 +113,9 @@ class HgQueuedBackingStore : public BackingStore {
return *traceBus_;
}
Hash parseRootId(folly::StringPiece rootId) override;
std::string renderRootId(const Hash& rootId) override;
folly::SemiFuture<std::unique_ptr<Tree>> getTree(
const Hash& id,
ObjectFetchContext& context) override;

View File

@ -11,35 +11,40 @@
#include "eden/fs/model/Blob.h"
#include "eden/fs/model/Hash.h"
#include "eden/fs/model/Tree.h"
#include "eden/fs/service/ThriftUtil.h"
#include "eden/fs/store/LocalStore.h"
namespace facebook {
namespace eden {
namespace facebook::eden {
ReCasBackingStore::ReCasBackingStore(
std::shared_ptr<LocalStore> /** localStore **/) {
return;
};
ReCasBackingStore::~ReCasBackingStore() {
return;
};
std::shared_ptr<LocalStore> /** localStore **/) {}
ReCasBackingStore::~ReCasBackingStore() = default;
Hash ReCasBackingStore::parseRootId(folly::StringPiece rootId) {
return hashFromThrift(rootId);
}
std::string ReCasBackingStore::renderRootId(const Hash& rootId) {
return thriftHash(rootId);
}
folly::SemiFuture<std::unique_ptr<Tree>> ReCasBackingStore::getTree(
const Hash& /** id **/,
ObjectFetchContext& /** context **/) {
throw std::domain_error("unimplemented:");
};
}
folly::SemiFuture<std::unique_ptr<Blob>> ReCasBackingStore::getBlob(
const Hash& /** id **/,
ObjectFetchContext& /** context **/) {
throw std::domain_error("unimplemented");
};
}
folly::SemiFuture<std::unique_ptr<Tree>> ReCasBackingStore::getTreeForCommit(
const Hash& /** id **/,
ObjectFetchContext& /** context **/) {
throw std::domain_error("unimplemented");
};
}
} // namespace eden
} // namespace facebook
} // namespace facebook::eden

View File

@ -15,11 +15,14 @@ namespace eden {
class Hash;
class LocalStore;
class ReCasBackingStore : public BackingStore {
class ReCasBackingStore final : public BackingStore {
public:
explicit ReCasBackingStore(std::shared_ptr<LocalStore> localStore);
~ReCasBackingStore() override;
Hash parseRootId(folly::StringPiece rootId) override;
std::string renderRootId(const Hash& rootId) override;
folly::SemiFuture<std::unique_ptr<Tree>> getTree(
const Hash& id,
ObjectFetchContext& context) override;

View File

@ -16,6 +16,7 @@
#include "eden/fs/model/Blob.h"
#include "eden/fs/model/Hash.h"
#include "eden/fs/model/Tree.h"
#include "eden/fs/service/ThriftUtil.h"
#include "eden/fs/store/LocalStore.h"
#include "eden/fs/testharness/FakeTreeBuilder.h"
#include "eden/fs/testharness/TestUtil.h"
@ -35,7 +36,15 @@ namespace eden {
FakeBackingStore::FakeBackingStore(std::shared_ptr<LocalStore> localStore)
: localStore_(std::move(localStore)) {}
FakeBackingStore::~FakeBackingStore() {}
FakeBackingStore::~FakeBackingStore() = default;
Hash FakeBackingStore::parseRootId(folly::StringPiece rootId) {
return hashFromThrift(rootId);
}
std::string FakeBackingStore::renderRootId(const Hash& rootId) {
return thriftHash(rootId);
}
SemiFuture<unique_ptr<Tree>> FakeBackingStore::getTree(
const Hash& id,

View File

@ -28,7 +28,7 @@ class LocalStore;
/**
* A BackingStore implementation for test code.
*/
class FakeBackingStore : public BackingStore {
class FakeBackingStore final : public BackingStore {
public:
struct TreeEntryData;
@ -39,6 +39,9 @@ class FakeBackingStore : public BackingStore {
* BackingStore APIs
*/
Hash parseRootId(folly::StringPiece rootId) override;
std::string renderRootId(const Hash& rootId) override;
folly::SemiFuture<std::unique_ptr<Tree>> getTree(
const Hash& id,
ObjectFetchContext& context) override;

View File

@ -9,18 +9,18 @@
#include <folly/String.h>
#include <folly/futures/Future.h>
#include "eden/fs/service/ThriftUtil.h"
using folly::Future;
using folly::makeFuture;
using std::make_shared;
using std::shared_ptr;
namespace facebook {
namespace eden {
namespace facebook::eden {
FakeObjectStore::FakeObjectStore() {}
FakeObjectStore::FakeObjectStore() = default;
FakeObjectStore::~FakeObjectStore() {}
FakeObjectStore::~FakeObjectStore() = default;
void FakeObjectStore::addTree(Tree&& tree) {
auto treeHash = tree.getHash();
@ -92,5 +92,5 @@ size_t FakeObjectStore::getAccessCount(const Hash& hash) const {
return 0;
}
}
} // namespace eden
} // namespace facebook
} // namespace facebook::eden

View File

@ -24,7 +24,7 @@ namespace eden {
* Fake implementation of IObjectStore that allows the data to be injected
* directly. This is designed to be used for unit tests.
*/
class FakeObjectStore : public IObjectStore {
class FakeObjectStore final : public IObjectStore {
public:
FakeObjectStore();
~FakeObjectStore() override;