sapling/eden/fs/inodes/TreePrefetchLease.h
Adam Simpkins 983f454135 limit the number of tree prefetch operations that can run in parallel
Summary:
Add a config option to restrict the number of tree prefetches that can run in
parallel.  Without this applications that recursively walk a checkout tree can
end up spawning a huge number of asynchronous prefetch operations.  These
prefetch operations are quite expensive today, as we currently have to fetch
the full file contents in order to retrieve the file sizes.  A recursive
directory walk can end up building up a huge backlog of in-progress tree
prefetches.  This will slow down the directory walk, and it can take tens of
minutes to finish processing the prefetch backlog even after the directory
walk is aborted.

Reviewed By: chadaustin

Differential Revision: D19136685

fbshipit-source-id: cdc7a570d016fd7ca81a639cef83380b197acdfc
2019-12-20 16:14:19 -08:00

56 lines
1.5 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 "eden/fs/inodes/TreeInode.h"
namespace facebook {
namespace eden {
/**
* TreePrefetchLease is a small helper class to track the total number of
* concurrent tree prefetch operations running in an EdenMount.
*
* When TreeInode wants to perform a prefetch it should call
* EdenMount::tryStartTreePrefetch() to obtain a prefetch lease. If it obtains
* a lease it can perform the prefetch, and should hold the TreePrefetchLease
* object around until the prefetch completes. When the TreePrefetchLease is
* destroyed this will inform the EdenMount that the prefetch is complete.
*/
class TreePrefetchLease {
public:
explicit TreePrefetchLease(TreeInodePtr inode) : inode_{std::move(inode)} {}
~TreePrefetchLease() {
release();
}
TreePrefetchLease(TreePrefetchLease&& lease) noexcept
: inode_{std::move(lease.inode_)} {}
TreePrefetchLease& operator=(TreePrefetchLease&& lease) noexcept {
if (&lease != this) {
release();
inode_ = std::move(lease.inode_);
}
return *this;
}
const TreeInodePtr& getTreeInode() const {
return inode_;
}
private:
TreePrefetchLease(const TreePrefetchLease& lease) = delete;
TreePrefetchLease& operator=(const TreePrefetchLease& lease) = delete;
void release() noexcept;
TreeInodePtr inode_;
};
} // namespace eden
} // namespace facebook