refactor: tr_block_info class (#2210)

* refactor: add tr_block_info with tests
This commit is contained in:
Charles Kerr
2021-11-24 08:48:52 -06:00
committed by GitHub
parent 449b83e340
commit 843e486d2a
17 changed files with 442 additions and 216 deletions

View File

@@ -49,6 +49,7 @@
558699542570759E00F77A43 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55869925257074EC00F77A43 /* libcurl.tbd */; }; 558699542570759E00F77A43 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55869925257074EC00F77A43 /* libcurl.tbd */; };
558699602570759F00F77A43 /* 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 */; }; 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 */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072D0486CEB800E47090 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; settings = {ATTRIBUTES = (); }; }; 8D11072D0486CEB800E47090 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 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 */; }; 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 */; }; 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 */; }; 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 */; }; F63480631E1D7274005B9E09 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F63480621E1D7274005B9E09 /* Images.xcassets */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -518,10 +520,6 @@
4D36BA660CA2F00800A63CA5 /* peer-io.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "peer-io.h"; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; F63480621E1D7274005B9E09 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Images/Images.xcassets; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -1374,6 +1378,8 @@
4D1838DC09DEC04A0047D688 /* libtransmission */ = { 4D1838DC09DEC04A0047D688 /* libtransmission */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A54D44C6A7AAF131D9AE29F5 /* block-info.cc */,
6A044CBD8C049AFCBD4DB411 /* block-info.h */,
C17740D3273A002C00E455D2 /* web-utils.cc */, C17740D3273A002C00E455D2 /* web-utils.cc */,
C17740D4273A002C00E455D2 /* web-utils.h */, C17740D4273A002C00E455D2 /* web-utils.h */,
CAB35C62252F6F5E00552A55 /* mime-types.h */, CAB35C62252F6F5E00552A55 /* mime-types.h */,
@@ -1898,6 +1904,7 @@
A2EA52321686AC0D00180493 /* quark.h in Headers */, A2EA52321686AC0D00180493 /* quark.h in Headers */,
A2AF23C916B44FA0003BC59E /* log.h in Headers */, A2AF23C916B44FA0003BC59E /* log.h in Headers */,
A23FAE55178BC2950053DC5B /* platform-quota.h in Headers */, A23FAE55178BC2950053DC5B /* platform-quota.h in Headers */,
F11545ACA7C4D7A464F703AB /* block-info.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -2493,6 +2500,7 @@
A2EA52311686AC0D00180493 /* quark.cc in Sources */, A2EA52311686AC0D00180493 /* quark.cc in Sources */,
A2AF23C816B44FA0003BC59E /* log.cc in Sources */, A2AF23C816B44FA0003BC59E /* log.cc in Sources */,
A23FAE54178BC2950053DC5B /* platform-quota.cc in Sources */, A23FAE54178BC2950053DC5B /* platform-quota.cc in Sources */,
62F644738FE3D8788EBF73A9 /* block-info.cc in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@@ -6,27 +6,28 @@ configure_file(
) )
set(PROJECT_FILES set(PROJECT_FILES
announcer.cc
announcer-http.cc announcer-http.cc
announcer-udp.cc announcer-udp.cc
announcer.cc
bandwidth.cc bandwidth.cc
bitfield.cc bitfield.cc
block-info.cc
blocklist.cc blocklist.cc
cache.cc cache.cc
clients.cc clients.cc
completion.cc completion.cc
crypto.cc
crypto-utils.cc
crypto-utils-ccrypto.cc crypto-utils-ccrypto.cc
crypto-utils-cyassl.cc crypto-utils-cyassl.cc
crypto-utils-fallback.cc crypto-utils-fallback.cc
crypto-utils-openssl.cc crypto-utils-openssl.cc
crypto-utils-polarssl.cc crypto-utils-polarssl.cc
crypto-utils.cc
crypto.cc
error.cc error.cc
fdlimit.cc fdlimit.cc
file.cc
file-posix.cc file-posix.cc
file-win32.cc file-win32.cc
file.cc
handshake.cc handshake.cc
inout.cc inout.cc
log.cc log.cc
@@ -36,46 +37,46 @@ set(PROJECT_FILES
natpmp.cc natpmp.cc
net.cc net.cc
peer-io.cc peer-io.cc
peer-mgr.cc
peer-mgr-active-requests.cc peer-mgr-active-requests.cc
peer-mgr-wishlist.cc peer-mgr-wishlist.cc
peer-mgr.cc
peer-msgs.cc peer-msgs.cc
platform.cc
platform-quota.cc platform-quota.cc
platform.cc
port-forwarding.cc port-forwarding.cc
ptrarray.cc ptrarray.cc
quark.cc quark.cc
resume.cc resume.cc
rpcimpl.cc
rpc-server.cc rpc-server.cc
session.cc rpcimpl.cc
session-id.cc session-id.cc
session.cc
stats.cc
subprocess-posix.cc subprocess-posix.cc
subprocess-win32.cc subprocess-win32.cc
stats.cc
torrent.cc
torrent-ctor.cc torrent-ctor.cc
torrent-magnet.cc torrent-magnet.cc
tr-dht.cc torrent.cc
trevent.cc
tr-assert.cc tr-assert.cc
tr-dht.cc
tr-getopt.cc tr-getopt.cc
tr-lpd.cc tr-lpd.cc
tr-udp.cc tr-udp.cc
tr-utp.cc tr-utp.cc
trevent.cc
upnp.cc upnp.cc
utils.cc utils.cc
variant-benc.cc variant-benc.cc
variant.cc
variant-json.cc variant-json.cc
variant.cc
verify.cc verify.cc
watchdir.cc
watchdir-generic.cc watchdir-generic.cc
watchdir-inotify.cc watchdir-inotify.cc
watchdir-kqueue.cc watchdir-kqueue.cc
watchdir-win32.cc watchdir-win32.cc
web.cc watchdir.cc
web-utils.cc web-utils.cc
web.cc
webseed.cc webseed.cc
) )
@@ -147,6 +148,7 @@ set(${PROJECT_NAME}_PRIVATE_HEADERS
announcer.h announcer.h
bandwidth.h bandwidth.h
bitfield.h bitfield.h
block-info.h
blocklist.h blocklist.h
cache.h cache.h
clients.h clients.h
@@ -164,9 +166,9 @@ set(${PROJECT_NAME}_PRIVATE_HEADERS
net.h net.h
peer-common.h peer-common.h
peer-io.h peer-io.h
peer-mgr.h
peer-mgr-active-requests.h peer-mgr-active-requests.h
peer-mgr-wishlist.h peer-mgr-wishlist.h
peer-mgr.h
peer-msgs.h peer-msgs.h
peer-socket.h peer-socket.h
platform-quota.h platform-quota.h

View 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
}

View 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);
};

View File

@@ -309,7 +309,7 @@ static struct cache_block* findBlock(tr_cache* cache, tr_torrent* torrent, tr_pi
{ {
struct cache_block key; struct cache_block key;
key.tor = torrent; 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)); 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->piece = piece;
cb->offset = offset; cb->offset = offset;
cb->length = length; cb->length = length;
cb->block = _tr_block(torrent, piece, offset); cb->block = torrent->blockOf(piece, offset);
cb->evbuf = evbuffer_new(); cb->evbuf = evbuffer_new();
tr_ptrArrayInsertSorted(&cache->blocks, cb, cache_block_compare); tr_ptrArrayInsertSorted(&cache->blocks, cb, cache_block_compare);
} }

View File

@@ -29,7 +29,7 @@ static void tr_cpReset(tr_completion* cp)
void tr_cpConstruct(tr_completion* cp, tr_torrent* tor) void tr_cpConstruct(tr_completion* cp, tr_torrent* tor)
{ {
cp->tor = tor; cp->tor = tor;
cp->blockBitfield = new tr_bitfield(tor->blockCount); cp->blockBitfield = new tr_bitfield(tor->n_blocks);
tr_cpReset(cp); tr_cpReset(cp);
} }
@@ -42,12 +42,12 @@ void tr_cpBlockInit(tr_completion* cp, tr_bitfield const& b)
// set sizeNow // set sizeNow
cp->sizeNow = cp->blockBitfield->count(); cp->sizeNow = cp->blockBitfield->count();
TR_ASSERT(cp->sizeNow <= cp->tor->blockCount); TR_ASSERT(cp->sizeNow <= cp->tor->n_blocks);
cp->sizeNow *= cp->tor->blockSize; 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); 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) void tr_cpPieceRem(tr_completion* cp, tr_piece_index_t piece)
{ {
tr_torrent const* tor = cp->tor; tr_torrent const* tor = cp->tor;
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) 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) 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) for (tr_block_index_t i = first; i <= last; ++i)
{ {
tr_cpBlockAdd(cp, 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)) 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->blockBitfield->set(block);
cp->sizeNow += tr_torBlockCountBytes(tor, block); cp->sizeNow += tor->countBytesInBlock(block);
cp->haveValidIsDirty = true; cp->haveValidIsDirty = true;
cp->sizeWhenDoneIsDirty = cp->sizeWhenDoneIsDirty || tor->pieceIsDnd(piece); cp->sizeWhenDoneIsDirty = cp->sizeWhenDoneIsDirty || tor->pieceIsDnd(piece);
@@ -136,7 +136,7 @@ uint64_t tr_cpHaveValid(tr_completion const* ccp)
{ {
if (tr_cpPieceIsComplete(ccp, i)) 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) for (tr_piece_index_t p = 0; p < inf->pieceCount; ++p)
{ {
uint64_t n = 0; uint64_t n = 0;
uint64_t const pieceSize = tr_torPieceCountBytes(tor, p); uint64_t const pieceSize = tor->countBytesInPiece(p);
if (!tor->pieceIsDnd(p)) if (!tor->pieceIsDnd(p))
{ {
@@ -173,18 +173,17 @@ uint64_t tr_cpSizeWhenDone(tr_completion const* ccp)
} }
else 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->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; size += n;
} }
} }
@@ -222,7 +221,7 @@ void tr_cpGetAmountDone(tr_completion const* cp, float* tab, int tabCount)
else else
{ {
tr_piece_index_t const piece = (tr_piece_index_t)i * interval; 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); 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; 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); 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; return 0;
} }
size_t const pieceByteSize = tr_torPieceCountBytes(cp->tor, piece); size_t const pieceByteSize = cp->tor->countBytesInPiece(piece);
auto const [first, last] = tr_torGetPieceBlockRange(cp->tor, piece); auto const [first, last] = cp->tor->blockRangeForPiece(piece);
auto haveBytes = size_t{}; auto haveBytes = size_t{};
if (first != last) 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 It's faster to handle the last block separately because its size
needs to be checked separately. */ needs to be checked separately. */
haveBytes = cp->blockBitfield->count(first, last); haveBytes = cp->blockBitfield->count(first, last);
haveBytes *= cp->tor->blockSize; haveBytes *= cp->tor->block_size;
} }
if (cp->blockBitfield->test(last)) /* handle the last block */ if (cp->blockBitfield->test(last)) /* handle the last block */
{ {
haveBytes += tr_torBlockCountBytes(cp->tor, last); haveBytes += cp->tor->countBytesInBlock(last);
} }
TR_ASSERT(haveBytes <= pieceByteSize); TR_ASSERT(haveBytes <= pieceByteSize);

