diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-07-20 19:42:30 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-07-20 19:42:30 +0100 |
commit | 1ab6da489e41b1108ba988b2054ffb658fec9202 (patch) | |
tree | 6a2017f2e880935db0f7b64435645ea4cfbb6b5a | |
parent | Don't pointlessly collect all the background functions of batch writes (diff) | |
download | netfs-1ab6da489e41b1108ba988b2054ffb658fec9202.tar.bz2 netfs-1ab6da489e41b1108ba988b2054ffb658fec9202.tar.xz netfs-1ab6da489e41b1108ba988b2054ffb658fec9202.zip |
BackgroundOps optimisation
Preallocated, non-pointer promises.
-rw-r--r-- | netfs/fuse/fuseFiles.cpp | 60 | ||||
-rw-r--r-- | netfs/fuse/fuseFiles.h | 3 | ||||
-rw-r--r-- | netfs/unittests/testEdgeCases.cpp | 2 |
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 << ')'; } } |