mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 08:47:12 +03:00
be0cd8da1e
Summary: This is the plumbing to allow us to skip Metadata prefetching during eden prefetches. These can trigger a bunch of wasted network requests when we are fetching files anyways. (These network requests are wasted since we fetch the file contents and most of them are being throttled on sandcastle anyways.) We won't necessarily want to skip metadata prefetching always, we will still want it for the watchman queries, but for `eden prefetch` will probably want to skip it. This is why we are making it an option in the GlobParams. Reviewed By: chadaustin Differential Revision: D24640754 fbshipit-source-id: 20db62d4c0e59fe17cb6535c86ac8f1e3877879c
158 lines
4.8 KiB
C++
158 lines
4.8 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.
|
|
*/
|
|
|
|
#include <folly/logging/xlog.h>
|
|
#include <gtest/gtest.h>
|
|
#include <array>
|
|
#include <memory>
|
|
|
|
#include "eden/fs/model/Hash.h"
|
|
#include "eden/fs/store/ImportPriority.h"
|
|
#include "eden/fs/store/ObjectFetchContext.h"
|
|
#include "eden/fs/store/hg/HgImportRequest.h"
|
|
#include "eden/fs/store/hg/HgImportRequestQueue.h"
|
|
#include "eden/fs/store/hg/HgProxyHash.h"
|
|
#include "eden/fs/telemetry/RequestMetricsScope.h"
|
|
#include "eden/fs/utils/IDGen.h"
|
|
|
|
using namespace facebook::eden;
|
|
|
|
Hash uniqueHash() {
|
|
std::array<uint8_t, Hash::RAW_SIZE> bytes = {0};
|
|
auto uid = generateUniqueID();
|
|
std::memcpy(bytes.data(), &uid, sizeof(uid));
|
|
return Hash{bytes};
|
|
}
|
|
|
|
std::pair<Hash, HgImportRequest> makeBlobImportRequest(
|
|
ImportPriority priority,
|
|
RequestMetricsScope::LockedRequestWatchList& pendingImportWatches) {
|
|
auto hgRevHash = uniqueHash();
|
|
auto proxyHash = HgProxyHash{RelativePath{"some_blob"}, hgRevHash};
|
|
auto hash = proxyHash.sha1();
|
|
auto importTracker =
|
|
std::make_unique<RequestMetricsScope>(&pendingImportWatches);
|
|
return std::make_pair(
|
|
hash,
|
|
HgImportRequest::makeBlobImportRequest(
|
|
hash, std::move(proxyHash), priority, std::move(importTracker))
|
|
.first);
|
|
}
|
|
|
|
std::pair<Hash, HgImportRequest> makeTreeImportRequest(
|
|
ImportPriority priority,
|
|
RequestMetricsScope::LockedRequestWatchList& pendingImportWatches) {
|
|
auto hgRevHash = uniqueHash();
|
|
auto proxyHash = HgProxyHash{RelativePath{"some_tree"}, hgRevHash};
|
|
auto hash = proxyHash.sha1();
|
|
auto importTracker =
|
|
std::make_unique<RequestMetricsScope>(&pendingImportWatches);
|
|
return std::make_pair(
|
|
hash,
|
|
HgImportRequest::makeTreeImportRequest(
|
|
hash, std::move(proxyHash), priority, std::move(importTracker), true)
|
|
.first);
|
|
}
|
|
|
|
TEST(HgImportRequestQueueTest, getRequestByPriority) {
|
|
auto queue = HgImportRequestQueue{};
|
|
std::vector<Hash> enqueued;
|
|
RequestMetricsScope::LockedRequestWatchList pendingImportWatches;
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
auto [hash, request] = makeBlobImportRequest(
|
|
ImportPriority(ImportPriorityKind::Normal, i), pendingImportWatches);
|
|
|
|
queue.enqueue(std::move(request));
|
|
enqueued.push_back(hash);
|
|
}
|
|
|
|
auto [smallHash, smallRequest] = makeBlobImportRequest(
|
|
ImportPriority(ImportPriorityKind::Low, 0), pendingImportWatches);
|
|
queue.enqueue(std::move(smallRequest));
|
|
|
|
// the queue should give requests in the reverse order of pushing
|
|
while (!enqueued.empty()) {
|
|
auto expected = enqueued.back();
|
|
enqueued.pop_back();
|
|
|
|
EXPECT_EQ(
|
|
expected,
|
|
queue.dequeue(1).at(0).getRequest<HgImportRequest::BlobImport>()->hash);
|
|
}
|
|
|
|
EXPECT_EQ(
|
|
smallHash,
|
|
queue.dequeue(1).at(0).getRequest<HgImportRequest::BlobImport>()->hash);
|
|
}
|
|
|
|
TEST(HgImportRequestQueueTest, getRequestByPriorityReverse) {
|
|
auto queue = HgImportRequestQueue{};
|
|
std::deque<Hash> enqueued;
|
|
RequestMetricsScope::LockedRequestWatchList pendingImportWatches;
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
auto [hash, request] = makeBlobImportRequest(
|
|
ImportPriority(ImportPriorityKind::Normal, 10 - i),
|
|
pendingImportWatches);
|
|
|
|
queue.enqueue(std::move(request));
|
|
enqueued.push_back(hash);
|
|
}
|
|
|
|
auto [largeHash, largeRequest] = makeBlobImportRequest(
|
|
ImportPriority(ImportPriority::kHigh()), pendingImportWatches);
|
|
queue.enqueue(std::move(largeRequest));
|
|
EXPECT_EQ(
|
|
largeHash,
|
|
queue.dequeue(1).at(0).getRequest<HgImportRequest::BlobImport>()->hash);
|
|
|
|
while (!enqueued.empty()) {
|
|
auto expected = enqueued.front();
|
|
enqueued.pop_front();
|
|
|
|
auto request = queue.dequeue(1);
|
|
|
|
EXPECT_EQ(
|
|
expected,
|
|
request.at(0).getRequest<HgImportRequest::BlobImport>()->hash);
|
|
}
|
|
}
|
|
|
|
TEST(HgImportRequestQueueTest, getMultipleRequests) {
|
|
RequestMetricsScope::LockedRequestWatchList pendingImportWatches;
|
|
|
|
auto queue = HgImportRequestQueue{};
|
|
std::set<Hash> enqueued_blob;
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
{
|
|
auto [hash, request] = makeBlobImportRequest(
|
|
ImportPriority(ImportPriorityKind::Normal, 0), pendingImportWatches);
|
|
|
|
XLOG(INFO) << "enqueuing blob:" << hash;
|
|
|
|
queue.enqueue(std::move(request));
|
|
enqueued_blob.emplace(hash);
|
|
}
|
|
|
|
auto [hash, request] = makeTreeImportRequest(
|
|
ImportPriority(ImportPriorityKind::Normal, 0), pendingImportWatches);
|
|
XLOG(INFO) << "enqueuing tree:" << hash;
|
|
queue.enqueue(std::move(request));
|
|
}
|
|
|
|
auto dequeued = queue.dequeue(20);
|
|
EXPECT_EQ(dequeued.size(), 10);
|
|
for (int i = 0; i < 10; i++) {
|
|
EXPECT_TRUE(
|
|
enqueued_blob.find(
|
|
dequeued.at(i).getRequest<HgImportRequest::BlobImport>()->hash) !=
|
|
enqueued_blob.end());
|
|
}
|
|
}
|