View File

@@ -260,12 +260,12 @@ static std::optional<tr_sha1_digest_t> recalculateHash(tr_torrent* tor, tr_piece
TR_ASSERT(tor != nullptr); TR_ASSERT(tor != nullptr);
TR_ASSERT(piece < tor->info.pieceCount); 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{}; auto offset = uint32_t{};
tr_ioPrefetch(tor, piece, offset, bytes_left); tr_ioPrefetch(tor, piece, offset, bytes_left);
auto sha = tr_sha1_init(); 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) while (bytes_left != 0)
{ {
size_t const len = std::min(bytes_left, std::size(buffer)); size_t const len = std::min(bytes_left, std::size(buffer));

View File

@@ -225,7 +225,7 @@ tr_peer::tr_peer(tr_torrent const* tor, peer_atom* atom_in)
: session{ tor->session } : session{ tor->session }
, atom{ atom_in } , atom{ atom_in }
, swarm{ tor->swarm } , swarm{ tor->swarm }
, blame{ tor->blockCount } , blame{ tor->n_blocks }
, have{ tor->info.pieceCount } , 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 consider ourselves to be in endgame if the number of bytes
we've got requested is >= the number of bytes left to download */ 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) 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 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 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 */ /* request the blocks that we don't have in this piece */
{ {
tr_torrent const* tor = t->tor; 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) for (tr_block_index_t b = first; b <= last; ++b)
{ {
if (tr_torrentBlockIsComplete(tor, b)) if (tr_torrentBlockIsComplete(tor, b))
{ {
uint32_t const offset = getBlockOffsetInPiece(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); tr_peerMsgsAddRequest(peer->msgs, pieceIndex, offset, length);
incrementPieceRequests(t, pieceIndex); 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 */ 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 */ /* bookkeeping */
@@ -824,7 +824,7 @@ static void peerCallbackFunc(tr_peer* peer, tr_peer_event const* e, void* vs)
break; break;
case TR_PEER_CLIENT_GOT_REJ: 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; break;
case TR_PEER_CLIENT_GOT_CHOKE: 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_torrent* tor = s->tor;
tr_piece_index_t const p = e->pieceIndex; 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); cancelAllRequestsForBlock(s, block, peer);
peer->blocksSentToClient.add(tr_time(), 1); peer->blocksSentToClient.add(tr_time(), 1);
tr_torrentGotBlock(tor, block); tr_torrentGotBlock(tor, block);
@@ -1243,7 +1243,7 @@ tr_pex* tr_peerMgrCompact6ToPex(
void tr_peerMgrGotBadPiece(tr_torrent* tor, tr_piece_index_t pieceIndex) void tr_peerMgrGotBadPiece(tr_torrent* tor, tr_piece_index_t pieceIndex)
{ {
tr_swarm* s = tor->swarm; 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) for (int i = 0, n = tr_ptrArraySize(&s->peers); i != n; ++i)
{ {

View File

@@ -358,7 +358,7 @@ public:
bool is_reading_block(tr_block_index_t block) const override 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 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_ASSERT(req != nullptr);
tr_torrent* tor = msgs->torrent; 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)) if (!requestIsValid(msgs, req))
{ {
@@ -1893,9 +1893,9 @@ static int clientGotBlock(tr_peerMsgsImpl* msgs, struct evbuffer* data, struct p
return EBADMSG; 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; return EMSGSIZE;
} }
@@ -2027,7 +2027,7 @@ static void updateDesiredRequestCount(tr_peerMsgsImpl* msgs)
* many requests we should send to this peer */ * many requests we should send to this peer */
size_t constexpr Floor = 32; size_t constexpr Floor = 32;
size_t constexpr Seconds = RequestBufSecs; 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; size_t const ceil = msgs->reqq ? *msgs->reqq : 250;
msgs->desired_request_count = std::clamp(estimated_blocks_in_period, Floor, ceil); 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 *** 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; --msgs->prefetchCount;

View File

@@ -615,7 +615,7 @@ static uint64_t loadProgress(tr_variant* dict, tr_torrent* tor)
/// COMPLETION /// COMPLETION
auto blocks = tr_bitfield{ tor->blockCount }; auto blocks = tr_bitfield{ tor->n_blocks };
char const* err = nullptr; char const* err = nullptr;
auto sv = std::string_view{}; auto sv = std::string_view{};
tr_variant const* const b = tr_variantDictFind(prog, TR_KEY_blocks); tr_variant const* const b = tr_variantDictFind(prog, TR_KEY_blocks);

View File

@@ -721,63 +721,10 @@ uint32_t tr_getBlockSize(uint32_t pieceSize)
return b; return b;
} }
static void refreshCurrentDir(tr_torrent* tor);
static void torrentInitFromInfo(tr_torrent* tor) static void torrentInitFromInfo(tr_torrent* tor)
{ {
tr_info const* const info = &tor->info; tor->initSizes(tor->info.totalSize, tor->info.pieceSize);
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
tr_cpConstruct(&tor->completion, tor); tr_cpConstruct(&tor->completion, tor);
tr_torrentInitFilePieces(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) static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
{ {
auto const lock = tor->unique_lock(); 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 // the first block
if (tr_torrentBlockIsComplete(tor, first)) if (tr_torrentBlockIsComplete(tor, first))
{ {
total += tor->blockSize - f.offset % tor->blockSize; total += tor->block_size - f.offset % tor->block_size;
} }
// the middle blocks // the middle blocks
if (first + 1 < last) if (first + 1 < last)
{ {
uint64_t u = tor->completion.blockBitfield->count(first + 1, last); uint64_t u = tor->completion.blockBitfield->count(first + 1, last);
u *= tor->blockSize; u *= tor->block_size;
total += u; total += u;
} }
// the last block // the last block
if (tr_torrentBlockIsComplete(tor, last)) 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; return total;
@@ -2372,33 +2321,12 @@ void tr_torrentGetBlockLocation(
uint32_t* length) uint32_t* length)
{ {
uint64_t pos = block; uint64_t pos = block;
pos *= tor->blockSize; pos *= tor->block_size;
*piece = pos / tor->info.pieceSize; *piece = pos / tor->info.pieceSize;
uint64_t piece_begin = tor->info.pieceSize; uint64_t piece_begin = tor->info.pieceSize;
piece_begin *= *piece; piece_begin *= *piece;
*offset = pos - piece_begin; *offset = pos - piece_begin;
*length = tr_torBlockCountBytes(tor, block); *length = tor->countBytesInBlock(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;
} }
bool tr_torrentReqIsValid(tr_torrent const* tor, tr_piece_index_t index, uint32_t offset, uint32_t length) 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; err = 2;
} }
else if (offset + length > tr_torPieceCountBytes(tor, index)) else if (offset + length > tor->countBytesInPiece(index))
{ {
err = 3; 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]; tr_file const* f = &tor->info.files[file];
uint64_t offset = f->offset; 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) if (f->length == 0)
{ {
return { first, first }; return { first, first };
} }
offset += f->length - 1; offset += f->length - 1;
tr_block_index_t const last = offset / tor->blockSize; tr_block_index_t const last = offset / tor->block_size;
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;
return { first, last }; return { first, last };
} }
@@ -3159,7 +3076,7 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
tr_cpBlockAdd(&tor->completion, block); tr_cpBlockAdd(&tor->completion, block);
tr_torrentSetDirty(tor); 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)) if (tr_torrentPieceIsComplete(tor, p))
{ {
@@ -3169,7 +3086,7 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
} }
else 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); tr_logAddTorErr(tor, _("Piece %" PRIu32 ", which was just downloaded, failed its checksum test"), p);
tor->corruptCur += n; tor->corruptCur += n;
tor->downloadedCur -= std::min(tor->downloadedCur, uint64_t{ 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 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 }); tor->downloadedCur -= std::min(tor->downloadedCur, uint64_t{ n });
tr_logAddTorDbg(tor, "we have this block already..."); tr_logAddTorDbg(tor, "we have this block already...");
} }

View File

@@ -19,8 +19,11 @@
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include "transmission.h"
#include "bandwidth.h" #include "bandwidth.h"
#include "bitfield.h" #include "bitfield.h"
#include "block-info.h"
#include "completion.h" #include "completion.h"
#include "file.h" #include "file.h"
#include "quark.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); 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); 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); 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_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_torrentInitFilePriority(tr_torrent* tor, tr_file_index_t fileIndex, tr_priority_t priority);
void tr_torrentCheckSeedLimit(tr_torrent* tor); void tr_torrentCheckSeedLimit(tr_torrent* tor);
@@ -128,7 +125,7 @@ tr_torrent_activity tr_torrentGetActivity(tr_torrent const* tor);
struct tr_incomplete_metadata; struct tr_incomplete_metadata;
/** @brief Torrent object */ /** @brief Torrent object */
struct tr_torrent struct tr_torrent : public tr_block_info
{ {
public: public:
void setLocation( void setLocation(
@@ -320,16 +317,6 @@ public:
* This pointer will be equal to downloadDir or incompleteDir */ * This pointer will be equal to downloadDir or incompleteDir */
char const* currentDir; 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; struct tr_completion completion;
tr_completeness completeness; tr_completeness completeness;
@@ -428,24 +415,6 @@ private:
mutable std::vector<tr_sha1_digest_t> piece_checksums_; 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) static inline bool tr_torrentExists(tr_session const* session, uint8_t const* torrentHash)
{ {
return tr_torrentFindFromHash((tr_session*)session, torrentHash) != nullptr; return tr_torrentFindFromHash((tr_session*)session, torrentHash) != nullptr;

View File

@@ -70,7 +70,7 @@ static bool verifyTorrent(tr_torrent* tor, bool* stopFlag)
} }
/* figure out how much we can read this pass */ /* 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 leftInFile = file->length - filePos;
uint64_t bytesThisPass = std::min(leftInFile, leftInPiece); uint64_t bytesThisPass = std::min(leftInFile, leftInPiece);
bytesThisPass = std::min(bytesThisPass, uint64_t{ buflen }); bytesThisPass = std::min(bytesThisPass, uint64_t{ buflen });

View File

@@ -147,7 +147,7 @@ static void fire_client_got_rejs(tr_torrent* tor, tr_webseed* w, tr_block_index_
{ {
if (i == count) if (i == count)
{ {
e.length = tr_torBlockCountBytes(tor, block + count - 1); e.length = tor->countBytesInBlock(block + count - 1);
} }
publish(w, &e); 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) if (i == count)
{ {
e.length = tr_torBlockCountBytes(tor, block + count - 1); e.length = tor->countBytesInBlock(block + count - 1);
} }
publish(w, &e); publish(w, &e);
@@ -206,7 +206,7 @@ static void write_block_func(void* vdata)
auto* const tor = tr_torrentFindFromId(data->session, data->torrent_id); auto* const tor = tr_torrentFindFromId(data->session, data->torrent_id);
if (tor != nullptr) 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 len = evbuffer_get_length(buf);
uint32_t const offset_end = data->block_offset + len; uint32_t const offset_end = data->block_offset + len;
tr_cache* cache = data->session->cache; tr_cache* cache = data->session->cache;
@@ -371,12 +371,12 @@ static void on_idle(tr_webseed* w)
task->session = tor->session; task->session = tor->session;
task->webseed = w; task->webseed = w;
task->block = first; task->block = first;
task->piece_index = tr_torBlockPiece(tor, first); task->piece_index = tor->pieceForBlock(first);
task->piece_offset = tor->blockSize * first - tor->info.pieceSize * task->piece_index; task->piece_offset = tor->block_size * first - tor->info.pieceSize * task->piece_index;
task->length = (last - first) * tor->blockSize + tr_torBlockCountBytes(tor, last); task->length = (last - first) * tor->block_size + tor->countBytesInBlock(last);
task->blocks_done = 0; task->blocks_done = 0;
task->response_code = 0; task->response_code = 0;
task->block_size = tor->blockSize; task->block_size = tor->block_size;
task->content = evbuffer_new(); task->content = evbuffer_new();
evbuffer_add_cb(task->content, on_content_changed, task); evbuffer_add_cb(task->content, on_content_changed, task);
w->tasks.insert(task); w->tasks.insert(task);
@@ -425,7 +425,7 @@ static void web_response_func(
if (!success) 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) if (blocks_remain != 0)
{ {
@@ -448,7 +448,7 @@ static void web_response_func(
} }
else 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); uint32_t const buf_len = evbuffer_get_length(t->content);
if (bytes_done + buf_len < t->length) 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; auto& urls = t->webseed->file_urls;
tr_info const* inf = tr_torrentInfo(tor); 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); 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; tr_piece_index_t const step_piece = total_offset / inf->pieceSize;

View File

@@ -1,5 +1,6 @@
add_executable(libtransmission-test add_executable(libtransmission-test
bitfield-test.cc bitfield-test.cc
block-info-test.cc
blocklist-test.cc blocklist-test.cc
clients-test.cc clients-test.cc
copy-test.cc copy-test.cc
@@ -14,9 +15,9 @@ add_executable(libtransmission-test
makemeta-test.cc makemeta-test.cc
metainfo-test.cc metainfo-test.cc
move-test.cc move-test.cc
peer-msgs-test.cc
peer-mgr-wishlist-test.cc
peer-mgr-active-requests-test.cc peer-mgr-active-requests-test.cc
peer-mgr-wishlist-test.cc
peer-msgs-test.cc
quark-test.cc quark-test.cc
rename-test.cc rename-test.cc
rpc-test.cc rpc-test.cc

View 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);
}

View File

@@ -80,28 +80,28 @@ TEST_P(IncompleteDirTest, incompleteDir)
auto const test_incomplete_dir_threadfunc = [](void* vdata) noexcept auto const test_incomplete_dir_threadfunc = [](void* vdata) noexcept
{ {
auto* data = static_cast<TestIncompleteDirData*>(vdata); 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); tr_torrentGotBlock(data->tor, data->block);
data->done = true; data->done = true;
}; };
// now finish writing it // now finish writing it
{ {
char* zero_block = tr_new0(char, tor->blockSize); char* zero_block = tr_new0(char, tor->block_size);
struct TestIncompleteDirData data = {}; struct TestIncompleteDirData data = {};
data.session = session_; data.session = session_;
data.tor = tor; data.tor = tor;
data.buf = evbuffer_new(); 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) 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.block = block_index;
data.done = false; data.done = false;
data.offset = data.block * tor->blockSize; data.offset = data.block * tor->block_size;
tr_runInEventThread(session_, test_incomplete_dir_threadfunc, &data); tr_runInEventThread(session_, test_incomplete_dir_threadfunc, &data);
auto const test = [&data]() auto const test = [&data]()