sapling/eden/fs/store/hg/MetadataImporter.h
Katie Mancini 58d012d8b4 enable metadata fetching by manifest id
Summary:
Previously we fetched metadata by commit hash and path. We knew this would be a
little extra expensive, but turns out this is a lot extra expensive.

Wait why is it expensive?
In short: lots of extra lookups that are not satisfied by cache :(
In long:
1. Each piece of the path would require a read to fetch the fsnode for that tree.
So this means asking for the metadata of a/b/c/d/e means 5 reads.
2. Normally these reads could be cached, but often we would make these requests
with a commit hash for a draft commit. On the server side this info is not
cached for a draft commit, this means a lot of database reads and recalculating.
(Most of the real uses of metadata prefetching is when an engineer is working
on a local commit. We just use the commit hash of the commit the user was on
when fetching metadata for a tree, even if that tree hasn't changed since a public
commit. so this means lots of requests with draft commit hashes).

Fetching by manifest id we are able to bypass this sequential path look up.
(and even if we are on a draft commit, if the tree has not locally changed
since a public commit, the manifest id will be the same as the public commit
avoiding this whole draft commit issue).

This allows us to query scs with a manifest id for a tree.

Reviewed By: wez

Differential Revision: D22990687

fbshipit-source-id: aa81d67de1f1d04a14d174774ee216f5ac6be5ba
2020-08-10 23:53:10 -07:00

81 lines
2.1 KiB
C++

/*
* 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 <memory>
#include <folly/Executor.h>
#include <folly/futures/Future.h>
#include "eden/fs/utils/PathFuncs.h"
namespace facebook {
namespace eden {
class Hash;
class LocalStore;
class MetadataImporter;
class ReloadableConfig;
class Tree;
class TreeMetadata;
using MetadataImporterFactory = std::function<std::unique_ptr<MetadataImporter>(
std::shared_ptr<ReloadableConfig> config,
std::string repoName,
std::shared_ptr<LocalStore> localStore)>;
class MetadataImporter {
public:
virtual ~MetadataImporter() = default;
/**
* Get the metadata for the entries in a tree for the tree specified by the
* edenId
*/
virtual folly::SemiFuture<std::unique_ptr<TreeMetadata>> getTreeMetadata(
const Hash& edenId,
const Hash& manifestId) = 0;
/**
* Returns if metadata fetching is supported on the current platform and
* is configured, if not the DefaultMetadataImporter should be used.
*/
virtual bool metadataFetchingAvailable() = 0;
template <typename T>
static MetadataImporterFactory getMetadataImporterFactory() {
return [](std::shared_ptr<ReloadableConfig> config,
std::string repoName,
std::shared_ptr<LocalStore> localStore) {
return std::make_unique<T>(
std::move(config), std::move(repoName), localStore);
};
}
};
/**
* Metdata importer where all the fetching and storing operations are no-ops.
* To be used when scs metadata fetching is not supported.
*/
class DefaultMetadataImporter : public MetadataImporter {
public:
DefaultMetadataImporter(
std::shared_ptr<ReloadableConfig> /*config*/,
std::string /*repoName*/,
std::shared_ptr<LocalStore> /*localStore*/) {}
folly::SemiFuture<std::unique_ptr<TreeMetadata>> getTreeMetadata(
const Hash& edenId,
const Hash& manifestId) override;
bool metadataFetchingAvailable() override;
};
} // namespace eden
} // namespace facebook