2020-03-17 12:29:57 +03:00
|
|
|
/*
|
|
|
|
* 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 <folly/futures/Promise.h>
|
|
|
|
#include <utility>
|
|
|
|
#include <variant>
|
|
|
|
|
|
|
|
#include "eden/fs/model/Blob.h"
|
|
|
|
#include "eden/fs/model/Hash.h"
|
|
|
|
#include "eden/fs/model/Tree.h"
|
|
|
|
#include "eden/fs/store/ImportPriority.h"
|
2020-11-03 07:16:26 +03:00
|
|
|
#include "eden/fs/store/hg/HgProxyHash.h"
|
2020-04-09 22:11:40 +03:00
|
|
|
#include "eden/fs/telemetry/RequestMetricsScope.h"
|
2020-04-07 05:10:31 +03:00
|
|
|
#include "eden/fs/utils/Bug.h"
|
2020-11-19 23:57:23 +03:00
|
|
|
#include "eden/fs/utils/IDGen.h"
|
2020-03-17 12:29:57 +03:00
|
|
|
|
2021-06-09 05:28:36 +03:00
|
|
|
namespace facebook::eden {
|
2020-03-17 12:29:57 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents an Hg import request. This class contains all the necessary
|
|
|
|
* information needed to fulfill the request as well as a promise that will be
|
2021-02-26 22:47:04 +03:00
|
|
|
* resolved after the requested data is imported. Blobs and Trees also contain
|
|
|
|
* a vector of promises to fulfill, corresponding to duplicate requests
|
2020-03-17 12:29:57 +03:00
|
|
|
*/
|
|
|
|
class HgImportRequest {
|
|
|
|
public:
|
2020-04-07 05:10:31 +03:00
|
|
|
struct BlobImport {
|
|
|
|
using Response = std::unique_ptr<Blob>;
|
2021-02-26 22:47:04 +03:00
|
|
|
BlobImport(Hash hash, HgProxyHash proxyHash, bool realRequest = true)
|
|
|
|
: hash(hash), proxyHash(proxyHash), realRequest(realRequest) {}
|
2020-04-07 05:10:31 +03:00
|
|
|
|
|
|
|
Hash hash;
|
2020-11-03 07:16:26 +03:00
|
|
|
HgProxyHash proxyHash;
|
2021-02-26 22:47:04 +03:00
|
|
|
|
|
|
|
// These two variables are used in the HgQueuedBackingStore while
|
|
|
|
// deduplicating requests
|
|
|
|
bool realRequest;
|
|
|
|
std::vector<folly::Promise<Response>> promises;
|
2020-04-07 05:10:31 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct TreeImport {
|
|
|
|
using Response = std::unique_ptr<Tree>;
|
2021-02-26 22:47:04 +03:00
|
|
|
TreeImport(
|
|
|
|
Hash hash,
|
|
|
|
HgProxyHash proxyHash,
|
|
|
|
bool prefetchMetadata = true,
|
|
|
|
bool realRequest = true)
|
|
|
|
: hash(hash),
|
|
|
|
proxyHash(proxyHash),
|
|
|
|
prefetchMetadata(prefetchMetadata),
|
|
|
|
realRequest(realRequest) {}
|
2020-04-07 05:10:31 +03:00
|
|
|
|
|
|
|
Hash hash;
|
2020-11-03 07:16:26 +03:00
|
|
|
HgProxyHash proxyHash;
|
2020-11-12 03:25:37 +03:00
|
|
|
// we normally want to prefetch metadata, there are only a few cases where
|
|
|
|
// we do not want to
|
2021-02-26 22:47:04 +03:00
|
|
|
bool prefetchMetadata;
|
|
|
|
|
|
|
|
// These two variables are used in the HgQueuedBackingStore while
|
|
|
|
// deduplicating requests
|
|
|
|
bool realRequest;
|
|
|
|
std::vector<folly::Promise<Response>> promises;
|
2020-03-17 12:29:57 +03:00
|
|
|
};
|
|
|
|
|
2020-04-07 05:10:31 +03:00
|
|
|
struct Prefetch {
|
|
|
|
using Response = folly::Unit;
|
|
|
|
|
2020-11-03 07:16:26 +03:00
|
|
|
std::vector<HgProxyHash> proxyHashes;
|
2020-04-07 05:10:31 +03:00
|
|
|
};
|
|
|
|
|
2020-11-19 23:57:23 +03:00
|
|
|
static std::pair<HgImportRequest, folly::Future<std::unique_ptr<Blob>>>
|
2020-04-09 22:11:40 +03:00
|
|
|
makeBlobImportRequest(
|
|
|
|
Hash hash,
|
2020-11-03 07:16:26 +03:00
|
|
|
HgProxyHash proxyHash,
|
2020-04-09 22:11:40 +03:00
|
|
|
ImportPriority priority,
|
|
|
|
std::unique_ptr<RequestMetricsScope> metricsScope);
|
2020-03-17 12:29:57 +03:00
|
|
|
|
2020-11-19 23:57:23 +03:00
|
|
|
static std::pair<HgImportRequest, folly::Future<std::unique_ptr<Tree>>>
|
2020-04-09 22:11:40 +03:00
|
|
|
makeTreeImportRequest(
|
|
|
|
Hash hash,
|
2020-11-03 07:16:26 +03:00
|
|
|
HgProxyHash proxyHash,
|
2020-04-09 22:11:40 +03:00
|
|
|
ImportPriority priority,
|
2020-11-12 03:25:37 +03:00
|
|
|
std::unique_ptr<RequestMetricsScope> metricsScope,
|
|
|
|
bool prefetchMetadata);
|
2020-03-17 12:29:57 +03:00
|
|
|
|
2020-11-19 23:57:23 +03:00
|
|
|
static std::pair<HgImportRequest, folly::Future<folly::Unit>>
|
2020-04-09 22:11:40 +03:00
|
|
|
makePrefetchRequest(
|
2020-11-03 07:16:26 +03:00
|
|
|
std::vector<HgProxyHash> hashes,
|
2020-04-09 22:11:40 +03:00
|
|
|
ImportPriority priority,
|
|
|
|
std::unique_ptr<RequestMetricsScope> metricsScope);
|
2020-04-07 05:10:31 +03:00
|
|
|
|
|
|
|
template <typename RequestType>
|
|
|
|
HgImportRequest(
|
|
|
|
RequestType request,
|
|
|
|
ImportPriority priority,
|
2020-05-06 06:55:16 +03:00
|
|
|
folly::Promise<typename RequestType::Response>&& promise)
|
2020-04-07 05:10:31 +03:00
|
|
|
: request_(std::move(request)),
|
|
|
|
priority_(priority),
|
2020-05-06 06:55:16 +03:00
|
|
|
promise_(std::move(promise)) {}
|
2020-04-07 05:10:31 +03:00
|
|
|
|
2020-05-06 06:55:16 +03:00
|
|
|
~HgImportRequest() = default;
|
|
|
|
|
|
|
|
HgImportRequest(HgImportRequest&&) = default;
|
|
|
|
HgImportRequest& operator=(HgImportRequest&&) = default;
|
|
|
|
|
2020-04-07 05:10:31 +03:00
|
|
|
template <typename T>
|
2021-02-26 22:47:04 +03:00
|
|
|
T* getRequest() noexcept {
|
2020-04-07 05:10:31 +03:00
|
|
|
return std::get_if<T>(&request_);
|
2020-03-17 12:29:57 +03:00
|
|
|
}
|
|
|
|
|
2020-05-06 06:55:16 +03:00
|
|
|
template <typename T>
|
|
|
|
bool isType() const noexcept {
|
|
|
|
return std::holds_alternative<T>(request_);
|
|
|
|
}
|
|
|
|
|
2020-05-06 06:55:16 +03:00
|
|
|
size_t getType() const noexcept {
|
|
|
|
return request_.index();
|
|
|
|
}
|
|
|
|
|
2021-02-26 22:47:04 +03:00
|
|
|
ImportPriority getPriority() const noexcept {
|
|
|
|
return priority_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setPriority(ImportPriority priority) noexcept {
|
|
|
|
priority_ = priority;
|
|
|
|
}
|
|
|
|
|
2020-05-06 06:55:16 +03:00
|
|
|
template <typename T>
|
|
|
|
folly::Promise<T>* getPromise() {
|
|
|
|
auto promise = std::get_if<folly::Promise<T>>(&promise_); // Promise<T>
|
2020-04-07 05:10:31 +03:00
|
|
|
|
|
|
|
if (!promise) {
|
|
|
|
EDEN_BUG() << "invalid promise type";
|
|
|
|
}
|
2020-05-06 06:55:16 +03:00
|
|
|
return promise;
|
2020-03-17 12:29:57 +03:00
|
|
|
}
|
|
|
|
|
2020-11-19 23:57:23 +03:00
|
|
|
uint64_t getUnique() const {
|
|
|
|
return unique_;
|
|
|
|
}
|
|
|
|
|
2020-03-17 12:29:57 +03:00
|
|
|
private:
|
2020-05-06 06:55:16 +03:00
|
|
|
HgImportRequest(const HgImportRequest&) = delete;
|
|
|
|
HgImportRequest& operator=(const HgImportRequest&) = delete;
|
|
|
|
|
2020-04-07 05:10:31 +03:00
|
|
|
using Request = std::variant<BlobImport, TreeImport, Prefetch>;
|
2020-04-07 05:10:31 +03:00
|
|
|
using Response = std::variant<
|
|
|
|
folly::Promise<std::unique_ptr<Blob>>,
|
2020-04-07 05:10:31 +03:00
|
|
|
folly::Promise<std::unique_ptr<Tree>>,
|
|
|
|
folly::Promise<folly::Unit>>;
|
2020-03-17 12:29:57 +03:00
|
|
|
|
2020-04-07 05:10:31 +03:00
|
|
|
Request request_;
|
2020-03-17 12:29:57 +03:00
|
|
|
ImportPriority priority_;
|
2020-04-07 05:10:31 +03:00
|
|
|
Response promise_;
|
2020-11-19 23:57:23 +03:00
|
|
|
uint64_t unique_ = generateUniqueID();
|
2020-03-17 12:29:57 +03:00
|
|
|
|
|
|
|
friend bool operator<(
|
|
|
|
const HgImportRequest& lhs,
|
|
|
|
const HgImportRequest& rhs) {
|
|
|
|
return lhs.priority_ < rhs.priority_;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-06-09 05:28:36 +03:00
|
|
|
} // namespace facebook::eden
|