// This file Copyright © 2010-2022 Mnemosyne LLC. // It may be used under GPLv2 (SPDX: GPL-2.0), GPLv3 (SPDX: GPL-3.0), // or any future license endorsed by Mnemosyne LLC. // License text can be found in the licenses/ folder. #pragma once #ifndef __TRANSMISSION__ #error only libtransmission should #include this header. #endif #include // intX_t, uintX_t #include // std::pair #include #include "transmission.h" #include "block-info.h" class tr_torrents; struct evbuffer; struct tr_torrent; class Cache { public: Cache(tr_torrents& torrents, int64_t max_bytes); int setLimit(int64_t new_limit); [[nodiscard]] constexpr auto getLimit() const noexcept { return max_bytes_; } int writeBlock(tr_torrent* torrent, tr_block_info::Location loc, uint32_t length, struct evbuffer* writeme); int readBlock(tr_torrent* torrent, tr_block_info::Location loc, uint32_t len, uint8_t* setme); int prefetchBlock(tr_torrent* torrent, tr_block_info::Location loc, uint32_t len); int flushTorrent(tr_torrent* torrent); int flushFile(tr_torrent* torrent, tr_file_index_t file); private: using Key = std::pair; struct CacheBlock { Key key; std::vector buf; time_t time_added = {}; }; using Blocks = std::vector; using CIter = Blocks::const_iterator; struct CompareCacheBlockByKey { [[nodiscard]] constexpr bool operator()(Key const& key, CacheBlock const& block) { return key < block.key; } [[nodiscard]] constexpr bool operator()(CacheBlock const& block, Key const& key) { return block.key < key; } }; [[nodiscard]] static Key makeKey(tr_torrent const* torrent, tr_block_info::Location loc) noexcept; [[nodiscard]] static std::pair findContiguous(CIter const begin, CIter const end, CIter const iter) noexcept; // @return any error code from tr_ioWrite() [[nodiscard]] int writeContiguous(CIter const begin, CIter const end) const; // @return any error code from writeContiguous() [[nodiscard]] int flushSpan(CIter const begin, CIter const end); // @return any error code from writeContiguous() [[nodiscard]] int flushOldest(); // @return any error code from writeContiguous() [[nodiscard]] int cacheTrim(); [[nodiscard]] static size_t getMaxBlocks(int64_t max_bytes) noexcept; [[nodiscard]] CIter getBlock(tr_torrent const* torrent, tr_block_info::Location loc) noexcept; tr_torrents& torrents_; 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; mutable size_t cache_writes_ = 0; mutable size_t cache_write_bytes_ = 0; };