summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2025-07-20 19:42:30 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2025-07-20 19:42:30 +0100
commit1ab6da489e41b1108ba988b2054ffb658fec9202 (patch)
tree6a2017f2e880935db0f7b64435645ea4cfbb6b5a
parentDon't pointlessly collect all the background functions of batch writes (diff)
downloadnetfs-1ab6da489e41b1108ba988b2054ffb658fec9202.tar.bz2
netfs-1ab6da489e41b1108ba988b2054ffb658fec9202.tar.xz
netfs-1ab6da489e41b1108ba988b2054ffb658fec9202.zip
BackgroundOps optimisation
Preallocated, non-pointer promises.
-rw-r--r--netfs/fuse/fuseFiles.cpp60
-rw-r--r--netfs/fuse/fuseFiles.h3
-rw-r--r--netfs/unittests/testEdgeCases.cpp2
3 files changed, 33 insertions, 32 deletions
diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp
index c5f2314..f47138d 100644
--- a/netfs/fuse/fuseFiles.cpp
+++ b/netfs/fuse/fuseFiles.cpp
@@ -171,51 +171,44 @@ namespace NetFS {
if (blockSizes.size1) {
callback(blockSizes.size1);
}
- while (blockSizes.count--) {
+ while (blockSizes.countN--) {
callback(blockSizes.sizeN);
}
}
-
- template<typename T>
- auto
- appendNewDefault(std::vector<std::unique_ptr<T>> & container)
- {
- return container.emplace_back(std::make_unique<T>()).get();
- }
}
int
FuseApp::read(const char *, char * buf, size_t size, off_t offset, struct fuse_file_info * fileInfo)
{
try {
- using BackgroundOps = std::vector<std::unique_ptr<std::promise<int>>>;
+ using BackgroundOps = std::vector<std::promise<int>>;
auto cpy = [buf](off_t blockOffset, const auto && data) -> int {
std::copy(data.begin(), data.end(), buf + blockOffset);
return safe {data.size()};
};
auto collateTotal = [](auto && ops) {
return std::accumulate(ops.begin(), ops.end(), 0, [](auto && total, auto & operation) {
- return total += operation->get_future().get();
+ return total += operation.get_future().get();
});
};
auto openFile = getProxy<OpenFilePtr>(fileInfo->fh);
auto remote = openFile->remote;
auto blockSizes = openFile->blockSizes(size);
if (fcr->Async) {
- BackgroundOps ops;
+ BackgroundOps ops(blockSizes.count());
blockSizeIterate(blockSizes,
- [&ops, &offset, &openFile, &remote, blockOffset = 0U, &cpy](safe<size_t> blockSize) mutable {
- const auto p = appendNewDefault(ops);
+ [&offset, &openFile, &remote, blockOffset = 0U, &cpy, opIter = ops.begin()](
+ safe<size_t> blockSize) mutable {
waitOnWriteRangeAndThen(blockSize, offset, openFile,
- [p, offset, blockOffset, blockSize, &remote, &cpy](const auto &) {
+ [thisOp = opIter++, offset, blockOffset, blockSize, &remote, &cpy](const auto &) {
return remote->readAsync(
offset, blockSize,
- [cpy, p, blockOffset](auto && resultBuf) {
- p->set_value(
+ [cpy, thisOp, blockOffset](auto && resultBuf) {
+ thisOp->set_value(
cpy(blockOffset, std::forward<Ice::ByteSeq>(resultBuf)));
},
- [p](auto error) {
- p->set_exception(std::move(error));
+ [thisOp](auto error) {
+ thisOp->set_exception(std::move(error));
});
});
offset += blockSize;
@@ -224,17 +217,18 @@ namespace NetFS {
return collateTotal(ops);
}
if (openFile->bodyMaxSize < size) {
- BackgroundOps ops;
- blockSizeIterate(
- blockSizes, [&offset, &remote, blockOffset = 0U, &ops, &cpy](safe<size_t> blockSize) mutable {
- const auto p = appendNewDefault(ops);
+ BackgroundOps ops(blockSizes.count());
+ blockSizeIterate(blockSizes,
+ [&offset, &remote, blockOffset = 0U, &cpy, opIter = ops.begin()](
+ safe<size_t> blockSize) mutable {
+ auto thisOp = opIter++;
remote->readAsync(
offset, blockSize,
- [cpy, p, blockOffset](auto && resultBuf) {
- p->set_value(cpy(blockOffset, std::forward<Ice::ByteSeq>(resultBuf)));
+ [cpy, thisOp, blockOffset](auto && resultBuf) {
+ thisOp->set_value(cpy(blockOffset, std::forward<Ice::ByteSeq>(resultBuf)));
},
- [p](auto error) {
- p->set_exception(std::move(error));
+ [thisOp](auto error) {
+ thisOp->set_exception(std::move(error));
});
offset += blockSize;
blockOffset += blockSize;
@@ -301,23 +295,29 @@ namespace NetFS {
FuseApp::OpenFile::blockSizes(size_t total, size_t max) noexcept
{
if (max >= total) { // Simple case, all in remainder block
- return {.size1 = total, .sizeN = 0, .count = 0};
+ return {.size1 = total, .sizeN = 0, .countN = 0};
}
if (total % max == 0) { // Simplish case, multiples of max
- return {.size1 = 0, .sizeN = max, .count = total / max};
+ return {.size1 = 0, .sizeN = max, .countN = total / max};
}
const auto blocks = (total / max);
const auto blockSize = (total / (blocks + 1)) + 1;
const auto batchTotal = blockSize * blocks;
const auto remainder = total - batchTotal;
- return {.size1 = remainder, .sizeN = blockSize, .count = blocks};
+ return {.size1 = remainder, .sizeN = blockSize, .countN = blocks};
}
size_t
FuseApp::OpenFile::BlockSizes::total() const noexcept
{
- return size1 + (sizeN * count);
+ return size1 + (sizeN * countN);
+ }
+
+ size_t
+ FuseApp::OpenFile::BlockSizes::count() const noexcept
+ {
+ return countN + (size1 ? 1 : 0);
}
ssize_t
diff --git a/netfs/fuse/fuseFiles.h b/netfs/fuse/fuseFiles.h
index 4fe38e5..9742236 100644
--- a/netfs/fuse/fuseFiles.h
+++ b/netfs/fuse/fuseFiles.h
@@ -12,9 +12,10 @@ namespace NetFS {
void wait() const;
struct BlockSizes {
- size_t size1, sizeN, count;
+ size_t size1, sizeN, countN;
auto operator<=>(const BlockSizes &) const = default;
[[nodiscard]] size_t total() const noexcept;
+ [[nodiscard]] size_t count() const noexcept;
};
[[nodiscard]] static BlockSizes blockSizes(size_t total, size_t max) noexcept;
diff --git a/netfs/unittests/testEdgeCases.cpp b/netfs/unittests/testEdgeCases.cpp
index 75ff3aa..07f2c18 100644
--- a/netfs/unittests/testEdgeCases.cpp
+++ b/netfs/unittests/testEdgeCases.cpp
@@ -131,7 +131,7 @@ namespace std {
ostream &
operator<<(ostream & s, const FuseMock::OpenFile::BlockSizes & b)
{
- return s << '(' << b.size1 << '+' << b.sizeN << '*' << b.count << ')';
+ return s << '(' << b.size1 << '+' << b.sizeN << '*' << b.countN << ')';
}
}