mirror of
https://github.com/transmission/transmission
synced 2025-03-15 16:29:34 +00:00
refactor: tr_block_info class (#2210)
* refactor: add tr_block_info with tests
This commit is contained in:
parent
449b83e340
commit
843e486d2a
17 changed files with 442 additions and 216 deletions
|
@ -49,6 +49,7 @@
|
|||
558699542570759E00F77A43 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55869925257074EC00F77A43 /* libcurl.tbd */; };
|
||||
558699602570759F00F77A43 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55869925257074EC00F77A43 /* libcurl.tbd */; };
|
||||
5586996C2570759F00F77A43 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55869925257074EC00F77A43 /* libcurl.tbd */; };
|
||||
62F644738FE3D8788EBF73A9 /* block-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = A54D44C6A7AAF131D9AE29F5 /* block-info.cc */; };
|
||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
|
||||
8D11072D0486CEB800E47090 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; settings = {ATTRIBUTES = (); }; };
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||
|
@ -366,6 +367,7 @@
|
|||
ED8A16412735A8AA000D61F9 /* peer-mgr-wishlist.h in Headers */ = {isa = PBXBuildFile; fileRef = ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */; };
|
||||
ED8A16422735A8AA000D61F9 /* peer-mgr-wishlist.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */; };
|
||||
EDBDFA9E25AFCCA60093D9C1 /* evutil_time.c in Sources */ = {isa = PBXBuildFile; fileRef = EDBDFA9D25AFCCA60093D9C1 /* evutil_time.c */; };
|
||||
F11545ACA7C4D7A464F703AB /* block-info.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A044CBD8C049AFCBD4DB411 /* block-info.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
F63480631E1D7274005B9E09 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F63480621E1D7274005B9E09 /* Images.xcassets */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
@ -518,10 +520,6 @@
|
|||
4D36BA660CA2F00800A63CA5 /* peer-io.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "peer-io.h"; sourceTree = "<group>"; };
|
||||
4D36BA680CA2F00800A63CA5 /* peer-mgr.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr.cc"; sourceTree = "<group>"; };
|
||||
4D36BA690CA2F00800A63CA5 /* peer-mgr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "peer-mgr.h"; sourceTree = "<group>"; };
|
||||
ED8A163B2735A8AA000D61F9 /* peer-mgr-active-requests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "peer-mgr-active-requests.h"; sourceTree = "<group>"; };
|
||||
ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-active-requests.cc"; sourceTree = "<group>"; };
|
||||
ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "peer-mgr-wishlist.h"; sourceTree = "<group>"; };
|
||||
ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-wishlist.cc"; sourceTree = "<group>"; };
|
||||
4D36BA6A0CA2F00800A63CA5 /* peer-msgs.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-msgs.cc"; sourceTree = "<group>"; };
|
||||
4D36BA6B0CA2F00800A63CA5 /* peer-msgs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "peer-msgs.h"; sourceTree = "<group>"; };
|
||||
4D36BA6C0CA2F00800A63CA5 /* ptrarray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ptrarray.h; sourceTree = "<group>"; };
|
||||
|
@ -544,6 +542,7 @@
|
|||
4DFBC2DD09C0970D00D5C571 /* Torrent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Torrent.h; sourceTree = "<group>"; };
|
||||
4DFBC2DE09C0970D00D5C571 /* Torrent.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Torrent.mm; sourceTree = "<group>"; };
|
||||
55869925257074EC00F77A43 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; };
|
||||
6A044CBD8C049AFCBD4DB411 /* block-info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "block-info.h"; path = "block-info.h"; sourceTree = SOURCE_ROOT; };
|
||||
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
8D1107320486CEB800E47090 /* Transmission.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Transmission.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A200B8390A2263BA007BBB1E /* InfoWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoWindowController.h; sourceTree = "<group>"; };
|
||||
|
@ -938,6 +937,7 @@
|
|||
A2FB07F115F8208300933543 /* nl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
A2FB701A0D95CAEA0001F331 /* GroupsController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupsController.h; sourceTree = "<group>"; };
|
||||
A2FB701B0D95CAEA0001F331 /* GroupsController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = GroupsController.mm; sourceTree = "<group>"; };
|
||||
A54D44C6A7AAF131D9AE29F5 /* block-info.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = block-info.cc; sourceTree = "<group>"; };
|
||||
BE1183480CE160960002D0F3 /* libminiupnp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libminiupnp.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BE11834E0CE160C50002D0F3 /* miniupnpc_declspec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = miniupnpc_declspec.h; sourceTree = "<group>"; };
|
||||
BE11834F0CE160C50002D0F3 /* igd_desc_parse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = igd_desc_parse.h; sourceTree = "<group>"; };
|
||||
|
@ -1028,6 +1028,10 @@
|
|||
CAB35C62252F6F5E00552A55 /* mime-types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mime-types.h"; sourceTree = "<group>"; };
|
||||
E138A9750C04D88F00C5426C /* ProgressGradients.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProgressGradients.h; sourceTree = "<group>"; };
|
||||
E138A9760C04D88F00C5426C /* ProgressGradients.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ProgressGradients.mm; sourceTree = "<group>"; };
|
||||
ED8A163B2735A8AA000D61F9 /* peer-mgr-active-requests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "peer-mgr-active-requests.h"; sourceTree = "<group>"; };
|
||||
ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-active-requests.cc"; sourceTree = "<group>"; };
|
||||
ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "peer-mgr-wishlist.h"; sourceTree = "<group>"; };
|
||||
ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-wishlist.cc"; sourceTree = "<group>"; };
|
||||
EDBDFA9D25AFCCA60093D9C1 /* evutil_time.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = evutil_time.c; sourceTree = "<group>"; };
|
||||
F63480621E1D7274005B9E09 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Images/Images.xcassets; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
@ -1374,6 +1378,8 @@
|
|||
4D1838DC09DEC04A0047D688 /* libtransmission */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A54D44C6A7AAF131D9AE29F5 /* block-info.cc */,
|
||||
6A044CBD8C049AFCBD4DB411 /* block-info.h */,
|
||||
C17740D3273A002C00E455D2 /* web-utils.cc */,
|
||||
C17740D4273A002C00E455D2 /* web-utils.h */,
|
||||
CAB35C62252F6F5E00552A55 /* mime-types.h */,
|
||||
|
@ -1898,6 +1904,7 @@
|
|||
A2EA52321686AC0D00180493 /* quark.h in Headers */,
|
||||
A2AF23C916B44FA0003BC59E /* log.h in Headers */,
|
||||
A23FAE55178BC2950053DC5B /* platform-quota.h in Headers */,
|
||||
F11545ACA7C4D7A464F703AB /* block-info.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -2493,6 +2500,7 @@
|
|||
A2EA52311686AC0D00180493 /* quark.cc in Sources */,
|
||||
A2AF23C816B44FA0003BC59E /* log.cc in Sources */,
|
||||
A23FAE54178BC2950053DC5B /* platform-quota.cc in Sources */,
|
||||
62F644738FE3D8788EBF73A9 /* block-info.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -6,27 +6,28 @@ configure_file(
|
|||
)
|
||||
|
||||
set(PROJECT_FILES
|
||||
announcer.cc
|
||||
announcer-http.cc
|
||||
announcer-udp.cc
|
||||
announcer.cc
|
||||
bandwidth.cc
|
||||
bitfield.cc
|
||||
block-info.cc
|
||||
blocklist.cc
|
||||
cache.cc
|
||||
clients.cc
|
||||
completion.cc
|
||||
crypto.cc
|
||||
crypto-utils.cc
|
||||
crypto-utils-ccrypto.cc
|
||||
crypto-utils-cyassl.cc
|
||||
crypto-utils-fallback.cc
|
||||
crypto-utils-openssl.cc
|
||||
crypto-utils-polarssl.cc
|
||||
crypto-utils.cc
|
||||
crypto.cc
|
||||
error.cc
|
||||
fdlimit.cc
|
||||
file.cc
|
||||
file-posix.cc
|
||||
file-win32.cc
|
||||
file.cc
|
||||
handshake.cc
|
||||
inout.cc
|
||||
log.cc
|
||||
|
@ -36,46 +37,46 @@ set(PROJECT_FILES
|
|||
natpmp.cc
|
||||
net.cc
|
||||
peer-io.cc
|
||||
peer-mgr.cc
|
||||
peer-mgr-active-requests.cc
|
||||
peer-mgr-wishlist.cc
|
||||
peer-mgr.cc
|
||||
peer-msgs.cc
|
||||
platform.cc
|
||||
platform-quota.cc
|
||||
platform.cc
|
||||
port-forwarding.cc
|
||||
ptrarray.cc
|
||||
quark.cc
|
||||
resume.cc
|
||||
rpcimpl.cc
|
||||
rpc-server.cc
|
||||
session.cc
|
||||
rpcimpl.cc
|
||||
session-id.cc
|
||||
session.cc
|
||||
stats.cc
|
||||
subprocess-posix.cc
|
||||
subprocess-win32.cc
|
||||
stats.cc
|
||||
torrent.cc
|
||||
torrent-ctor.cc
|
||||
torrent-magnet.cc
|
||||
tr-dht.cc
|
||||
trevent.cc
|
||||
torrent.cc
|
||||
tr-assert.cc
|
||||
tr-dht.cc
|
||||
tr-getopt.cc
|
||||
tr-lpd.cc
|
||||
tr-udp.cc
|
||||
tr-utp.cc
|
||||
trevent.cc
|
||||
upnp.cc
|
||||
utils.cc
|
||||
variant-benc.cc
|
||||
variant.cc
|
||||
variant-json.cc
|
||||
variant.cc
|
||||
verify.cc
|
||||
watchdir.cc
|
||||
watchdir-generic.cc
|
||||
watchdir-inotify.cc
|
||||
watchdir-kqueue.cc
|
||||
watchdir-win32.cc
|
||||
web.cc
|
||||
watchdir.cc
|
||||
web-utils.cc
|
||||
web.cc
|
||||
webseed.cc
|
||||
)
|
||||
|
||||
|
@ -147,6 +148,7 @@ set(${PROJECT_NAME}_PRIVATE_HEADERS
|
|||
announcer.h
|
||||
bandwidth.h
|
||||
bitfield.h
|
||||
block-info.h
|
||||
blocklist.h
|
||||
cache.h
|
||||
clients.h
|
||||
|
@ -164,9 +166,9 @@ set(${PROJECT_NAME}_PRIVATE_HEADERS
|
|||
net.h
|
||||
peer-common.h
|
||||
peer-io.h
|
||||
peer-mgr.h
|
||||
peer-mgr-active-requests.h
|
||||
peer-mgr-wishlist.h
|
||||
peer-mgr.h
|
||||
peer-msgs.h
|
||||
peer-socket.h
|
||||
platform-quota.h
|
||||
|
|
87
libtransmission/block-info.cc
Normal file
87
libtransmission/block-info.cc
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007-2014 Mnemosyne LLC
|
||||
*
|
||||
* It may be used under the GNU GPL versions 2 or 3
|
||||
* or any future license endorsed by Mnemosyne LLC.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <event2/util.h>
|
||||
|
||||
#include "transmission.h"
|
||||
|
||||
#include "block-info.h"
|
||||
|
||||
// Decide on a block size. Constraints:
|
||||
// (1) most clients decline requests over 16 KiB
|
||||
// (2) pieceSize must be a multiple of block size
|
||||
uint32_t tr_block_info::bestBlockSize(uint64_t piece_size)
|
||||
{
|
||||
uint32_t b = piece_size;
|
||||
|
||||
auto constexpr MaxBlockSize = uint32_t{ 1024 * 16 };
|
||||
while (b > MaxBlockSize)
|
||||
{
|
||||
b /= 2U;
|
||||
}
|
||||
|
||||
if (b == 0 || piece_size % b != 0) // not cleanly divisible
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void tr_block_info::initSizes(uint64_t total_size_in, uint64_t piece_size_in)
|
||||
{
|
||||
total_size = total_size_in;
|
||||
piece_size = piece_size_in;
|
||||
block_size = bestBlockSize(piece_size);
|
||||
|
||||
if (piece_size == 0 || block_size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
n_pieces = (total_size + piece_size - 1) / piece_size;
|
||||
|
||||
auto remainder = total_size % piece_size;
|
||||
final_piece_size = remainder ? remainder : piece_size;
|
||||
|
||||
remainder = total_size % block_size;
|
||||
final_block_size = remainder ? remainder : block_size;
|
||||
|
||||
if (block_size != 0)
|
||||
{
|
||||
n_blocks = (total_size + block_size - 1) / block_size;
|
||||
n_blocks_in_piece = piece_size / block_size;
|
||||
n_blocks_in_final_piece = (final_piece_size + block_size - 1) / block_size;
|
||||
}
|
||||
|
||||
#ifdef TR_ENABLE_ASSERTS
|
||||
// check our work
|
||||
if (block_size != 0)
|
||||
{
|
||||
TR_ASSERT(piece_size % block_size == 0);
|
||||
}
|
||||
|
||||
uint64_t t = n_pieces - 1;
|
||||
t *= piece_size;
|
||||
t += final_piece_size;
|
||||
TR_ASSERT(t == total_size);
|
||||
|
||||
t = n_blocks - 1;
|
||||
t *= block_size;
|
||||
t += final_block_size;
|
||||
TR_ASSERT(t == total_size);
|
||||
|
||||
t = n_pieces - 1;
|
||||
t *= n_blocks_in_piece;
|
||||
t += n_blocks_in_final_piece;
|
||||
TR_ASSERT(t == n_blocks);
|
||||
#endif
|
||||
}
|
93
libtransmission/block-info.h
Normal file
93
libtransmission/block-info.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* This file Copyright (C) Mnemosyne LLC
|
||||
*
|
||||
* It may be used under the GNU GPL versions 2 or 3
|
||||
* or any future license endorsed by Mnemosyne LLC.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __TRANSMISSION__
|
||||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
|
||||
#include "transmission.h"
|
||||
|
||||
#include "metainfo.h"
|
||||
|
||||
struct tr_block_info
|
||||
{
|
||||
uint64_t total_size = 0;
|
||||
uint64_t piece_size = 0;
|
||||
uint64_t n_pieces = 0;
|
||||
|
||||
tr_block_index_t n_blocks = 0;
|
||||
tr_block_index_t n_blocks_in_piece = 0;
|
||||
tr_block_index_t n_blocks_in_final_piece = 0;
|
||||
uint32_t block_size = 0;
|
||||
uint32_t final_block_size = 0;
|
||||
uint32_t final_piece_size = 0;
|
||||
|
||||
tr_block_info() = default;
|
||||
tr_block_info(uint64_t total_size, uint64_t piece_size)
|
||||
{
|
||||
initSizes(total_size, piece_size);
|
||||
}
|
||||
|
||||
void initSizes(uint64_t total_size_in, uint64_t piece_size_in);
|
||||
|
||||
constexpr tr_piece_index_t pieceForBlock(tr_block_index_t block) const
|
||||
{
|
||||
return n_blocks_in_piece ? block / n_blocks_in_piece : 0;
|
||||
}
|
||||
|
||||
constexpr uint32_t countBytesInPiece(tr_piece_index_t piece) const
|
||||
{
|
||||
// how many bytes are in this piece?
|
||||
return piece + 1 == n_pieces ? final_piece_size : piece_size;
|
||||
}
|
||||
|
||||
constexpr uint32_t countBytesInBlock(tr_block_index_t block) const
|
||||
{
|
||||
// how many bytes are in this block?
|
||||
return block + 1 == n_blocks ? final_block_size : block_size;
|
||||
}
|
||||
|
||||
constexpr tr_block_index_t blockOf(uint64_t offset) const
|
||||
{
|
||||
return offset / block_size;
|
||||
}
|
||||
|
||||
constexpr uint64_t offset(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
{
|
||||
auto ret = piece_size;
|
||||
ret *= piece;
|
||||
ret += offset;
|
||||
ret += length;
|
||||
return ret;
|
||||
}
|
||||
|
||||
constexpr tr_block_index_t blockOf(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
{
|
||||
return blockOf(this->offset(piece, offset, length));
|
||||
}
|
||||
|
||||
constexpr tr_block_range_t blockRangeForPiece(tr_piece_index_t piece) const
|
||||
{
|
||||
if (block_size == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
uint64_t offset = piece_size;
|
||||
offset *= piece;
|
||||
tr_block_index_t const first_block = offset / block_size;
|
||||
offset += countBytesInPiece(piece) - 1;
|
||||
tr_block_index_t const final_block = offset / block_size;
|
||||
|
||||
return { first_block, final_block };
|
||||
}
|
||||
|
||||
static uint32_t bestBlockSize(uint64_t piece_size);
|
||||
};
|
|
@ -309,7 +309,7 @@ static struct cache_block* findBlock(tr_cache* cache, tr_torrent* torrent, tr_pi
|
|||
{
|
||||
struct cache_block key;
|
||||
key.tor = torrent;
|
||||
key.block = _tr_block(torrent, piece, offset);
|
||||
key.block = torrent->blockOf(piece, offset);
|
||||
return static_cast<struct cache_block*>(tr_ptrArrayFindSorted(&cache->blocks, &key, cache_block_compare));
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ int tr_cacheWriteBlock(
|
|||
cb->piece = piece;
|
||||
cb->offset = offset;
|
||||
cb->length = length;
|
||||
cb->block = _tr_block(torrent, piece, offset);
|
||||
cb->block = torrent->blockOf(piece, offset);
|
||||
cb->evbuf = evbuffer_new();
|
||||
tr_ptrArrayInsertSorted(&cache->blocks, cb, cache_block_compare);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ static void tr_cpReset(tr_completion* cp)
|
|||
void tr_cpConstruct(tr_completion* cp, tr_torrent* tor)
|
||||
{
|
||||
cp->tor = tor;
|
||||
cp->blockBitfield = new tr_bitfield(tor->blockCount);
|
||||
cp->blockBitfield = new tr_bitfield(tor->n_blocks);
|
||||
tr_cpReset(cp);
|
||||
}
|
||||
|
||||
|
@ -42,12 +42,12 @@ void tr_cpBlockInit(tr_completion* cp, tr_bitfield const& b)
|
|||
|
||||
// set sizeNow
|
||||
cp->sizeNow = cp->blockBitfield->count();
|
||||
TR_ASSERT(cp->sizeNow <= cp->tor->blockCount);
|
||||
cp->sizeNow *= cp->tor->blockSize;
|
||||
TR_ASSERT(cp->sizeNow <= cp->tor->n_blocks);
|
||||
cp->sizeNow *= cp->tor->block_size;
|
||||
|
||||
if (b.test(cp->tor->blockCount - 1))
|
||||
if (b.test(cp->tor->n_blocks - 1))
|
||||
{
|
||||
cp->sizeNow -= (cp->tor->blockSize - cp->tor->lastBlockSize);
|
||||
cp->sizeNow -= (cp->tor->block_size - cp->tor->final_block_size);
|
||||
}
|
||||
|
||||
TR_ASSERT(cp->sizeNow <= cp->tor->info.totalSize);
|
||||
|
@ -80,12 +80,12 @@ tr_completeness tr_cpGetStatus(tr_completion const* cp)
|
|||
void tr_cpPieceRem(tr_completion* cp, tr_piece_index_t piece)
|
||||
{
|
||||
tr_torrent const* tor = cp->tor;
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(cp->tor, piece);
|
||||
for (tr_block_index_t i = first; i <= last; ++i)
|
||||
auto const [first, last] = cp->tor->blockRangeForPiece(piece);
|
||||
for (tr_block_index_t block = first; block <= last; ++block)
|
||||
{
|
||||
if (tr_cpBlockIsComplete(cp, i))
|
||||
if (tr_cpBlockIsComplete(cp, block))
|
||||
{
|
||||
cp->sizeNow -= tr_torBlockCountBytes(tor, i);
|
||||
cp->sizeNow -= tor->countBytesInBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ void tr_cpPieceRem(tr_completion* cp, tr_piece_index_t piece)
|
|||
|
||||
void tr_cpPieceAdd(tr_completion* cp, tr_piece_index_t piece)
|
||||
{
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(cp->tor, piece);
|
||||
auto const [first, last] = cp->tor->blockRangeForPiece(piece);
|
||||
for (tr_block_index_t i = first; i <= last; ++i)
|
||||
{
|
||||
tr_cpBlockAdd(cp, i);
|
||||
|
@ -109,10 +109,10 @@ void tr_cpBlockAdd(tr_completion* cp, tr_block_index_t block)
|
|||
|
||||
if (!tr_cpBlockIsComplete(cp, block))
|
||||
{
|
||||
tr_piece_index_t const piece = tr_torBlockPiece(cp->tor, block);
|
||||
tr_piece_index_t const piece = cp->tor->pieceForBlock(block);
|
||||
|
||||
cp->blockBitfield->set(block);
|
||||
cp->sizeNow += tr_torBlockCountBytes(tor, block);
|
||||
cp->sizeNow += tor->countBytesInBlock(block);
|
||||
|
||||
cp->haveValidIsDirty = true;
|
||||
cp->sizeWhenDoneIsDirty = cp->sizeWhenDoneIsDirty || tor->pieceIsDnd(piece);
|
||||
|
@ -136,7 +136,7 @@ uint64_t tr_cpHaveValid(tr_completion const* ccp)
|
|||
{
|
||||
if (tr_cpPieceIsComplete(ccp, i))
|
||||
{
|
||||
size += tr_torPieceCountBytes(tor, i);
|
||||
size += tor->countBytesInPiece(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ uint64_t tr_cpSizeWhenDone(tr_completion const* ccp)
|
|||
for (tr_piece_index_t p = 0; p < inf->pieceCount; ++p)
|
||||
{
|
||||
uint64_t n = 0;
|
||||
uint64_t const pieceSize = tr_torPieceCountBytes(tor, p);
|
||||
uint64_t const pieceSize = tor->countBytesInPiece(p);
|
||||
|
||||
if (!tor->pieceIsDnd(p))
|
||||
{
|
||||
|
@ -173,18 +173,17 @@ uint64_t tr_cpSizeWhenDone(tr_completion const* ccp)
|
|||
}
|
||||
else
|
||||
{
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(cp->tor, p);
|
||||
|
||||
auto const [first, last] = cp->tor->blockRangeForPiece(p);
|
||||
n = cp->blockBitfield->count(first, last + 1);
|
||||
n *= cp->tor->blockSize;
|
||||
n *= cp->tor->block_size;
|
||||
|
||||
if (last == cp->tor->blockCount - 1 && cp->blockBitfield->test(last))
|
||||
if (last == cp->tor->n_blocks - 1 && cp->blockBitfield->test(last))
|
||||
{
|
||||
n -= cp->tor->blockSize - cp->tor->lastBlockSize;
|
||||
n -= cp->tor->block_size - cp->tor->final_block_size;
|
||||
}
|
||||
}
|
||||
|
||||
TR_ASSERT(n <= tr_torPieceCountBytes(tor, p));
|
||||
TR_ASSERT(n <= tor->countBytesInPiece(p));
|
||||
size += n;
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +221,7 @@ void tr_cpGetAmountDone(tr_completion const* cp, float* tab, int tabCount)
|
|||
else
|
||||
{
|
||||
tr_piece_index_t const piece = (tr_piece_index_t)i * interval;
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(cp->tor, piece);
|
||||
auto const [first, last] = cp->tor->blockRangeForPiece(piece);
|
||||
tab[i] = cp->blockBitfield->count(first, last + 1) / (float)(last + 1 - first);
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +234,7 @@ size_t tr_cpMissingBlocksInPiece(tr_completion const* cp, tr_piece_index_t piece
|
|||
return 0;
|
||||
}
|
||||
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(cp->tor, piece);
|
||||
auto const [first, last] = cp->tor->blockRangeForPiece(piece);
|
||||
return (last + 1 - first) - cp->blockBitfield->count(first, last + 1);
|
||||
}
|
||||
|
||||
|
@ -246,8 +245,8 @@ size_t tr_cpMissingBytesInPiece(tr_completion const* cp, tr_piece_index_t piece)
|
|||
return 0;
|
||||
}
|
||||
|
||||
size_t const pieceByteSize = tr_torPieceCountBytes(cp->tor, piece);
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(cp->tor, piece);
|
||||
size_t const pieceByteSize = cp->tor->countBytesInPiece(piece);
|
||||
auto const [first, last] = cp->tor->blockRangeForPiece(piece);
|
||||
|
||||
auto haveBytes = size_t{};
|
||||
if (first != last)
|
||||
|
@ -256,12 +255,12 @@ size_t tr_cpMissingBytesInPiece(tr_completion const* cp, tr_piece_index_t piece)
|
|||
It's faster to handle the last block separately because its size
|
||||
needs to be checked separately. */
|
||||
haveBytes = cp->blockBitfield->count(first, last);
|
||||
haveBytes *= cp->tor->blockSize;
|
||||
haveBytes *= cp->tor->block_size;
|
||||
}
|
||||
|
||||
if (cp->blockBitfield->test(last)) /* handle the last block */
|
||||
{
|
||||
haveBytes += tr_torBlockCountBytes(cp->tor, last);
|
||||
haveBytes += cp->tor->countBytesInBlock(last);
|
||||
}
|
||||
|
||||
TR_ASSERT(haveBytes <= pieceByteSize);
|
||||
|
|
|
@ -260,12 +260,12 @@ static std::optional<tr_sha1_digest_t> recalculateHash(tr_torrent* tor, tr_piece
|
|||
TR_ASSERT(tor != nullptr);
|
||||
TR_ASSERT(piece < tor->info.pieceCount);
|
||||
|
||||
auto bytes_left = size_t{ tr_torPieceCountBytes(tor, piece) };
|
||||
auto bytes_left = size_t{ tor->countBytesInPiece(piece) };
|
||||
auto offset = uint32_t{};
|
||||
tr_ioPrefetch(tor, piece, offset, bytes_left);
|
||||
|
||||
auto sha = tr_sha1_init();
|
||||
auto buffer = std::vector<uint8_t>(tor->blockSize);
|
||||
auto buffer = std::vector<uint8_t>(tor->block_size);
|
||||
while (bytes_left != 0)
|
||||
{
|
||||
size_t const len = std::min(bytes_left, std::size(buffer));
|
||||
|
|
|
@ -225,7 +225,7 @@ tr_peer::tr_peer(tr_torrent const* tor, peer_atom* atom_in)
|
|||
: session{ tor->session }
|
||||
, atom{ atom_in }
|
||||
, swarm{ tor->swarm }
|
||||
, blame{ tor->blockCount }
|
||||
, blame{ tor->n_blocks }
|
||||
, have{ tor->info.pieceCount }
|
||||
{
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ static void updateEndgame(tr_swarm* s)
|
|||
{
|
||||
/* we consider ourselves to be in endgame if the number of bytes
|
||||
we've got requested is >= the number of bytes left to download */
|
||||
s->endgame = uint64_t(std::size(s->active_requests)) * s->tor->blockSize >= tr_torrentGetLeftUntilDone(s->tor);
|
||||
s->endgame = uint64_t(std::size(s->active_requests)) * s->tor->block_size >= tr_torrentGetLeftUntilDone(s->tor);
|
||||
}
|
||||
|
||||
std::vector<tr_block_range_t> tr_peerMgrGetNextRequests(tr_torrent* torrent, tr_peer* peer, size_t numwant)
|
||||
|
@ -596,7 +596,7 @@ std::vector<tr_block_range_t> tr_peerMgrGetNextRequests(tr_torrent* torrent, tr_
|
|||
|
||||
tr_block_range_t blockRange(tr_piece_index_t piece) const override
|
||||
{
|
||||
return tr_torGetPieceBlockRange(torrent_, piece);
|
||||
return torrent_->blockRangeForPiece(piece);
|
||||
}
|
||||
|
||||
tr_piece_index_t countAllPieces() const override
|
||||
|
@ -725,14 +725,14 @@ static void peerSuggestedPiece(tr_swarm* /*s*/, tr_peer* /*peer*/, tr_piece_inde
|
|||
/* request the blocks that we don't have in this piece */
|
||||
{
|
||||
tr_torrent const* tor = t->tor;
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(t->tor, pieceIndex);
|
||||
auto const [first, last] = tor->blockRangeForPiece(pieceIndex);
|
||||
|
||||
for (tr_block_index_t b = first; b <= last; ++b)
|
||||
{
|
||||
if (tr_torrentBlockIsComplete(tor, b))
|
||||
{
|
||||
uint32_t const offset = getBlockOffsetInPiece(tor, b);
|
||||
uint32_t const length = tr_torBlockCountBytes(tor, b);
|
||||
uint32_t const length = tor->countBytesInBlock(b);
|
||||
tr_peerMsgsAddRequest(peer->msgs, pieceIndex, offset, length);
|
||||
incrementPieceRequests(t, pieceIndex);
|
||||
}
|
||||
|
@ -762,7 +762,7 @@ void tr_peerMgrPieceCompleted(tr_torrent* tor, tr_piece_index_t p)
|
|||
|
||||
if (pieceCameFromPeers) /* webseed downloads don't belong in announce totals */
|
||||
{
|
||||
tr_announcerAddBytes(tor, TR_ANN_DOWN, tr_torPieceCountBytes(tor, p));
|
||||
tr_announcerAddBytes(tor, TR_ANN_DOWN, tor->countBytesInPiece(p));
|
||||
}
|
||||
|
||||
/* bookkeeping */
|
||||
|
@ -824,7 +824,7 @@ static void peerCallbackFunc(tr_peer* peer, tr_peer_event const* e, void* vs)
|
|||
break;
|
||||
|
||||
case TR_PEER_CLIENT_GOT_REJ:
|
||||
s->active_requests.remove(_tr_block(s->tor, e->pieceIndex, e->offset), peer);
|
||||
s->active_requests.remove(s->tor->blockOf(e->pieceIndex, e->offset), peer);
|
||||
break;
|
||||
|
||||
case TR_PEER_CLIENT_GOT_CHOKE:
|
||||
|
@ -851,7 +851,7 @@ static void peerCallbackFunc(tr_peer* peer, tr_peer_event const* e, void* vs)
|
|||
{
|
||||
tr_torrent* tor = s->tor;
|
||||
tr_piece_index_t const p = e->pieceIndex;
|
||||
tr_block_index_t const block = _tr_block(tor, p, e->offset);
|
||||
tr_block_index_t const block = tor->blockOf(p, e->offset);
|
||||
cancelAllRequestsForBlock(s, block, peer);
|
||||
peer->blocksSentToClient.add(tr_time(), 1);
|
||||
tr_torrentGotBlock(tor, block);
|
||||
|
@ -1243,7 +1243,7 @@ tr_pex* tr_peerMgrCompact6ToPex(
|
|||
void tr_peerMgrGotBadPiece(tr_torrent* tor, tr_piece_index_t pieceIndex)
|
||||
{
|
||||
tr_swarm* s = tor->swarm;
|
||||
uint32_t const byteCount = tr_torPieceCountBytes(tor, pieceIndex);
|
||||
uint32_t const byteCount = tor->countBytesInPiece(pieceIndex);
|
||||
|
||||
for (int i = 0, n = tr_ptrArraySize(&s->peers); i != n; ++i)
|
||||
{
|
||||
|
|
|
@ -358,7 +358,7 @@ public:
|
|||
|
||||
bool is_reading_block(tr_block_index_t block) const override
|
||||
{
|
||||
return state == AwaitingBtPiece && block == _tr_block(torrent, incoming.blockReq.index, incoming.blockReq.offset);
|
||||
return state == AwaitingBtPiece && block == torrent->blockOf(incoming.blockReq.index, incoming.blockReq.offset);
|
||||
}
|
||||
|
||||
void cancel_block_request(tr_block_index_t block) override
|
||||
|
@ -1885,7 +1885,7 @@ static int clientGotBlock(tr_peerMsgsImpl* msgs, struct evbuffer* data, struct p
|
|||
TR_ASSERT(req != nullptr);
|
||||
|
||||
tr_torrent* tor = msgs->torrent;
|
||||
tr_block_index_t const block = _tr_block(tor, req->index, req->offset);
|
||||
tr_block_index_t const block = tor->blockOf(req->index, req->offset);
|
||||
|
||||
if (!requestIsValid(msgs, req))
|
||||
{
|
||||
|
@ -1893,9 +1893,9 @@ static int clientGotBlock(tr_peerMsgsImpl* msgs, struct evbuffer* data, struct p
|
|||
return EBADMSG;
|
||||
}
|
||||
|
||||
if (req->length != tr_torBlockCountBytes(msgs->torrent, block))
|
||||
if (req->length != msgs->torrent->countBytesInBlock(block))
|
||||
{
|
||||
dbgmsg(msgs, "wrong block size -- expected %u, got %d", tr_torBlockCountBytes(msgs->torrent, block), req->length);
|
||||
dbgmsg(msgs, "wrong block size -- expected %u, got %d", msgs->torrent->countBytesInBlock(block), req->length);
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
|
@ -2027,7 +2027,7 @@ static void updateDesiredRequestCount(tr_peerMsgsImpl* msgs)
|
|||
* many requests we should send to this peer */
|
||||
size_t constexpr Floor = 32;
|
||||
size_t constexpr Seconds = RequestBufSecs;
|
||||
size_t const estimated_blocks_in_period = (rate_Bps * Seconds) / torrent->blockSize;
|
||||
size_t const estimated_blocks_in_period = (rate_Bps * Seconds) / torrent->block_size;
|
||||
size_t const ceil = msgs->reqq ? *msgs->reqq : 250;
|
||||
msgs->desired_request_count = std::clamp(estimated_blocks_in_period, Floor, ceil);
|
||||
}
|
||||
|
@ -2194,7 +2194,7 @@ static size_t fillOutputBuffer(tr_peerMsgsImpl* msgs, time_t now)
|
|||
*** Data Blocks
|
||||
**/
|
||||
|
||||
if (tr_peerIoGetWriteBufferSpace(msgs->io, now) >= msgs->torrent->blockSize && popNextRequest(msgs, &req))
|
||||
if (tr_peerIoGetWriteBufferSpace(msgs->io, now) >= msgs->torrent->block_size && popNextRequest(msgs, &req))
|
||||
{
|
||||
--msgs->prefetchCount;
|
||||
|
||||
|
|
|
@ -615,7 +615,7 @@ static uint64_t loadProgress(tr_variant* dict, tr_torrent* tor)
|
|||
|
||||
/// COMPLETION
|
||||
|
||||
auto blocks = tr_bitfield{ tor->blockCount };
|
||||
auto blocks = tr_bitfield{ tor->n_blocks };
|
||||
char const* err = nullptr;
|
||||
auto sv = std::string_view{};
|
||||
tr_variant const* const b = tr_variantDictFind(prog, TR_KEY_blocks);
|
||||
|
|
|
@ -721,63 +721,10 @@ uint32_t tr_getBlockSize(uint32_t pieceSize)
|
|||
return b;
|
||||
}
|
||||
|
||||
static void refreshCurrentDir(tr_torrent* tor);
|
||||
|
||||
static void torrentInitFromInfo(tr_torrent* tor)
|
||||
{
|
||||
tr_info const* const info = &tor->info;
|
||||
|
||||
tor->blockSize = tr_getBlockSize(info->pieceSize);
|
||||
|
||||
if (info->pieceSize != 0)
|
||||
{
|
||||
tor->lastPieceSize = (uint32_t)(info->totalSize % info->pieceSize);
|
||||
}
|
||||
|
||||
if (tor->lastPieceSize == 0)
|
||||
{
|
||||
tor->lastPieceSize = info->pieceSize;
|
||||
}
|
||||
|
||||
if (tor->blockSize != 0)
|
||||
{
|
||||
tor->lastBlockSize = info->totalSize % tor->blockSize;
|
||||
}
|
||||
|
||||
if (tor->lastBlockSize == 0)
|
||||
{
|
||||
tor->lastBlockSize = tor->blockSize;
|
||||
}
|
||||
|
||||
tor->blockCount = tor->blockSize != 0 ? (info->totalSize + tor->blockSize - 1) / tor->blockSize : 0;
|
||||
tor->blockCountInPiece = tor->blockSize != 0 ? info->pieceSize / tor->blockSize : 0;
|
||||
tor->blockCountInLastPiece = tor->blockSize != 0 ? (tor->lastPieceSize + tor->blockSize - 1) / tor->blockSize : 0;
|
||||
|
||||
#ifdef TR_ENABLE_ASSERTS
|
||||
/* check our work */
|
||||
if (tor->blockSize != 0)
|
||||
{
|
||||
TR_ASSERT(info->pieceSize % tor->blockSize == 0);
|
||||
}
|
||||
|
||||
uint64_t t = info->pieceCount - 1;
|
||||
t *= info->pieceSize;
|
||||
t += tor->lastPieceSize;
|
||||
TR_ASSERT(t == info->totalSize);
|
||||
|
||||
t = tor->blockCount - 1;
|
||||
t *= tor->blockSize;
|
||||
t += tor->lastBlockSize;
|
||||
TR_ASSERT(t == info->totalSize);
|
||||
|
||||
t = info->pieceCount - 1;
|
||||
t *= tor->blockCountInPiece;
|
||||
t += tor->blockCountInLastPiece;
|
||||
TR_ASSERT(t == (uint64_t)tor->blockCount);
|
||||
#endif
|
||||
|
||||
tor->initSizes(tor->info.totalSize, tor->info.pieceSize);
|
||||
tr_cpConstruct(&tor->completion, tor);
|
||||
|
||||
tr_torrentInitFilePieces(tor);
|
||||
}
|
||||
|
||||
|
@ -836,6 +783,8 @@ static void callScriptIfEnabled(tr_torrent const* tor, TrScript type)
|
|||
}
|
||||
}
|
||||
|
||||
static void refreshCurrentDir(tr_torrent* tor);
|
||||
|
||||
static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
||||
{
|
||||
auto const lock = tor->unique_lock();
|
||||
|
@ -1374,21 +1323,21 @@ static uint64_t countFileBytesCompleted(tr_torrent const* tor, tr_file_index_t i
|
|||
// the first block
|
||||
if (tr_torrentBlockIsComplete(tor, first))
|
||||
{
|
||||
total += tor->blockSize - f.offset % tor->blockSize;
|
||||
total += tor->block_size - f.offset % tor->block_size;
|
||||
}
|
||||
|
||||
// the middle blocks
|
||||
if (first + 1 < last)
|
||||
{
|
||||
uint64_t u = tor->completion.blockBitfield->count(first + 1, last);
|
||||
u *= tor->blockSize;
|
||||
u *= tor->block_size;
|
||||
total += u;
|
||||
}
|
||||
|
||||
// the last block
|
||||
if (tr_torrentBlockIsComplete(tor, last))
|
||||
{
|
||||
total += f.offset + f.length - (uint64_t)tor->blockSize * last;
|
||||
total += f.offset + f.length - (uint64_t)tor->block_size * last;
|
||||
}
|
||||
|
||||
return total;
|
||||
|
@ -2372,33 +2321,12 @@ void tr_torrentGetBlockLocation(
|
|||
uint32_t* length)
|
||||
{
|
||||
uint64_t pos = block;
|
||||
pos *= tor->blockSize;
|
||||
pos *= tor->block_size;
|
||||
*piece = pos / tor->info.pieceSize;
|
||||
uint64_t piece_begin = tor->info.pieceSize;
|
||||
piece_begin *= *piece;
|
||||
*offset = pos - piece_begin;
|
||||
*length = tr_torBlockCountBytes(tor, block);
|
||||
}
|
||||
|
||||
tr_block_index_t _tr_block(tr_torrent const* tor, tr_piece_index_t index, uint32_t offset)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
tr_block_index_t ret = 0;
|
||||
|
||||
if (tor->blockSize > 0)
|
||||
{
|
||||
ret = index;
|
||||
ret *= tor->info.pieceSize / tor->blockSize;
|
||||
ret += offset / tor->blockSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_logAddTorErr(tor, "Cannot calculate block number when blockSize is zero");
|
||||
TR_ASSERT(tor->blockSize > 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
*length = tor->countBytesInBlock(block);
|
||||
}
|
||||
|
||||
bool tr_torrentReqIsValid(tr_torrent const* tor, tr_piece_index_t index, uint32_t offset, uint32_t length)
|
||||
|
@ -2415,7 +2343,7 @@ bool tr_torrentReqIsValid(tr_torrent const* tor, tr_piece_index_t index, uint32_
|
|||
{
|
||||
err = 2;
|
||||
}
|
||||
else if (offset + length > tr_torPieceCountBytes(tor, index))
|
||||
else if (offset + length > tor->countBytesInPiece(index))
|
||||
{
|
||||
err = 3;
|
||||
}
|
||||
|
@ -2459,25 +2387,14 @@ tr_block_range_t tr_torGetFileBlockRange(tr_torrent const* tor, tr_file_index_t
|
|||
tr_file const* f = &tor->info.files[file];
|
||||
|
||||
uint64_t offset = f->offset;
|
||||
tr_block_index_t const first = offset / tor->blockSize;
|
||||
tr_block_index_t const first = offset / tor->block_size;
|
||||
if (f->length == 0)
|
||||
{
|
||||
return { first, first };
|
||||
}
|
||||
|
||||
offset += f->length - 1;
|
||||
tr_block_index_t const last = offset / tor->blockSize;
|
||||
return { first, last };
|
||||
}
|
||||
|
||||
tr_block_range_t tr_torGetPieceBlockRange(tr_torrent const* tor, tr_piece_index_t const piece)
|
||||
{
|
||||
uint64_t offset = tor->info.pieceSize;
|
||||
offset *= piece;
|
||||
tr_block_index_t const first = offset / tor->blockSize;
|
||||
offset += tr_torPieceCountBytes(tor, piece) - 1;
|
||||
tr_block_index_t const last = offset / tor->blockSize;
|
||||
|
||||
tr_block_index_t const last = offset / tor->block_size;
|
||||
return { first, last };
|
||||
}
|
||||
|
||||
|
@ -3159,7 +3076,7 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
|
|||
tr_cpBlockAdd(&tor->completion, block);
|
||||
tr_torrentSetDirty(tor);
|
||||
|
||||
tr_piece_index_t const p = tr_torBlockPiece(tor, block);
|
||||
tr_piece_index_t const p = tor->pieceForBlock(block);
|
||||
|
||||
if (tr_torrentPieceIsComplete(tor, p))
|
||||
{
|
||||
|
@ -3169,7 +3086,7 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t const n = tr_torPieceCountBytes(tor, p);
|
||||
uint32_t const n = tor->countBytesInPiece(p);
|
||||
tr_logAddTorErr(tor, _("Piece %" PRIu32 ", which was just downloaded, failed its checksum test"), p);
|
||||
tor->corruptCur += n;
|
||||
tor->downloadedCur -= std::min(tor->downloadedCur, uint64_t{ n });
|
||||
|
@ -3179,7 +3096,7 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t const n = tr_torBlockCountBytes(tor, block);
|
||||
uint32_t const n = tor->countBytesInBlock(block);
|
||||
tor->downloadedCur -= std::min(tor->downloadedCur, uint64_t{ n });
|
||||
tr_logAddTorDbg(tor, "we have this block already...");
|
||||
}
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "transmission.h"
|
||||
|
||||
#include "bandwidth.h"
|
||||
#include "bitfield.h"
|
||||
#include "block-info.h"
|
||||
#include "completion.h"
|
||||
#include "file.h"
|
||||
#include "quark.h"
|
||||
|
@ -76,10 +79,6 @@ tr_torrent* tr_torrentFindFromObfuscatedHash(tr_session* session, uint8_t const*
|
|||
|
||||
bool tr_torrentIsPieceTransferAllowed(tr_torrent const* torrent, tr_direction direction);
|
||||
|
||||
#define tr_block(a, b) _tr_block(tor, a, b)
|
||||
|
||||
tr_block_index_t _tr_block(tr_torrent const* tor, tr_piece_index_t index, uint32_t offset);
|
||||
|
||||
bool tr_torrentReqIsValid(tr_torrent const* tor, tr_piece_index_t index, uint32_t offset, uint32_t length);
|
||||
|
||||
uint64_t tr_pieceOffset(tr_torrent const* tor, tr_piece_index_t index, uint32_t offset, uint32_t length);
|
||||
|
@ -93,8 +92,6 @@ void tr_torrentGetBlockLocation(
|
|||
|
||||
tr_block_range_t tr_torGetFileBlockRange(tr_torrent const* tor, tr_file_index_t const file);
|
||||
|
||||
tr_block_range_t tr_torGetPieceBlockRange(tr_torrent const* tor, tr_piece_index_t const piece);
|
||||
|
||||
void tr_torrentInitFilePriority(tr_torrent* tor, tr_file_index_t fileIndex, tr_priority_t priority);
|
||||
|
||||
void tr_torrentCheckSeedLimit(tr_torrent* tor);
|
||||
|
@ -128,7 +125,7 @@ tr_torrent_activity tr_torrentGetActivity(tr_torrent const* tor);
|
|||
struct tr_incomplete_metadata;
|
||||
|
||||
/** @brief Torrent object */
|
||||
struct tr_torrent
|
||||
struct tr_torrent : public tr_block_info
|
||||
{
|
||||
public:
|
||||
void setLocation(
|
||||
|
@ -320,16 +317,6 @@ public:
|
|||
* This pointer will be equal to downloadDir or incompleteDir */
|
||||
char const* currentDir;
|
||||
|
||||
/* How many bytes we ask for per request */
|
||||
uint32_t blockSize;
|
||||
tr_block_index_t blockCount;
|
||||
|
||||
uint32_t lastBlockSize;
|
||||
uint32_t lastPieceSize;
|
||||
|
||||
uint32_t blockCountInPiece;
|
||||
uint32_t blockCountInLastPiece;
|
||||
|
||||
struct tr_completion completion;
|
||||
|
||||
tr_completeness completeness;
|
||||
|
@ -428,24 +415,6 @@ private:
|
|||
mutable std::vector<tr_sha1_digest_t> piece_checksums_;
|
||||
};
|
||||
|
||||
/* what piece index is this block in? */
|
||||
constexpr tr_piece_index_t tr_torBlockPiece(tr_torrent const* tor, tr_block_index_t const block)
|
||||
{
|
||||
return block / tor->blockCountInPiece;
|
||||
}
|
||||
|
||||
/* how many bytes are in this piece? */
|
||||
constexpr uint32_t tr_torPieceCountBytes(tr_torrent const* tor, tr_piece_index_t const piece)
|
||||
{
|
||||
return piece + 1 == tor->info.pieceCount ? tor->lastPieceSize : tor->info.pieceSize;
|
||||
}
|
||||
|
||||
/* how many bytes are in this block? */
|
||||
constexpr uint32_t tr_torBlockCountBytes(tr_torrent const* tor, tr_block_index_t const block)
|
||||
{
|
||||
return block + 1 == tor->blockCount ? tor->lastBlockSize : tor->blockSize;
|
||||
}
|
||||
|
||||
static inline bool tr_torrentExists(tr_session const* session, uint8_t const* torrentHash)
|
||||
{
|
||||
return tr_torrentFindFromHash((tr_session*)session, torrentHash) != nullptr;
|
||||
|
|
|
@ -70,7 +70,7 @@ static bool verifyTorrent(tr_torrent* tor, bool* stopFlag)
|
|||
}
|
||||
|
||||
/* figure out how much we can read this pass */
|
||||
uint64_t leftInPiece = tr_torPieceCountBytes(tor, pieceIndex) - piecePos;
|
||||
uint64_t leftInPiece = tor->countBytesInPiece(pieceIndex) - piecePos;
|
||||
uint64_t leftInFile = file->length - filePos;
|
||||
uint64_t bytesThisPass = std::min(leftInFile, leftInPiece);
|
||||
bytesThisPass = std::min(bytesThisPass, uint64_t{ buflen });
|
||||
|
|
|
@ -147,7 +147,7 @@ static void fire_client_got_rejs(tr_torrent* tor, tr_webseed* w, tr_block_index_
|
|||
{
|
||||
if (i == count)
|
||||
{
|
||||
e.length = tr_torBlockCountBytes(tor, block + count - 1);
|
||||
e.length = tor->countBytesInBlock(block + count - 1);
|
||||
}
|
||||
|
||||
publish(w, &e);
|
||||
|
@ -165,7 +165,7 @@ static void fire_client_got_blocks(tr_torrent* tor, tr_webseed* w, tr_block_inde
|
|||
{
|
||||
if (i == count)
|
||||
{
|
||||
e.length = tr_torBlockCountBytes(tor, block + count - 1);
|
||||
e.length = tor->countBytesInBlock(block + count - 1);
|
||||
}
|
||||
|
||||
publish(w, &e);
|
||||
|
@ -206,7 +206,7 @@ static void write_block_func(void* vdata)
|
|||
auto* const tor = tr_torrentFindFromId(data->session, data->torrent_id);
|
||||
if (tor != nullptr)
|
||||
{
|
||||
uint32_t const block_size = tor->blockSize;
|
||||
uint32_t const block_size = tor->block_size;
|
||||
uint32_t len = evbuffer_get_length(buf);
|
||||
uint32_t const offset_end = data->block_offset + len;
|
||||
tr_cache* cache = data->session->cache;
|
||||
|
@ -371,12 +371,12 @@ static void on_idle(tr_webseed* w)
|
|||
task->session = tor->session;
|
||||
task->webseed = w;
|
||||
task->block = first;
|
||||
task->piece_index = tr_torBlockPiece(tor, first);
|
||||
task->piece_offset = tor->blockSize * first - tor->info.pieceSize * task->piece_index;
|
||||
task->length = (last - first) * tor->blockSize + tr_torBlockCountBytes(tor, last);
|
||||
task->piece_index = tor->pieceForBlock(first);
|
||||
task->piece_offset = tor->block_size * first - tor->info.pieceSize * task->piece_index;
|
||||
task->length = (last - first) * tor->block_size + tor->countBytesInBlock(last);
|
||||
task->blocks_done = 0;
|
||||
task->response_code = 0;
|
||||
task->block_size = tor->blockSize;
|
||||
task->block_size = tor->block_size;
|
||||
task->content = evbuffer_new();
|
||||
evbuffer_add_cb(task->content, on_content_changed, task);
|
||||
w->tasks.insert(task);
|
||||
|
@ -425,7 +425,7 @@ static void web_response_func(
|
|||
|
||||
if (!success)
|
||||
{
|
||||
tr_block_index_t const blocks_remain = (t->length + tor->blockSize - 1) / tor->blockSize - t->blocks_done;
|
||||
tr_block_index_t const blocks_remain = (t->length + tor->block_size - 1) / tor->block_size - t->blocks_done;
|
||||
|
||||
if (blocks_remain != 0)
|
||||
{
|
||||
|
@ -448,7 +448,7 @@ static void web_response_func(
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t const bytes_done = t->blocks_done * tor->blockSize;
|
||||
uint32_t const bytes_done = t->blocks_done * tor->block_size;
|
||||
uint32_t const buf_len = evbuffer_get_length(t->content);
|
||||
|
||||
if (bytes_done + buf_len < t->length)
|
||||
|
@ -508,7 +508,7 @@ static void task_request_next_chunk(struct tr_webseed_task* t)
|
|||
auto& urls = t->webseed->file_urls;
|
||||
|
||||
tr_info const* inf = tr_torrentInfo(tor);
|
||||
uint64_t const remain = t->length - t->blocks_done * tor->blockSize - evbuffer_get_length(t->content);
|
||||
uint64_t const remain = t->length - t->blocks_done * tor->block_size - evbuffer_get_length(t->content);
|
||||
|
||||
uint64_t const total_offset = tr_pieceOffset(tor, t->piece_index, t->piece_offset, t->length - remain);
|
||||
tr_piece_index_t const step_piece = total_offset / inf->pieceSize;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
add_executable(libtransmission-test
|
||||
bitfield-test.cc
|
||||
block-info-test.cc
|
||||
blocklist-test.cc
|
||||
clients-test.cc
|
||||
copy-test.cc
|
||||
|
@ -14,9 +15,9 @@ add_executable(libtransmission-test
|
|||
makemeta-test.cc
|
||||
metainfo-test.cc
|
||||
move-test.cc
|
||||
peer-msgs-test.cc
|
||||
peer-mgr-wishlist-test.cc
|
||||
peer-mgr-active-requests-test.cc
|
||||
peer-mgr-wishlist-test.cc
|
||||
peer-msgs-test.cc
|
||||
quark-test.cc
|
||||
rename-test.cc
|
||||
rpc-test.cc
|
||||
|
|
150
tests/libtransmission/block-info-test.cc
Normal file
150
tests/libtransmission/block-info-test.cc
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* This file Copyright (C) Mnemosyne LLC
|
||||
*
|
||||
* It may be used under the GNU GPL versions 2 or 3
|
||||
* or any future license endorsed by Mnemosyne LLC.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "transmission.h"
|
||||
|
||||
#include "block-info.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using BlockInfoTest = ::testing::Test;
|
||||
|
||||
TEST_F(BlockInfoTest, fieldsAreSet)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
||||
uint64_t constexpr ExpectedBlockSize = 1024 * 16;
|
||||
uint64_t constexpr ExpectedBlocksPerPiece = 4;
|
||||
uint64_t constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
uint64_t constexpr PieceCount = 4;
|
||||
uint64_t constexpr TotalSize = PieceSize * PieceCount;
|
||||
info.initSizes(TotalSize, PieceSize);
|
||||
|
||||
EXPECT_EQ(ExpectedBlockSize, info.block_size);
|
||||
EXPECT_EQ(ExpectedBlockSize, info.final_block_size);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece, info.n_blocks_in_final_piece);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece, info.n_blocks_in_piece);
|
||||
EXPECT_EQ(PieceCount, info.n_pieces);
|
||||
EXPECT_EQ(PieceSize, info.final_piece_size);
|
||||
EXPECT_EQ(PieceSize, info.piece_size);
|
||||
EXPECT_EQ(TotalSize, info.total_size);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, handlesOddSize)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
||||
uint64_t constexpr ExpectedBlockSize = 1024 * 16;
|
||||
uint64_t constexpr ExpectedBlocksPerPiece = 4;
|
||||
uint64_t constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
uint64_t constexpr PieceCount = 5;
|
||||
uint64_t constexpr TotalSize = PieceSize * (PieceCount - 1) + 1;
|
||||
info.initSizes(TotalSize, PieceSize);
|
||||
|
||||
EXPECT_EQ(1, info.final_block_size);
|
||||
EXPECT_EQ(1, info.final_piece_size);
|
||||
EXPECT_EQ(1, info.n_blocks_in_final_piece);
|
||||
EXPECT_EQ(ExpectedBlockSize, info.block_size);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece, info.n_blocks_in_piece);
|
||||
EXPECT_EQ(PieceCount, info.n_pieces);
|
||||
EXPECT_EQ(PieceSize, info.piece_size);
|
||||
EXPECT_EQ(TotalSize, info.total_size);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, pieceForBlock)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
||||
uint64_t constexpr ExpectedBlockSize = 1024 * 16;
|
||||
uint64_t constexpr ExpectedBlocksPerPiece = 4;
|
||||
uint64_t constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
uint64_t constexpr PieceCount = 4;
|
||||
uint64_t constexpr TotalSize = PieceSize * PieceCount;
|
||||
info.initSizes(TotalSize, PieceSize);
|
||||
|
||||
for (uint64_t i = 0; i < info.n_blocks; ++i)
|
||||
{
|
||||
EXPECT_EQ((i * ExpectedBlockSize) / PieceSize, info.pieceForBlock(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, countBytesInPiece)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
||||
uint64_t constexpr ExpectedBlockSize = 1024 * 16;
|
||||
uint64_t constexpr ExpectedBlocksPerPiece = 4;
|
||||
uint64_t constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
uint64_t constexpr PieceCount = 5;
|
||||
uint64_t constexpr TotalSize = PieceSize * (PieceCount - 1) + 1;
|
||||
info.initSizes(TotalSize, PieceSize);
|
||||
|
||||
EXPECT_EQ(PieceSize, info.countBytesInPiece(info.n_pieces - 2));
|
||||
EXPECT_EQ(1, info.countBytesInPiece(info.n_pieces - 1));
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, countBytesInBlock)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
||||
uint64_t constexpr ExpectedBlockSize = 1024 * 16;
|
||||
uint64_t constexpr ExpectedBlocksPerPiece = 4;
|
||||
uint64_t constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
uint64_t constexpr PieceCount = 5;
|
||||
uint64_t constexpr TotalSize = PieceSize * (PieceCount - 1) + 1;
|
||||
info.initSizes(TotalSize, PieceSize);
|
||||
|
||||
EXPECT_EQ(ExpectedBlockSize, info.countBytesInBlock(info.n_blocks - 2));
|
||||
EXPECT_EQ(1, info.countBytesInBlock(info.n_blocks - 1));
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, offset)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
||||
uint64_t constexpr ExpectedBlockSize = 1024 * 16;
|
||||
uint64_t constexpr ExpectedBlocksPerPiece = 4;
|
||||
uint64_t constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
uint64_t constexpr PieceCount = 5;
|
||||
uint64_t constexpr TotalSize = PieceSize * (PieceCount - 1) + 1;
|
||||
info.initSizes(TotalSize, PieceSize);
|
||||
|
||||
EXPECT_EQ(0, info.offset(0, 0));
|
||||
EXPECT_EQ(1, info.offset(0, 0, 1));
|
||||
EXPECT_EQ(PieceSize * 2 + 100 + 1, info.offset(2, 100, 1));
|
||||
EXPECT_EQ(
|
||||
info.total_size - 1,
|
||||
info.offset(
|
||||
info.n_pieces - 1,
|
||||
((info.n_blocks_in_final_piece - 1) * info.block_size) + info.n_blocks_in_final_piece - 1));
|
||||
EXPECT_EQ(info.n_blocks_in_piece, info.blockOf(info.offset(1, 0)));
|
||||
EXPECT_EQ(info.n_blocks_in_piece, info.blockOf(info.offset(1, info.block_size - 1)));
|
||||
EXPECT_EQ(info.n_blocks_in_piece + 1, info.blockOf(info.offset(1, info.block_size)));
|
||||
EXPECT_EQ(info.n_blocks - 1, info.blockOf(info.total_size - 1));
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, blockRangeForPiece)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
||||
uint64_t constexpr ExpectedBlockSize = 1024 * 16;
|
||||
uint64_t constexpr ExpectedBlocksPerPiece = 4;
|
||||
uint64_t constexpr PieceSize = ExpectedBlockSize * ExpectedBlocksPerPiece;
|
||||
uint64_t constexpr PieceCount = 5;
|
||||
uint64_t constexpr TotalSize = PieceSize * (PieceCount - 1) + 1;
|
||||
info.initSizes(TotalSize, PieceSize);
|
||||
|
||||
EXPECT_EQ(0, info.blockRangeForPiece(0).first);
|
||||
EXPECT_EQ(3, info.blockRangeForPiece(0).last);
|
||||
EXPECT_EQ(12, info.blockRangeForPiece(3).first);
|
||||
EXPECT_EQ(15, info.blockRangeForPiece(3).last);
|
||||
EXPECT_EQ(16, info.blockRangeForPiece(4).first);
|
||||
EXPECT_EQ(16, info.blockRangeForPiece(4).last);
|
||||
}
|
|
@ -80,28 +80,28 @@ TEST_P(IncompleteDirTest, incompleteDir)
|
|||
auto const test_incomplete_dir_threadfunc = [](void* vdata) noexcept
|
||||
{
|
||||
auto* data = static_cast<TestIncompleteDirData*>(vdata);
|
||||
tr_cacheWriteBlock(data->session->cache, data->tor, 0, data->offset, data->tor->blockSize, data->buf);
|
||||
tr_cacheWriteBlock(data->session->cache, data->tor, 0, data->offset, data->tor->block_size, data->buf);
|
||||
tr_torrentGotBlock(data->tor, data->block);
|
||||
data->done = true;
|
||||
};
|
||||
|
||||
// now finish writing it
|
||||
{
|
||||
char* zero_block = tr_new0(char, tor->blockSize);
|
||||
char* zero_block = tr_new0(char, tor->block_size);
|
||||
|
||||
struct TestIncompleteDirData data = {};
|
||||
data.session = session_;
|
||||
data.tor = tor;
|
||||
data.buf = evbuffer_new();
|
||||
|
||||
auto const [first, last] = tr_torGetPieceBlockRange(tor, data.pieceIndex);
|
||||
auto const [first, last] = tor->blockRangeForPiece(data.pieceIndex);
|
||||
|
||||
for (tr_block_index_t block_index = first; block_index <= last; ++block_index)
|
||||
{
|
||||
evbuffer_add(data.buf, zero_block, tor->blockSize);
|
||||
evbuffer_add(data.buf, zero_block, tor->block_size);
|
||||
data.block = block_index;
|
||||
data.done = false;
|
||||
data.offset = data.block * tor->blockSize;
|
||||
data.offset = data.block * tor->block_size;
|
||||
tr_runInEventThread(session_, test_incomplete_dir_threadfunc, &data);
|
||||
|
||||
auto const test = [&data]()
|
||||
|
|
Loading…
Add table
Reference in a new issue