From 6bbe6537cbd31c7ef874e032b218dbdc98baba97 Mon Sep 17 00:00:00 2001 From: tearfur <46261767+tearfur@users.noreply.github.com> Date: Wed, 28 Jun 2023 21:57:26 +0800 Subject: [PATCH] feat: bypass disk write cache when `cache-size-mb` is zero --- docs/Editing-Configuration-Files.md | 2 +- libtransmission/cache.cc | 15 ++++++++++++--- libtransmission/cache.h | 6 ------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/Editing-Configuration-Files.md b/docs/Editing-Configuration-Files.md index bb41a129f..99efcba85 100644 --- a/docs/Editing-Configuration-Files.md +++ b/docs/Editing-Configuration-Files.md @@ -70,7 +70,7 @@ Here is a sample of the three basic types: respectively Boolean, Number and Stri _Note: When **watch-dir-enabled** is true, only the transmission-daemon, transmission-gtk, and transmission-qt applications will monitor **watch-dir** for new .torrent files and automatically load them._ #### Misc - * **cache-size-mb:** Number (default = 4), in megabytes, to allocate for Transmission's memory cache. The cache is used to help batch disk IO together, so increasing the cache size can be used to reduce the number of disk reads and writes. The value is the total available to the Transmission instance. + * **cache-size-mb:** Number (default = 4), in megabytes, to allocate for Transmission's memory cache. The cache is used to help batch disk IO together, so increasing the cache size can be used to reduce the number of disk reads and writes. The value is the total available to the Transmission instance. Setting this to 0 bypasses the cache, which may be useful if your filesystem already has a cache layer that aggregates transactions. * **default-trackers:** String (default = "") A list of double-newline separated tracker announce URLs. These are used for all torrents in addition to the per torrent trackers specified in the torrent file. If a tracker is only meant to be a backup, it should be separated from its main tracker by a single newline character. If a tracker should be used additionally to another tracker it should be separated by two newlines. (e.g. "udp://tracker.example.invalid:1337/announce\n\nudp://tracker.another-example.invalid:6969/announce\nhttps://backup-tracker.another-example.invalid:443/announce\n\nudp://tracker.yet-another-example.invalid:1337/announce", in this case tracker.example.invalid, tracker.another-example.invalid and tracker.yet-another-example.invalid would be used as trackers and backup-tracker.another-example.invalid as backup in case tracker.another-example.invalid is unreachable. * **dht-enabled:** Boolean (default = true) Enable [Distributed Hash Table (DHT)](https://wiki.theory.org/BitTorrentSpecification#Distributed_Hash_Table). * **encryption:** Number (0 = Prefer unencrypted connections, 1 = Prefer encrypted connections, 2 = Require encrypted connections; default = 1) [Encryption](https://wiki.vuze.com/w/Message_Stream_Encryption) preference. Encryption may help get around some ISP filtering, but at the cost of slightly higher CPU use. diff --git a/libtransmission/cache.cc b/libtransmission/cache.cc index d5de357bc..2796ea359 100644 --- a/libtransmission/cache.cc +++ b/libtransmission/cache.cc @@ -119,10 +119,9 @@ size_t Cache::get_max_blocks(size_t max_bytes) noexcept int Cache::set_limit(size_t new_limit) { - max_bytes_ = new_limit; max_blocks_ = get_max_blocks(new_limit); - tr_logAddDebug(fmt::format("Maximum cache size set to {} ({} blocks)", tr_formatter_mem_B(max_bytes_), max_blocks_)); + tr_logAddDebug(fmt::format("Maximum cache size set to {} ({} blocks)", tr_formatter_mem_B(new_limit), max_blocks_)); return cache_trim(); } @@ -130,7 +129,6 @@ int Cache::set_limit(size_t new_limit) Cache::Cache(tr_torrents& torrents, size_t max_bytes) : torrents_{ torrents } , max_blocks_(get_max_blocks(max_bytes)) - , max_bytes_(max_bytes) { } @@ -138,6 +136,17 @@ Cache::Cache(tr_torrents& torrents, size_t max_bytes) int Cache::write_block(tr_torrent_id_t tor_id, tr_block_index_t block, std::unique_ptr writeme) { + if (max_blocks_ == 0U) + { + TR_ASSERT(std::empty(blocks_)); + + // Bypass cache. This may be helpful for those whose filesystem + // already has a cache layer for the very purpose of this cache + // https://github.com/transmission/transmission/pull/5668 + auto* const tor = torrents_.get(tor_id); + return tr_ioWrite(tor, tor->block_loc(block), std::size(*writeme), std::data(*writeme)); + } + auto const key = Key{ tor_id, block }; auto iter = std::lower_bound(std::begin(blocks_), std::end(blocks_), key, CompareCacheBlockByKey{}); if (iter == std::end(blocks_) || iter->key != key) diff --git a/libtransmission/cache.h b/libtransmission/cache.h index 842de5492..0491bf171 100644 --- a/libtransmission/cache.h +++ b/libtransmission/cache.h @@ -33,11 +33,6 @@ public: int set_limit(size_t new_limit); - [[nodiscard]] constexpr auto get_limit() const noexcept - { - return max_bytes_; - } - // @return any error code from cacheTrim() int write_block(tr_torrent_id_t tor, tr_block_index_t block, std::unique_ptr writeme); @@ -96,7 +91,6 @@ private: Blocks blocks_ = {}; size_t max_blocks_ = 0; - size_t max_bytes_ = 0; mutable size_t disk_writes_ = 0; mutable size_t disk_write_bytes_ = 0;