1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-25 09:13:06 +00:00
transmission/libtransmission/completion.h

194 lines
4.9 KiB
C
Raw Normal View History

// This file Copyright © 2009-2023 Mnemosyne LLC.
2022-08-08 18:05:39 +00:00
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
2006-07-16 19:39:23 +00:00
#pragma once
#ifndef __TRANSMISSION__
#error only libtransmission should #include this header.
#endif
#include <algorithm>
#include <cstdint>
#include <cstddef> // size_t
#include <optional>
#include <vector>
2023-07-08 15:24:03 +00:00
#include "libtransmission/transmission.h"
2023-07-08 15:24:03 +00:00
#include "libtransmission/block-info.h"
#include "libtransmission/bitfield.h"
#include "libtransmission/tr-macros.h"
/**
* @brief knows which blocks and pieces we have
*/
struct tr_completion
{
struct torrent_view
{
virtual bool piece_is_wanted(tr_piece_index_t piece) const = 0;
fix: sonarcloud warnings / code smells (#2242) * fix: use-init-statement Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX1f6EvHJiycnfA7gfrG\&open\=AX1f6EvHJiycnfA7gfrG * fix replace-use-of-new warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX1ZNs41ZmlvCveKTzon\&open\=AX1ZNs41ZmlvCveKTzon * fix has-virtual-functions-but-non-virtual-destructor warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX1ZNs72ZmlvCveKTzo6\&open\=AX1ZNs72ZmlvCveKTzo6 * fix make-variable-const warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX0_a_OVNJn7rAzml_7B\&open\=AX0_a_OVNJn7rAzml_7B * fix remove-redundant-static-specifiers Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06St-81usi2gyYkPTb\&open\=AX06St-81usi2gyYkPTb * fix function-should-be-declared-const Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06St-81usi2gyYkPTd\&open\=AX06St-81usi2gyYkPTd * fix use-init-statement warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06St-81usi2gyYkPTc\&open\=AX06St-81usi2gyYkPTc * fix class-has-virtual-functions-but-non-virtual-destructor warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06Stz41usi2gyYkPTS\&open\=AX06Stz41usi2gyYkPTS * fix remove-commented-out-code warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06St241usi2gyYkPTT\&open\=AX06St241usi2gyYkPTT * fix remove-commented-out-code warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06St241usi2gyYkPTV\&open\=AX06St241usi2gyYkPTV * fix has-virtual-functions-but-non-virtual-destructor warning https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06St241usi2gyYkPTW\&open\=AX06St241usi2gyYkPTW * fix remove-commented-out-code warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX06SuCA1usi2gyYkPTh\&open\=AX06SuCA1usi2gyYkPTh * fix use-init-statement warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX0rAQvnfJ-O-YIDS9xF\&open\=AX0rAQvnfJ-O-YIDS9xF * fix use-init-statement warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX0rAQvnfJ-O-YIDS9xG\&open\=AX0rAQvnfJ-O-YIDS9xG * fix remove-redundant-access-specifier warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX1ZNs5tZmlvCveKTzor\&open\=AX1ZNs5tZmlvCveKTzor * fix use-init-statement warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX01Itl7f_SST5i7BN1l\&open\=AX01Itl7f_SST5i7BN1l * fix use-init-statement warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX0wDijI2l89lDvp1C9P\&open\=AX0wDijI2l89lDvp1C9P * fix use-automatically-managed-memory-instead-of-new warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX1f6E6HJiycnfA7gfrI\&open\=AX1f6E6HJiycnfA7gfrI * fix use-init-statement warning Xref: https://sonarcloud.io/project/issues\?id\=transmission_transmission\&issues\=AX0l8vknEafnvRiIHUEv\&open\=AX0l8vknEafnvRiIHUEv * fixup! fix has-virtual-functions-but-non-virtual-destructor warning
2021-11-28 01:58:35 +00:00
virtual ~torrent_view() = default;
};
explicit tr_completion(torrent_view const* tor, tr_block_info const* block_info)
: tor_{ tor }
, block_info_{ block_info }
, blocks_{ block_info_->block_count() }
{
blocks_.set_has_none();
}
[[nodiscard]] constexpr tr_bitfield const& blocks() const noexcept
{
return blocks_;
}
[[nodiscard]] constexpr bool has_all() const noexcept
{
return has_metainfo() && blocks_.has_all();
}
[[nodiscard]] TR_CONSTEXPR20 bool has_block(tr_block_index_t block) const
{
return blocks_.test(block);
}
[[nodiscard]] bool has_blocks(tr_block_span_t span) const
{
return blocks_.count(span.begin, span.end) == span.end - span.begin;
}
[[nodiscard]] constexpr bool has_none() const noexcept
{
return !has_metainfo() || blocks_.has_none();
}
[[nodiscard]] bool has_piece(tr_piece_index_t piece) const
{
return block_info_->piece_size() != 0 && count_missing_blocks_in_piece(piece) == 0;
}
[[nodiscard]] constexpr uint64_t has_total() const noexcept
{
return size_now_;
}
[[nodiscard]] uint64_t has_valid() const;
[[nodiscard]] auto left_until_done() const
{
return size_when_done() - has_total();
}
[[nodiscard]] constexpr double percent_complete() const
{
auto const denom = block_info_->total_size();
return denom ? std::clamp(double(size_now_) / denom, 0.0, 1.0) : 0.0;
}
[[nodiscard]] double percent_done() const
{
auto const denom = size_when_done();
return denom ? std::clamp(double(size_now_) / denom, 0.0, 1.0) : 0.0;
}
[[nodiscard]] uint64_t size_when_done() const;
2022-08-31 04:17:23 +00:00
[[nodiscard]] tr_completeness status() const
{
if (!has_metainfo())
2022-08-31 04:17:23 +00:00
{
return TR_LEECH;
}
if (has_all())
2022-08-31 04:17:23 +00:00
{
return TR_SEED;
}
if (size_now_ == size_when_done())
2022-08-31 04:17:23 +00:00
{
return TR_PARTIAL_SEED;
}
return TR_LEECH;
}
[[nodiscard]] std::vector<uint8_t> create_piece_bitfield() const;
[[nodiscard]] size_t count_missing_blocks_in_piece(tr_piece_index_t piece) const
{
auto const [begin, end] = block_info_->block_span_for_piece(piece);
return (end - begin) - blocks_.count(begin, end);
}
[[nodiscard]] size_t count_missing_bytes_in_piece(tr_piece_index_t piece) const
{
return block_info_->piece_size(piece) - count_has_bytes_in_piece(piece);
}
void amount_done(float* tab, size_t n_tabs) const;
void add_block(tr_block_index_t block);
void add_piece(tr_piece_index_t piece);
void remove_piece(tr_piece_index_t piece);
void set_has_piece(tr_piece_index_t i, bool has)
{
if (has)
{
add_piece(i);
}
else
{
remove_piece(i);
}
}
void set_has_all() noexcept;
void set_blocks(tr_bitfield blocks);
void invalidate_size_when_done()
{
size_when_done_.reset();
}
[[nodiscard]] uint64_t count_has_bytes_in_span(tr_byte_span_t) const;
[[nodiscard]] constexpr bool has_metainfo() const noexcept
{
return !std::empty(blocks_);
}
private:
[[nodiscard]] uint64_t compute_has_valid() const;
[[nodiscard]] uint64_t compute_size_when_done() const;
[[nodiscard]] uint64_t count_has_bytes_in_piece(tr_piece_index_t piece) const
{
return count_has_bytes_in_span(block_info_->byte_span_for_piece(piece));
}
void remove_block(tr_block_index_t block);
torrent_view const* tor_;
tr_block_info const* block_info_;
tr_bitfield blocks_{ 0 };
// Number of bytes we'll have when done downloading. [0..totalSize]
// Mutable because lazy-calculated
mutable std::optional<uint64_t> size_when_done_;
// Number of verified bytes we have right now. [0..totalSize]
// Mutable because lazy-calculated
mutable std::optional<uint64_t> has_valid_;
// Number of bytes we have now. [0..sizeWhenDone]
uint64_t size_now_ = 0;
};