Feat: add tr_block_info::Location (#2649)
This commit is contained in:
parent
02b6cc76d1
commit
f88f3c4b03
|
@ -38,9 +38,9 @@ struct tr_block_info
|
|||
return block_size;
|
||||
}
|
||||
|
||||
// return the number of bytes in `block`
|
||||
[[nodiscard]] constexpr auto blockSize(tr_block_index_t block) const
|
||||
{
|
||||
// how many bytes are in this block?
|
||||
return block + 1 == n_blocks ? final_block_size : blockSize();
|
||||
}
|
||||
|
||||
|
@ -49,86 +49,25 @@ struct tr_block_info
|
|||
return n_pieces;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr tr_piece_index_t pieceForBlock(tr_block_index_t block) const
|
||||
{
|
||||
// if not initialized yet, don't divide by zero
|
||||
if (n_blocks_in_piece == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return block / n_blocks_in_piece;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto pieceSize() const
|
||||
{
|
||||
return piece_size;
|
||||
}
|
||||
|
||||
// return the number of bytes in `piece`
|
||||
[[nodiscard]] constexpr auto pieceSize(tr_piece_index_t piece) const
|
||||
{
|
||||
// how many bytes are in this piece?
|
||||
return piece + 1 == n_pieces ? final_piece_size : pieceSize();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr tr_piece_index_t pieceOf(uint64_t offset) const
|
||||
{
|
||||
// if not initialized yet, don't divide by zero
|
||||
if (piece_size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle 0-byte files at the end of a torrent
|
||||
if (offset == total_size)
|
||||
{
|
||||
return n_pieces - 1;
|
||||
}
|
||||
|
||||
return offset / piece_size;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr tr_block_index_t blockOf(uint64_t offset) const
|
||||
{
|
||||
// if not initialized yet, don't divide by zero
|
||||
if (block_size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle 0-byte files at the end of a torrent
|
||||
if (offset == total_size)
|
||||
{
|
||||
return n_blocks - 1;
|
||||
}
|
||||
|
||||
return offset / block_size;
|
||||
}
|
||||
|
||||
[[nodiscard]] 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;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto blockOf(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
{
|
||||
return blockOf(this->offset(piece, offset, length));
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr tr_block_span_t blockSpanForPiece(tr_piece_index_t piece) const
|
||||
{
|
||||
if (block_size == 0)
|
||||
if (!isInitialized())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto const begin = blockOf(offset(piece, 0));
|
||||
auto const end = 1 + blockOf(offset(piece, pieceSize(piece) - 1));
|
||||
return { begin, end };
|
||||
return { pieceLoc(piece).block, pieceLastLoc(piece).block + 1 };
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto totalSize() const
|
||||
|
@ -136,5 +75,95 @@ struct tr_block_info
|
|||
return total_size;
|
||||
}
|
||||
|
||||
static uint32_t bestBlockSize(uint64_t piece_size);
|
||||
struct Location
|
||||
{
|
||||
uint64_t byte = 0;
|
||||
|
||||
tr_piece_index_t piece = 0;
|
||||
uint32_t piece_offset = 0;
|
||||
|
||||
tr_block_index_t block = 0;
|
||||
uint32_t block_offset = 0;
|
||||
|
||||
[[nodiscard]] bool operator==(Location const& that) const
|
||||
{
|
||||
return this->byte == that.byte;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator<(Location const& that) const
|
||||
{
|
||||
return this->byte < that.byte;
|
||||
}
|
||||
};
|
||||
|
||||
// Location of the first byte in `block`.
|
||||
[[nodiscard]] Location constexpr blockLoc(tr_block_index_t block) const
|
||||
{
|
||||
return byteLoc(uint64_t{ block } * blockSize());
|
||||
}
|
||||
|
||||
// Location of the last byte in `block`.
|
||||
[[nodiscard]] Location constexpr blockLastLoc(tr_block_index_t block) const
|
||||
{
|
||||
if (!isInitialized())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return byteLoc(uint64_t{ block } * blockSize() + blockSize(block) - 1);
|
||||
}
|
||||
|
||||
// Location of the first byte (+ optional offset and length) in `piece`
|
||||
[[nodiscard]] Location constexpr pieceLoc(tr_piece_index_t piece, uint32_t offset = 0, uint32_t length = 0) const
|
||||
{
|
||||
return byteLoc(uint64_t{ piece } * pieceSize() + offset + length);
|
||||
}
|
||||
|
||||
// Location of the last byte in `piece`.
|
||||
[[nodiscard]] Location constexpr pieceLastLoc(tr_piece_index_t piece) const
|
||||
{
|
||||
if (!isInitialized())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return byteLoc(uint64_t{ piece } * pieceSize() + pieceSize(piece) - 1);
|
||||
}
|
||||
|
||||
// Location of the torrent's nth byte
|
||||
[[nodiscard]] Location constexpr byteLoc(uint64_t byte) const
|
||||
{
|
||||
if (!isInitialized())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto loc = Location{};
|
||||
|
||||
loc.byte = byte;
|
||||
|
||||
if (byte == totalSize()) // handle 0-byte files at the end of a torrent
|
||||
{
|
||||
loc.block = blockCount() - 1;
|
||||
loc.piece = pieceCount() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
loc.block = byte / blockSize();
|
||||
loc.piece = byte / pieceSize();
|
||||
}
|
||||
|
||||
loc.block_offset = static_cast<uint32_t>(loc.byte - (uint64_t{ loc.block } * blockSize()));
|
||||
loc.piece_offset = static_cast<uint32_t>(loc.byte - (uint64_t{ loc.piece } * pieceSize()));
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
[[nodiscard]] static uint32_t bestBlockSize(uint64_t piece_size);
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool constexpr isInitialized() const
|
||||
{
|
||||
return n_blocks_in_piece != 0;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@ struct cache_block
|
|||
{
|
||||
tr_torrent* tor;
|
||||
|
||||
// TODO: use tr_block_info::Location
|
||||
tr_piece_index_t piece;
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
|
@ -304,9 +305,9 @@ static int cache_block_compare(void const* va, void const* vb)
|
|||
|
||||
static struct cache_block* findBlock(tr_cache* cache, tr_torrent* torrent, tr_piece_index_t piece, uint32_t offset)
|
||||
{
|
||||
struct cache_block key;
|
||||
auto key = cache_block{};
|
||||
key.tor = torrent;
|
||||
key.block = torrent->blockOf(piece, offset);
|
||||
key.block = torrent->pieceLoc(piece, offset).block;
|
||||
return static_cast<struct cache_block*>(tr_ptrArrayFindSorted(&cache->blocks, &key, cache_block_compare));
|
||||
}
|
||||
|
||||
|
@ -329,7 +330,7 @@ int tr_cacheWriteBlock(
|
|||
cb->piece = piece;
|
||||
cb->offset = offset;
|
||||
cb->length = length;
|
||||
cb->block = torrent->blockOf(piece, offset);
|
||||
cb->block = torrent->pieceLoc(piece, offset).block;
|
||||
cb->evbuf = evbuffer_new();
|
||||
tr_ptrArrayInsertSorted(&cache->blocks, cb, cache_block_compare);
|
||||
}
|
||||
|
|
|
@ -222,9 +222,8 @@ uint64_t tr_completion::countHasBytesInSpan(tr_byte_span_t span) const
|
|||
}
|
||||
|
||||
// get the block span of the byte span
|
||||
auto const begin_block = block_info_->blockOf(begin_byte);
|
||||
auto const final_byte = end_byte - 1;
|
||||
auto const final_block = block_info_->blockOf(final_byte);
|
||||
auto const begin_block = block_info_->byteLoc(begin_byte).block;
|
||||
auto const final_block = block_info_->byteLoc(end_byte - 1).block;
|
||||
|
||||
// if the entire span is in a single block
|
||||
if (begin_block == final_block)
|
||||
|
|
|
@ -26,7 +26,7 @@ void tr_file_piece_map::reset(tr_block_info const& block_info, uint64_t const* f
|
|||
{
|
||||
auto const file_size = file_sizes[i];
|
||||
auto const begin_byte = offset;
|
||||
auto const begin_piece = block_info.pieceOf(begin_byte);
|
||||
auto const begin_piece = block_info.byteLoc(begin_byte).piece;
|
||||
auto end_byte = tr_byte_index_t{};
|
||||
auto end_piece = tr_piece_index_t{};
|
||||
|
||||
|
@ -34,7 +34,7 @@ void tr_file_piece_map::reset(tr_block_info const& block_info, uint64_t const* f
|
|||
{
|
||||
end_byte = offset + file_size;
|
||||
auto const final_byte = end_byte - 1;
|
||||
auto const final_piece = block_info.pieceOf(final_byte);
|
||||
auto const final_piece = block_info.byteLoc(final_byte).piece;
|
||||
end_piece = final_piece + 1;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -816,7 +816,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(s->tor->blockOf(e->pieceIndex, e->offset), peer);
|
||||
s->active_requests.remove(s->tor->pieceLoc(e->pieceIndex, e->offset).block, peer);
|
||||
break;
|
||||
|
||||
case TR_PEER_CLIENT_GOT_CHOKE:
|
||||
|
@ -841,12 +841,11 @@ static void peerCallbackFunc(tr_peer* peer, tr_peer_event const* e, void* vs)
|
|||
|
||||
case TR_PEER_CLIENT_GOT_BLOCK:
|
||||
{
|
||||
tr_torrent* tor = s->tor;
|
||||
tr_piece_index_t const p = e->pieceIndex;
|
||||
tr_block_index_t const block = tor->blockOf(p, e->offset);
|
||||
cancelAllRequestsForBlock(s, block, peer);
|
||||
auto* const tor = s->tor;
|
||||
auto const loc = tor->pieceLoc(e->pieceIndex, e->offset);
|
||||
cancelAllRequestsForBlock(s, loc.block, peer);
|
||||
peer->blocksSentToClient.add(tr_time(), 1);
|
||||
tr_torrentGotBlock(tor, block);
|
||||
tr_torrentGotBlock(tor, loc.block);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -363,11 +363,6 @@ public:
|
|||
return tr_peerIoGetAge(io);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_reading_block(tr_block_index_t block) const override
|
||||
{
|
||||
return state == AwaitingBt::Piece && block == torrent->blockOf(incoming.blockReq.index, incoming.blockReq.offset);
|
||||
}
|
||||
|
||||
void cancel_block_request(tr_block_index_t block) override
|
||||
{
|
||||
protocolSendCancel(this, blockToReq(torrent, block));
|
||||
|
@ -1888,8 +1883,8 @@ static int clientGotBlock(tr_peerMsgsImpl* msgs, struct evbuffer* data, struct p
|
|||
TR_ASSERT(msgs != nullptr);
|
||||
TR_ASSERT(req != nullptr);
|
||||
|
||||
tr_torrent* tor = msgs->torrent;
|
||||
tr_block_index_t const block = tor->blockOf(req->index, req->offset);
|
||||
tr_torrent* const tor = msgs->torrent;
|
||||
auto const block = tor->pieceLoc(req->index, req->offset).block;
|
||||
|
||||
if (!requestIsValid(msgs, req))
|
||||
{
|
||||
|
@ -1952,7 +1947,7 @@ static ReadState canRead(tr_peerIo* io, void* vmsgs, size_t* piece)
|
|||
struct evbuffer* in = tr_peerIoGetReadBuffer(io);
|
||||
size_t const inlen = evbuffer_get_length(in);
|
||||
|
||||
dbgmsg(msgs, "canRead: inlen is %zu, msgs->state is %d", inlen, msgs->state);
|
||||
dbgmsg(msgs, "canRead: inlen is %zu, msgs->state is %d", inlen, int(msgs->state));
|
||||
|
||||
auto ret = ReadState{};
|
||||
if (inlen == 0)
|
||||
|
|
|
@ -48,7 +48,6 @@ public:
|
|||
virtual void update_active(tr_direction direction) = 0;
|
||||
|
||||
virtual time_t get_connection_age() const = 0;
|
||||
virtual bool is_reading_block(tr_block_index_t block) const = 0;
|
||||
|
||||
virtual void cancel_block_request(tr_block_index_t block) = 0;
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "magnet-metainfo.h"
|
||||
|
||||
struct tr_error;
|
||||
struct tr_info;
|
||||
|
||||
struct tr_torrent_metainfo : public tr_magnet_metainfo
|
||||
{
|
||||
|
@ -45,13 +44,17 @@ public:
|
|||
{
|
||||
return blockInfo().blockCount();
|
||||
}
|
||||
[[nodiscard]] constexpr auto blockOf(uint64_t offset) const
|
||||
[[nodiscard]] auto byteLoc(uint64_t byte) const
|
||||
{
|
||||
return blockInfo().blockOf(offset);
|
||||
return blockInfo().byteLoc(byte);
|
||||
}
|
||||
[[nodiscard]] constexpr auto blockOf(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
[[nodiscard]] auto blockLoc(tr_block_index_t block) const
|
||||
{
|
||||
return blockInfo().blockOf(piece, offset, length);
|
||||
return blockInfo().blockLoc(block);
|
||||
}
|
||||
[[nodiscard]] auto pieceLoc(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
{
|
||||
return blockInfo().pieceLoc(piece, offset, length);
|
||||
}
|
||||
[[nodiscard]] constexpr auto blockSize() const
|
||||
{
|
||||
|
@ -65,22 +68,10 @@ public:
|
|||
{
|
||||
return blockInfo().blockSpanForPiece(piece);
|
||||
}
|
||||
[[nodiscard]] constexpr auto offset(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
{
|
||||
return blockInfo().offset(piece, offset, length);
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceCount() const
|
||||
{
|
||||
return blockInfo().pieceCount();
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceForBlock(tr_block_index_t block) const
|
||||
{
|
||||
return blockInfo().pieceForBlock(block);
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceOf(uint64_t offset) const
|
||||
{
|
||||
return blockInfo().pieceOf(offset);
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceSize() const
|
||||
{
|
||||
return blockInfo().pieceSize();
|
||||
|
@ -147,12 +138,12 @@ public:
|
|||
return pieces_offset_;
|
||||
}
|
||||
|
||||
std::string torrentFile(std::string_view torrent_dir) const
|
||||
[[nodiscard]] std::string torrentFile(std::string_view torrent_dir) const
|
||||
{
|
||||
return makeFilename(torrent_dir, name(), infoHashString(), BasenameFormat::Hash, ".torrent");
|
||||
}
|
||||
|
||||
std::string resumeFile(std::string_view resume_dir) const
|
||||
[[nodiscard]] std::string resumeFile(std::string_view resume_dir) const
|
||||
{
|
||||
return makeFilename(resume_dir, name(), infoHashString(), BasenameFormat::Hash, ".resume");
|
||||
}
|
||||
|
@ -190,7 +181,7 @@ private:
|
|||
BasenameFormat format,
|
||||
std::string_view suffix);
|
||||
|
||||
std::string makeFilename(std::string_view dirname, BasenameFormat format, std::string_view suffix) const
|
||||
[[nodiscard]] std::string makeFilename(std::string_view dirname, BasenameFormat format, std::string_view suffix) const
|
||||
{
|
||||
return makeFilename(dirname, name(), infoHashString(), format, suffix);
|
||||
}
|
||||
|
@ -198,7 +189,7 @@ private:
|
|||
struct file_t
|
||||
{
|
||||
public:
|
||||
std::string const& path() const
|
||||
[[nodiscard]] std::string const& path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
@ -208,7 +199,7 @@ private:
|
|||
path_ = subpath;
|
||||
}
|
||||
|
||||
uint64_t size() const
|
||||
[[nodiscard]] uint64_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
|
|
@ -1977,7 +1977,7 @@ bool tr_torrentReqIsValid(tr_torrent const* tor, tr_piece_index_t index, uint32_
|
|||
{
|
||||
err = 4;
|
||||
}
|
||||
else if (tor->offset(index, offset, length) > tor->totalSize())
|
||||
else if (tor->pieceLoc(index, offset, length).byte > tor->totalSize())
|
||||
{
|
||||
err = 5;
|
||||
}
|
||||
|
@ -2001,14 +2001,14 @@ tr_block_span_t tr_torGetFileBlockSpan(tr_torrent const* tor, tr_file_index_t i)
|
|||
{
|
||||
auto const [begin_byte, end_byte] = tor->fpm_.byteSpan(i);
|
||||
|
||||
auto const begin_block = tor->blockOf(begin_byte);
|
||||
auto const begin_block = tor->byteLoc(begin_byte).block;
|
||||
if (begin_byte >= end_byte)
|
||||
{
|
||||
return { begin_block, begin_block };
|
||||
}
|
||||
|
||||
auto const final_byte = end_byte - 1;
|
||||
auto const end_block = tor->blockOf(final_byte) + 1;
|
||||
auto const final_block = tor->byteLoc(end_byte - 1).block;
|
||||
auto const end_block = final_block + 1;
|
||||
return { begin_block, end_block };
|
||||
}
|
||||
|
||||
|
@ -2572,21 +2572,21 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
|
|||
tor->completion.addBlock(block);
|
||||
tor->setDirty();
|
||||
|
||||
tr_piece_index_t const p = tor->pieceForBlock(block);
|
||||
auto const piece = tor->blockLoc(block).piece;
|
||||
|
||||
if (tor->hasPiece(p))
|
||||
if (tor->hasPiece(piece))
|
||||
{
|
||||
if (tor->checkPiece(p))
|
||||
if (tor->checkPiece(piece))
|
||||
{
|
||||
tr_torrentPieceCompleted(tor, p);
|
||||
tr_torrentPieceCompleted(tor, piece);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t const n = tor->pieceSize(p);
|
||||
tr_logAddTorErr(tor, _("Piece %" PRIu32 ", which was just downloaded, failed its checksum test"), p);
|
||||
uint32_t const n = tor->pieceSize(piece);
|
||||
tr_logAddTorErr(tor, _("Piece %" PRIu32 ", which was just downloaded, failed its checksum test"), piece);
|
||||
tor->corruptCur += n;
|
||||
tor->downloadedCur -= std::min(tor->downloadedCur, uint64_t{ n });
|
||||
tr_peerMgrGotBadPiece(tor, p);
|
||||
tr_peerMgrGotBadPiece(tor, piece);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,13 +155,17 @@ public:
|
|||
{
|
||||
return metainfo_.blockCount();
|
||||
}
|
||||
[[nodiscard]] constexpr auto blockOf(uint64_t offset) const
|
||||
[[nodiscard]] auto byteLoc(uint64_t byte) const
|
||||
{
|
||||
return metainfo_.blockOf(offset);
|
||||
return metainfo_.byteLoc(byte);
|
||||
}
|
||||
[[nodiscard]] constexpr auto blockOf(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
[[nodiscard]] auto blockLoc(tr_block_index_t block) const
|
||||
{
|
||||
return metainfo_.blockOf(piece, offset, length);
|
||||
return metainfo_.blockLoc(block);
|
||||
}
|
||||
[[nodiscard]] auto pieceLoc(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
{
|
||||
return metainfo_.pieceLoc(piece, offset, length);
|
||||
}
|
||||
[[nodiscard]] constexpr auto blockSize() const
|
||||
{
|
||||
|
@ -175,22 +179,10 @@ public:
|
|||
{
|
||||
return metainfo_.blockSpanForPiece(piece);
|
||||
}
|
||||
[[nodiscard]] constexpr auto offset(tr_piece_index_t piece, uint32_t offset, uint32_t length = 0) const
|
||||
{
|
||||
return metainfo_.offset(piece, offset, length);
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceCount() const
|
||||
{
|
||||
return metainfo_.pieceCount();
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceForBlock(tr_block_index_t block) const
|
||||
{
|
||||
return metainfo_.pieceForBlock(block);
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceOf(uint64_t offset) const
|
||||
{
|
||||
return metainfo_.pieceOf(offset);
|
||||
}
|
||||
[[nodiscard]] constexpr auto pieceSize() const
|
||||
{
|
||||
return metainfo_.pieceSize();
|
||||
|
@ -297,7 +289,7 @@ public:
|
|||
|
||||
[[nodiscard]] auto fileOffset(tr_piece_index_t piece, uint32_t piece_offset) const
|
||||
{
|
||||
return fpm_.fileOffset(this->offset(piece, piece_offset));
|
||||
return fpm_.fileOffset(this->pieceLoc(piece, piece_offset).byte);
|
||||
}
|
||||
|
||||
/// WANTED
|
||||
|
@ -784,9 +776,6 @@ char* tr_torrentBuildPartial(tr_torrent const*, tr_file_index_t fileNo);
|
|||
|
||||
tr_peer_id_t const& tr_torrentGetPeerId(tr_torrent* tor);
|
||||
|
||||
/** @brief free a metainfo */
|
||||
void tr_metainfoFree(tr_info* inf);
|
||||
|
||||
tr_torrent_metainfo&& tr_ctorStealMetainfo(tr_ctor* ctor);
|
||||
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string const& filename, tr_error** error);
|
||||
|
|
|
@ -41,10 +41,9 @@ public:
|
|||
tr_webseed_task(tr_torrent* tor, tr_webseed* webseed_in, tr_block_span_t span)
|
||||
: webseed{ webseed_in }
|
||||
, session{ tor->session }
|
||||
, block{ span.begin }
|
||||
, piece_index{ tor->pieceForBlock(this->block) }
|
||||
, piece_offset{ static_cast<uint32_t>(
|
||||
int64_t{ tor->blockSize() } * this->block - tor->pieceSize() * this->piece_index) }
|
||||
, block{ span.begin } // TODO(ckerr): just own the loc
|
||||
, piece_index{ tor->blockLoc(this->block).piece }
|
||||
, piece_offset{ tor->blockLoc(this->block).piece_offset }
|
||||
, block_size{ tor->blockSize() }
|
||||
, length{ (span.end - 1 - span.begin) * tor->blockSize() + tor->blockSize(span.end - 1) }
|
||||
{
|
||||
|
@ -500,7 +499,7 @@ void task_request_next_chunk(tr_webseed_task* t)
|
|||
auto const piece_size = tor->pieceSize();
|
||||
uint64_t const remain = t->length - t->blocks_done * tor->blockSize() - evbuffer_get_length(t->content());
|
||||
|
||||
auto const total_offset = tor->offset(t->piece_index, t->piece_offset, t->length - remain);
|
||||
auto const total_offset = tor->pieceLoc(t->piece_index, t->piece_offset, t->length - remain).byte;
|
||||
tr_piece_index_t const step_piece = total_offset / piece_size;
|
||||
uint64_t const step_piece_offset = total_offset - uint64_t(piece_size) * step_piece;
|
||||
|
||||
|
|
|
@ -65,23 +65,6 @@ TEST_F(BlockInfoTest, handlesOddSize)
|
|||
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, pieceSize)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
@ -112,31 +95,6 @@ TEST_F(BlockInfoTest, blockSize)
|
|||
EXPECT_EQ(1, info.blockSize(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, blockSpanForPiece)
|
||||
{
|
||||
auto info = tr_block_info{};
|
||||
|
@ -160,3 +118,197 @@ TEST_F(BlockInfoTest, blockSpanForPiece)
|
|||
EXPECT_EQ(0, info.blockSpanForPiece(0).begin);
|
||||
EXPECT_EQ(0, info.blockSpanForPiece(0).end);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, blockLoc)
|
||||
{
|
||||
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);
|
||||
|
||||
// begin
|
||||
auto loc = info.blockLoc(0);
|
||||
EXPECT_EQ(tr_block_info::Location{}, loc);
|
||||
|
||||
// third block is halfway through the first piece
|
||||
loc = info.blockLoc(2);
|
||||
EXPECT_EQ(ExpectedBlockSize * 2, loc.byte);
|
||||
EXPECT_EQ(2, loc.block);
|
||||
EXPECT_EQ(0, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(ExpectedBlockSize * 2, loc.piece_offset);
|
||||
|
||||
// second piece aligns with fifth block
|
||||
loc = info.blockLoc(4);
|
||||
EXPECT_EQ(PieceSize, loc.byte);
|
||||
EXPECT_EQ(4, loc.block);
|
||||
EXPECT_EQ(0, loc.block_offset);
|
||||
EXPECT_EQ(1, loc.piece);
|
||||
EXPECT_EQ(0, loc.piece_offset);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, blockLastLoc)
|
||||
{
|
||||
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);
|
||||
|
||||
auto loc = info.blockLastLoc(0);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1, loc.byte);
|
||||
EXPECT_EQ(0, loc.block);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1, loc.piece_offset);
|
||||
|
||||
loc = info.blockLastLoc(info.blockCount() - 1);
|
||||
EXPECT_EQ(info.totalSize() - 1, loc.byte);
|
||||
EXPECT_EQ(info.blockCount() - 1, loc.block);
|
||||
EXPECT_EQ(info.totalSize() - 1 - (ExpectedBlockSize * (info.blockCount() - 1)), loc.block_offset);
|
||||
EXPECT_EQ(info.pieceCount() - 1, loc.piece);
|
||||
EXPECT_EQ(info.totalSize() - 1 - PieceSize * (PieceCount - 1), loc.piece_offset);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, pieceLoc)
|
||||
{
|
||||
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);
|
||||
|
||||
// begin
|
||||
auto loc = info.pieceLoc(0);
|
||||
EXPECT_EQ(tr_block_info::Location{}, loc);
|
||||
|
||||
for (uint64_t i = 0; i < PieceCount; ++i)
|
||||
{
|
||||
loc = info.pieceLoc(i);
|
||||
EXPECT_EQ(info.blockLoc(i * ExpectedBlocksPerPiece), loc);
|
||||
EXPECT_EQ(PieceSize * i, loc.byte);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece * i, loc.block);
|
||||
EXPECT_EQ(0, loc.block_offset);
|
||||
EXPECT_EQ(i, loc.piece);
|
||||
EXPECT_EQ(0, loc.piece_offset);
|
||||
}
|
||||
|
||||
loc = info.pieceLoc(0, PieceSize - 1);
|
||||
EXPECT_EQ(PieceSize - 1, loc.byte);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece - 1, loc.block);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(PieceSize - 1, loc.piece_offset);
|
||||
|
||||
loc = info.pieceLoc(0, PieceSize);
|
||||
EXPECT_EQ(PieceSize, loc.byte);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece, loc.block);
|
||||
EXPECT_EQ(0, loc.block_offset);
|
||||
EXPECT_EQ(1, loc.piece);
|
||||
EXPECT_EQ(0, loc.piece_offset);
|
||||
|
||||
loc = info.pieceLoc(0, PieceSize + 1);
|
||||
EXPECT_EQ(PieceSize + 1, loc.byte);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece, loc.block);
|
||||
EXPECT_EQ(1, loc.block_offset);
|
||||
EXPECT_EQ(1, loc.piece);
|
||||
EXPECT_EQ(1, loc.piece_offset);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, pieceLastLoc)
|
||||
{
|
||||
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);
|
||||
|
||||
auto loc = info.pieceLastLoc(0);
|
||||
EXPECT_EQ(PieceSize - 1, loc.byte);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece - 1, loc.block);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(PieceSize - 1, loc.piece_offset);
|
||||
|
||||
loc = info.pieceLastLoc(info.pieceCount() - 1);
|
||||
EXPECT_EQ(info.totalSize() - 1, loc.byte);
|
||||
EXPECT_EQ(info.blockCount() - 1, loc.block);
|
||||
EXPECT_EQ(info.totalSize() - 1 - (ExpectedBlockSize * (info.blockCount() - 1)), loc.block_offset);
|
||||
EXPECT_EQ(info.pieceCount() - 1, loc.piece);
|
||||
EXPECT_EQ(info.totalSize() - 1 - PieceSize * (PieceCount - 1), loc.piece_offset);
|
||||
}
|
||||
|
||||
TEST_F(BlockInfoTest, byteLoc)
|
||||
{
|
||||
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);
|
||||
|
||||
auto loc = info.byteLoc(0);
|
||||
EXPECT_EQ(tr_block_info::Location{}, loc);
|
||||
|
||||
loc = info.byteLoc(1);
|
||||
EXPECT_EQ(1, loc.byte);
|
||||
EXPECT_EQ(0, loc.block);
|
||||
EXPECT_EQ(1, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(1, loc.piece_offset);
|
||||
|
||||
auto n = ExpectedBlockSize - 1;
|
||||
loc = info.byteLoc(n);
|
||||
EXPECT_EQ(n, loc.byte);
|
||||
EXPECT_EQ(0, loc.block);
|
||||
EXPECT_EQ(n, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(n, loc.piece_offset);
|
||||
|
||||
n = ExpectedBlockSize;
|
||||
loc = info.byteLoc(n);
|
||||
EXPECT_EQ(n, loc.byte);
|
||||
EXPECT_EQ(1, loc.block);
|
||||
EXPECT_EQ(0, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(n, loc.piece_offset);
|
||||
|
||||
n = ExpectedBlockSize + 1;
|
||||
loc = info.byteLoc(n);
|
||||
EXPECT_EQ(n, loc.byte);
|
||||
EXPECT_EQ(1, loc.block);
|
||||
EXPECT_EQ(1, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(n, loc.piece_offset);
|
||||
|
||||
n = PieceSize - 1;
|
||||
loc = info.byteLoc(n);
|
||||
EXPECT_EQ(n, loc.byte);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece - 1, loc.block);
|
||||
EXPECT_EQ(ExpectedBlockSize - 1, loc.block_offset);
|
||||
EXPECT_EQ(0, loc.piece);
|
||||
EXPECT_EQ(n, loc.piece_offset);
|
||||
|
||||
n = PieceSize;
|
||||
loc = info.byteLoc(n);
|
||||
EXPECT_EQ(n, loc.byte);
|
||||
EXPECT_EQ(ExpectedBlocksPerPiece, loc.block);
|
||||
EXPECT_EQ(0, loc.block_offset);
|
||||
EXPECT_EQ(1, loc.piece);
|
||||
EXPECT_EQ(0, loc.piece_offset);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue