introduce type for slot index in part_file
This commit is contained in:
parent
42a27b3ebc
commit
cda715c152
|
@ -43,6 +43,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
struct slot_index_tag_t {};
|
||||
using slot_index_t = aux::strong_typedef<int, slot_index_tag_t>;
|
||||
|
||||
struct TORRENT_EXTRA_EXPORT part_file
|
||||
{
|
||||
// create a part file at 'path', that can hold 'num_pieces' pieces.
|
||||
|
@ -74,7 +77,7 @@ namespace libtorrent
|
|||
std::string m_name;
|
||||
|
||||
// allocate a slot and return the slot index
|
||||
int allocate_slot(piece_index_t piece);
|
||||
slot_index_t allocate_slot(piece_index_t piece);
|
||||
|
||||
// this mutex must be held while accessing the data
|
||||
// structure. Not while reading or writing from the file though!
|
||||
|
@ -83,10 +86,10 @@ namespace libtorrent
|
|||
|
||||
// this is a list of unallocated slots in the part file
|
||||
// within the m_num_allocated range
|
||||
std::vector<int> m_free_slots;
|
||||
std::vector<slot_index_t> m_free_slots;
|
||||
|
||||
// this is the number of slots allocated
|
||||
int m_num_allocated;
|
||||
slot_index_t m_num_allocated;
|
||||
|
||||
// the max number of pieces in the torrent this part file is
|
||||
// backing
|
||||
|
@ -106,7 +109,7 @@ namespace libtorrent
|
|||
bool m_dirty_metadata;
|
||||
|
||||
// maps a piece index to the part-file slot it is stored in
|
||||
std::unordered_map<piece_index_t, int> m_piece_map;
|
||||
std::unordered_map<piece_index_t, slot_index_t> m_piece_map;
|
||||
|
||||
// this is the file handle to the part file
|
||||
file m_file;
|
||||
|
|
|
@ -701,7 +701,7 @@ std::shared_ptr<torrent_info> make_torrent(bool priv)
|
|||
|
||||
ct.add_tracker("http://tracker.com:8080/announce");
|
||||
|
||||
for (int i = 0; i < ct.num_pieces(); ++i)
|
||||
for (piece_index_t i(0); i < piece_index_t(ct.num_pieces()); ++i)
|
||||
ct.set_hash(i, sha1_hash(nullptr));
|
||||
|
||||
ct.set_priv(priv);
|
||||
|
|
|
@ -57,10 +57,10 @@ add_torrent_params create_torrent(file_storage& fs, bool const pad_files = false
|
|||
, pad_files ? create_torrent::optimize_alignment : 0);
|
||||
|
||||
std::vector<char> piece(piece_size);
|
||||
int const num = t.num_pieces();
|
||||
piece_index_t const num = fs.end_piece();
|
||||
if (pad_files)
|
||||
{
|
||||
for (int i = 0; i < num; ++i)
|
||||
for (piece_index_t i(0); i < num; ++i)
|
||||
{
|
||||
std::vector<file_slice> files = fs.map_block(i, 0, fs.piece_size(i));
|
||||
int k = 0;
|
||||
|
@ -92,7 +92,7 @@ add_torrent_params create_torrent(file_storage& fs, bool const pad_files = false
|
|||
|
||||
// calculate the hash for all pieces
|
||||
sha1_hash ph = hasher(&piece[0], int(piece.size())).final();
|
||||
for (int i = 0; i < num; ++i)
|
||||
for (piece_index_t i(0); i < num; ++i)
|
||||
t.set_hash(i, ph);
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ add_torrent_params create_torrent(file_storage& fs, bool const pad_files = false
|
|||
if ((fs.total_size() % piece_size) > 0)
|
||||
{
|
||||
piece.resize(fs.total_size() % piece_size);
|
||||
t.set_hash(num-1, hasher(&piece[0], int(piece.size())).final());
|
||||
t.set_hash(prev(num), hasher(&piece[0], int(piece.size())).final());
|
||||
}
|
||||
|
||||
std::vector<char> tmp;
|
||||
|
@ -239,7 +239,7 @@ TORRENT_TEST(multi_file)
|
|||
TEST_CHECK(expected[1]);
|
||||
}
|
||||
|
||||
std::string generate_content(lt::file_storage const& fs, int file
|
||||
std::string generate_content(lt::file_storage const& fs, file_index_t file
|
||||
, std::int64_t offset, std::int64_t len)
|
||||
{
|
||||
std::string ret;
|
||||
|
@ -252,9 +252,9 @@ std::string generate_content(lt::file_storage const& fs, int file
|
|||
}
|
||||
|
||||
void serve_content_for(sim::http_server& http, std::string const& path
|
||||
, lt::file_storage const& fs, int const file)
|
||||
, lt::file_storage const& fs, file_index_t const file)
|
||||
{
|
||||
http.register_content(path, fs.file_size(file)
|
||||
http.register_content(path, fs.file_size(file_index_t(file))
|
||||
, [&fs,file](std::int64_t offset, std::int64_t len)
|
||||
{ return generate_content(fs, file, offset, len); });
|
||||
}
|
||||
|
@ -294,8 +294,8 @@ TORRENT_TEST(unaligned_file_redirect)
|
|||
// server for serving the content
|
||||
sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3"));
|
||||
sim::http_server http2(web_server2, 4444);
|
||||
serve_content_for(http2, "/bla/file1", fs, 0);
|
||||
serve_content_for(http2, "/bar/file2", fs, 1);
|
||||
serve_content_for(http2, "/bla/file1", fs, file_index_t(0));
|
||||
serve_content_for(http2, "/bar/file2", fs, file_index_t(1));
|
||||
|
||||
sim.run();
|
||||
}
|
||||
|
@ -343,12 +343,12 @@ TORRENT_TEST(multi_file_redirect_pad_files)
|
|||
// server for file 1
|
||||
sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3"));
|
||||
sim::http_server http2(web_server2, 4444);
|
||||
serve_content_for(http2, "/bla/file1", fs, 0);
|
||||
serve_content_for(http2, "/bla/file1", fs, file_index_t(0));
|
||||
|
||||
// server for file 2
|
||||
sim::asio::io_service web_server3(sim, address_v4::from_string("4.4.4.4"));
|
||||
sim::http_server http3(web_server3, 9999);
|
||||
serve_content_for(http3, "/bar/file2", fs, 2);
|
||||
serve_content_for(http3, "/bar/file2", fs, file_index_t(2));
|
||||
|
||||
sim.run();
|
||||
}
|
||||
|
@ -391,12 +391,12 @@ TORRENT_TEST(multi_file_redirect)
|
|||
// server for file 1
|
||||
sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3"));
|
||||
sim::http_server http2(web_server2, 4444);
|
||||
serve_content_for(http2, "/bla/file1", fs, 0);
|
||||
serve_content_for(http2, "/bla/file1", fs, file_index_t(0));
|
||||
|
||||
// server for file 2
|
||||
sim::asio::io_service web_server3(sim, address_v4::from_string("4.4.4.4"));
|
||||
sim::http_server http3(web_server3, 9999);
|
||||
serve_content_for(http3, "/bar/file2", fs, 1);
|
||||
serve_content_for(http3, "/bar/file2", fs, file_index_t(1));
|
||||
|
||||
sim.run();
|
||||
}
|
||||
|
@ -438,12 +438,12 @@ TORRENT_TEST(multi_file_unaligned_redirect)
|
|||
// server for file 1
|
||||
sim::asio::io_service web_server2(sim, address_v4::from_string("3.3.3.3"));
|
||||
sim::http_server http2(web_server2, 4444);
|
||||
serve_content_for(http2, "/bla/file1", fs, 0);
|
||||
serve_content_for(http2, "/bla/file1", fs, file_index_t(0));
|
||||
|
||||
// server for file 2
|
||||
sim::asio::io_service web_server3(sim, address_v4::from_string("4.4.4.4"));
|
||||
sim::http_server http3(web_server3, 9999);
|
||||
serve_content_for(http3, "/bar/file2", fs, 1);
|
||||
serve_content_for(http3, "/bar/file2", fs, file_index_t(1));
|
||||
|
||||
sim.run();
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/part_file.hpp"
|
||||
#include "libtorrent/io.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/aux_/vector.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -113,28 +114,27 @@ namespace libtorrent
|
|||
|
||||
// this is used to determine which slots are free, and how many
|
||||
// slots are allocated
|
||||
std::vector<bool> free_slots;
|
||||
aux::vector<bool, slot_index_t> free_slots;
|
||||
free_slots.resize(num_pieces, true);
|
||||
|
||||
for (piece_index_t i = piece_index_t(0); i < piece_index_t(num_pieces); ++i)
|
||||
{
|
||||
std::uint32_t const uslot = read_uint32(ptr);
|
||||
if (uslot == 0xffffffff) continue;
|
||||
int const slot = int(uslot);
|
||||
slot_index_t const slot(read_int32(ptr));
|
||||
if (static_cast<int>(slot) < 0) continue;
|
||||
|
||||
// invalid part-file
|
||||
TORRENT_ASSERT(slot < num_pieces);
|
||||
if (slot >= num_pieces) continue;
|
||||
TORRENT_ASSERT(slot < slot_index_t(num_pieces));
|
||||
if (slot >= slot_index_t(num_pieces)) continue;
|
||||
|
||||
if (slot >= m_num_allocated)
|
||||
m_num_allocated = slot + 1;
|
||||
m_num_allocated = next(slot);
|
||||
|
||||
free_slots[slot] = false;
|
||||
m_piece_map[i] = slot;
|
||||
}
|
||||
|
||||
// now, populate the free_list with the "holes"
|
||||
for (int i = 0; i < m_num_allocated; ++i)
|
||||
for (slot_index_t i(0); i < m_num_allocated; ++i)
|
||||
{
|
||||
if (free_slots[i]) m_free_slots.push_back(i);
|
||||
}
|
||||
|
@ -149,12 +149,12 @@ namespace libtorrent
|
|||
flush_metadata_impl(ec);
|
||||
}
|
||||
|
||||
int part_file::allocate_slot(piece_index_t const piece)
|
||||
slot_index_t part_file::allocate_slot(piece_index_t const piece)
|
||||
{
|
||||
// the mutex is assumed to be held here, since this is a private function
|
||||
|
||||
TORRENT_ASSERT(m_piece_map.find(piece) == m_piece_map.end());
|
||||
int slot = -1;
|
||||
slot_index_t slot(-1);
|
||||
if (!m_free_slots.empty())
|
||||
{
|
||||
slot = m_free_slots.front();
|
||||
|
@ -180,16 +180,13 @@ namespace libtorrent
|
|||
open_file(file::read_write, ec);
|
||||
if (ec) return -1;
|
||||
|
||||
int slot = -1;
|
||||
auto const i = m_piece_map.find(piece);
|
||||
if (i == m_piece_map.end())
|
||||
slot = allocate_slot(piece);
|
||||
else
|
||||
slot = i->second;
|
||||
slot_index_t const slot = (i == m_piece_map.end())
|
||||
? allocate_slot(piece) : i->second;
|
||||
|
||||
l.unlock();
|
||||
|
||||
std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(slot) * m_piece_size;
|
||||
std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(static_cast<int>(slot)) * m_piece_size;
|
||||
return int(m_file.writev(slot_offset + offset, bufs, ec));
|
||||
}
|
||||
|
||||
|
@ -207,14 +204,13 @@ namespace libtorrent
|
|||
return -1;
|
||||
}
|
||||
|
||||
int slot = i->second;
|
||||
|
||||
slot_index_t const slot = i->second;
|
||||
open_file(file::read_write, ec);
|
||||
if (ec) return -1;
|
||||
|
||||
l.unlock();
|
||||
|
||||
std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(slot) * m_piece_size;
|
||||
std::int64_t slot_offset = std::int64_t(m_header_size) + std::int64_t(static_cast<int>(slot)) * m_piece_size;
|
||||
return int(m_file.readv(slot_offset + offset, bufs, ec));
|
||||
}
|
||||
|
||||
|
@ -316,14 +312,14 @@ namespace libtorrent
|
|||
int const block_to_copy = int(std::min(m_piece_size - piece_offset, size));
|
||||
if (i != m_piece_map.end())
|
||||
{
|
||||
int const slot = i->second;
|
||||
slot_index_t const slot = i->second;
|
||||
open_file(file::read_only, ec);
|
||||
if (ec) return;
|
||||
|
||||
if (!buf) buf.reset(new char[m_piece_size]);
|
||||
|
||||
std::int64_t const slot_offset = std::int64_t(m_header_size)
|
||||
+ std::int64_t(slot) * m_piece_size;
|
||||
+ std::int64_t(static_cast<int>(slot)) * m_piece_size;
|
||||
|
||||
// don't hold the lock during disk I/O
|
||||
l.unlock();
|
||||
|
@ -407,10 +403,9 @@ namespace libtorrent
|
|||
for (piece_index_t piece(0); piece < piece_index_t(m_max_pieces); ++piece)
|
||||
{
|
||||
auto const i = m_piece_map.find(piece);
|
||||
int const slot = i == m_piece_map.end()
|
||||
? 0xffffffff
|
||||
: i->second;
|
||||
write_uint32(slot, ptr);
|
||||
slot_index_t const slot(i == m_piece_map.end()
|
||||
? slot_index_t(-1) : i->second);
|
||||
write_int32(static_cast<int>(slot), ptr);
|
||||
}
|
||||
std::memset(ptr, 0, m_header_size - (ptr - reinterpret_cast<char*>(header.get())));
|
||||
|
||||
|
|
Loading…
Reference in New Issue