From e2784df13c8ea5f1ce7676d62cb769036de334e1 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 28 Jun 2015 22:47:11 -0400 Subject: [PATCH] factor out file progress tracking from the torrent class --- Jamfile | 1 + include/libtorrent/Makefile.am | 1 + include/libtorrent/aux_/file_progress.hpp | 78 ++++++++++ include/libtorrent/torrent.hpp | 13 +- src/Makefile.am | 1 + src/file_progress.cpp | 170 ++++++++++++++++++++++ src/torrent.cpp | 129 ++-------------- test/Jamfile | 3 +- test/Makefile.am | 3 +- test/test_file_progress.cpp | 110 ++++++++++++++ test/test_torrent.cpp | 62 -------- 11 files changed, 382 insertions(+), 189 deletions(-) create mode 100644 include/libtorrent/aux_/file_progress.hpp create mode 100644 src/file_progress.cpp create mode 100644 test/test_file_progress.cpp diff --git a/Jamfile b/Jamfile index cbde085be..100cba093 100755 --- a/Jamfile +++ b/Jamfile @@ -684,6 +684,7 @@ SOURCES = performance_counters resolver session_settings + file_progress # -- extensions -- metadata_transfer diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index 07f74b90e..071d884ef 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -166,6 +166,7 @@ nobase_include_HEADERS = \ aux_/session_settings.hpp \ aux_/session_interface.hpp \ aux_/time.hpp \ + aux_/file_progress.hpp \ \ extensions/lt_trackers.hpp \ extensions/metadata_transfer.hpp \ diff --git a/include/libtorrent/aux_/file_progress.hpp b/include/libtorrent/aux_/file_progress.hpp new file mode 100644 index 000000000..e4a7cd142 --- /dev/null +++ b/include/libtorrent/aux_/file_progress.hpp @@ -0,0 +1,78 @@ +/* + +Copyright (c) 2015, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TORRENT_FILE_PROGRESS_HPP_INCLUDE +#define TORRENT_FILE_PROGRESS_HPP_INCLUDE + +#include +#include + +namespace libtorrent +{ +class piece_picker; +class file_storage; +class alert_manager; +class torrent_handle; + +namespace aux +{ + struct file_progress + { + file_progress(); + + void init(piece_picker const& picker + , file_storage const& fs); + + void export_progress(std::vector &fp); + + void clear(); + + void update(file_storage const& fs, int index + , alert_manager* alerts, torrent_handle const& h); + +#if TORRENT_USE_INVARIANT_CHECKS + void check_invariant(file_storage const& fs) const; +#endif + + private: + + // this vector contains the number of bytes completely + // downloaded (as in passed-hash-check) in each file. + // this lets us trigger on individual files completing + // the vector is allocated lazily, when file progress + // is first queried by the client + std::vector m_file_progress; + }; +} } + +#endif + diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index dd6af65e5..9025d4bfd 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -74,6 +74,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/vector_utils.hpp" #include "libtorrent/linked_list.hpp" #include "libtorrent/debug.hpp" +#include "libtorrent/aux_/file_progress.hpp" #if TORRENT_COMPLETE_TYPES_REQUIRED #include "libtorrent/peer_connection.hpp" @@ -99,10 +100,6 @@ namespace libtorrent struct listen_socket_t; - TORRENT_EXTRA_EXPORT void initialize_file_progress( - std::vector& file_progress - , piece_picker const& picker, file_storage const& fs); - namespace aux { struct piece_checker_data; @@ -1269,12 +1266,8 @@ namespace libtorrent // TODO: this wastes 5 bits per file std::vector m_file_priority; - // this vector contains the number of bytes completely - // downloaded (as in passed-hash-check) in each file. - // this lets us trigger on individual files completing - // the vector is allocated lazily, when file progress - // is first queried by the client - std::vector m_file_progress; + // this object is used to track download progress of individual files + aux::file_progress m_file_progress; // these are the pieces we're currently // suggesting to peers. diff --git a/src/Makefile.am b/src/Makefile.am index bf800ab7a..b1d8fe78c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -142,6 +142,7 @@ libtorrent_rasterbar_la_SOURCES = \ utp_stream.cpp \ web_peer_connection.cpp \ xml_parse.cpp \ + file_progress.cpp \ \ $(KADEMLIA_SOURCES) \ $(ASIO_OPENSSL_SOURCES) diff --git a/src/file_progress.cpp b/src/file_progress.cpp new file mode 100644 index 000000000..74a039cc8 --- /dev/null +++ b/src/file_progress.cpp @@ -0,0 +1,170 @@ +/* + +Copyright (c) 2015, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "libtorrent/piece_picker.hpp" +#include "libtorrent/file_storage.hpp" +#include "libtorrent/alert_manager.hpp" +#include "libtorrent/aux_/file_progress.hpp" +#include "libtorrent/alert_types.hpp" + +namespace libtorrent { namespace aux +{ + + file_progress::file_progress() + { + } + + void file_progress::init(piece_picker const& picker, file_storage const& fs) + { + if (!m_file_progress.empty()) return; + + int num_pieces = fs.num_pieces(); + int num_files = fs.num_files(); + + m_file_progress.resize(num_files, 0); + std::fill(m_file_progress.begin(), m_file_progress.end(), 0); + + // initialize the progress of each file + + const int piece_size = fs.piece_length(); + boost::uint64_t off = 0; + boost::uint64_t total_size = fs.total_size(); + int file_index = 0; + for (int piece = 0; piece < num_pieces; ++piece, off += piece_size) + { + TORRENT_ASSERT(file_index < fs.num_files()); + boost::int64_t file_offset = off - fs.file_offset(file_index); + TORRENT_ASSERT(file_offset >= 0); + while (file_offset >= fs.file_size(file_index)) + { + ++file_index; + TORRENT_ASSERT(file_index < fs.num_files()); + file_offset = off - fs.file_offset(file_index); + TORRENT_ASSERT(file_offset >= 0); + } + TORRENT_ASSERT(file_offset <= fs.file_size(file_index)); + + if (!picker.have_piece(piece)) continue; + + int size = (std::min)(boost::uint64_t(piece_size), total_size - off); + TORRENT_ASSERT(size >= 0); + + while (size) + { + int add = (std::min)(boost::int64_t(size), fs.file_size(file_index) - file_offset); + TORRENT_ASSERT(add >= 0); + m_file_progress[file_index] += add; + + TORRENT_ASSERT(m_file_progress[file_index] + <= fs.file_size(file_index)); + + size -= add; + TORRENT_ASSERT(size >= 0); + if (size > 0) + { + ++file_index; + TORRENT_ASSERT(file_index < fs.num_files()); + file_offset = 0; + } + } + } + } + + void file_progress::export_progress(std::vector &fp) + { + fp.resize(m_file_progress.size(), 0); + std::copy(m_file_progress.begin(), m_file_progress.end(), fp.begin()); + } + + void file_progress::clear() + { + std::vector().swap(m_file_progress); + } + + // update the file progress now that we just completed downloading piece + // 'index' + void file_progress::update(file_storage const& fs, int index + , alert_manager* alerts, torrent_handle const& h) + { + if (m_file_progress.empty()) + return; + + const int piece_size = fs.piece_length(); + boost::int64_t off = boost::int64_t(index) * piece_size; + int file_index = fs.file_index_at_offset(off); + int size = fs.piece_size(index); + for (; size > 0; ++file_index) + { + boost::int64_t file_offset = off - fs.file_offset(file_index); + TORRENT_ASSERT(file_index != fs.num_files()); + TORRENT_ASSERT(file_offset <= fs.file_size(file_index)); + int add = (std::min)(fs.file_size(file_index) - file_offset, (boost::int64_t)size); + m_file_progress[file_index] += add; + + TORRENT_ASSERT(m_file_progress[file_index] + <= fs.file_size(file_index)); + + // TODO: it would be nice to not depend on alert_manager here + if (m_file_progress[file_index] >= fs.file_size(file_index) && alerts) + { + if (!fs.pad_file_at(file_index)) + { + if (alerts->should_post()) + { + // this file just completed, post alert + alerts->emplace_alert(h, file_index); + } + } + } + size -= add; + off += add; + TORRENT_ASSERT(size >= 0); + } + } + +#if TORRENT_USE_INVARIANT_CHECKS + void file_progress::check_invariant(file_storage const& fs) const + { + if (!m_file_progress.empty()) + { + for (std::vector::const_iterator i = m_file_progress.begin() + , end(m_file_progress.end()); i != end; ++i) + { + int index = i - m_file_progress.begin(); + TORRENT_ASSERT(*i <= fs.file_size(index)); + } + } + } +#endif +} } + + diff --git a/src/torrent.cpp b/src/torrent.cpp index e65271a4e..5a2924b2b 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -93,6 +93,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/resolver_interface.hpp" #include "libtorrent/alloca.hpp" #include "libtorrent/resolve_links.hpp" +#include "libtorrent/aux_/file_progress.hpp" #ifndef TORRENT_DISABLE_LOGGING #include "libtorrent/aux_/session_impl.hpp" // for tracker_logger @@ -803,7 +804,7 @@ namespace libtorrent update_gauge(); - std::vector().swap(m_file_progress); + m_file_progress.clear(); if (m_resume_data) { @@ -2560,7 +2561,7 @@ namespace libtorrent // file progress is allocated lazily, the first time the client // asks for it - std::vector().swap(m_file_progress); + m_file_progress.clear(); // assume that we don't have anything m_files_checked = false; @@ -4196,41 +4197,8 @@ namespace libtorrent m_ses.alerts().emplace_alert(get_handle(), index); // update m_file_progress (if we have one) - if (!m_file_progress.empty()) - { - const int piece_size = m_torrent_file->piece_length(); - boost::int64_t off = boost::int64_t(index) * piece_size; - int file_index = m_torrent_file->files().file_index_at_offset(off); - int size = m_torrent_file->piece_size(index); - file_storage const& fs = m_torrent_file->files(); - for (; size > 0; ++file_index) - { - boost::int64_t file_offset = off - fs.file_offset(file_index); - TORRENT_ASSERT(file_index != fs.num_files()); - TORRENT_ASSERT(file_offset <= fs.file_size(file_index)); - int add = (std::min)(fs.file_size(file_index) - file_offset, (boost::int64_t)size); - m_file_progress[file_index] += add; - - TORRENT_ASSERT(m_file_progress[file_index] - <= m_torrent_file->files().file_size(file_index)); - - if (m_file_progress[file_index] >= m_torrent_file->files().file_size(file_index)) - { - if (!m_torrent_file->files().pad_file_at(file_index)) - { - if (m_ses.alerts().should_post()) - { - // this file just completed, post alert - m_ses.alerts().emplace_alert(get_handle() - , file_index); - } - } - } - size -= add; - off += add; - TORRENT_ASSERT(size >= 0); - } - } + m_file_progress.update(m_torrent_file->files(), index + , &m_ses.alerts(), get_handle()); remove_time_critical_piece(index, true); @@ -8299,7 +8267,8 @@ namespace libtorrent m_became_seed = m_ses.session_time(); // no need for this anymore - std::vector().swap(m_file_progress); + m_file_progress.clear(); + if (!m_announcing) return; time_point now = aux::time_now(); @@ -8824,15 +8793,7 @@ namespace libtorrent TORRENT_ASSERT(block_size() > 0); } - if (!m_file_progress.empty()) - { - for (std::vector::const_iterator i = m_file_progress.begin() - , end(m_file_progress.end()); i != end; ++i) - { - int index = i - m_file_progress.begin(); - TORRENT_ASSERT(*i <= m_torrent_file->files().file_size(index)); - } - } + m_file_progress.check_invariant(m_torrent_file->files()); } #endif @@ -11233,61 +11194,6 @@ namespace libtorrent } #endif - void initialize_file_progress(std::vector& file_progress - , piece_picker const& picker, file_storage const& fs) - { - int num_pieces = fs.num_pieces(); - int num_files = fs.num_files(); - - file_progress.resize(num_files, 0); - std::fill(file_progress.begin(), file_progress.end(), 0); - - // initialize the progress of each file - - const int piece_size = fs.piece_length(); - boost::uint64_t off = 0; - boost::uint64_t total_size = fs.total_size(); - int file_index = 0; - for (int piece = 0; piece < num_pieces; ++piece, off += piece_size) - { - TORRENT_ASSERT(file_index < fs.num_files()); - boost::int64_t file_offset = off - fs.file_offset(file_index); - TORRENT_ASSERT(file_offset >= 0); - while (file_offset >= fs.file_size(file_index)) - { - ++file_index; - TORRENT_ASSERT(file_index < fs.num_files()); - file_offset = off - fs.file_offset(file_index); - TORRENT_ASSERT(file_offset >= 0); - } - TORRENT_ASSERT(file_offset <= fs.file_size(file_index)); - - if (!picker.have_piece(piece)) continue; - - int size = (std::min)(boost::uint64_t(piece_size), total_size - off); - TORRENT_ASSERT(size >= 0); - - while (size) - { - int add = (std::min)(boost::int64_t(size), fs.file_size(file_index) - file_offset); - TORRENT_ASSERT(add >= 0); - file_progress[file_index] += add; - - TORRENT_ASSERT(file_progress[file_index] - <= fs.file_size(file_index)); - - size -= add; - TORRENT_ASSERT(size >= 0); - if (size > 0) - { - ++file_index; - TORRENT_ASSERT(file_index < fs.num_files()); - file_offset = 0; - } - } - } - } - void torrent::file_progress(std::vector& fp, int flags) { TORRENT_ASSERT(is_single_thread()); @@ -11320,21 +11226,14 @@ namespace libtorrent } int num_files = m_torrent_file->num_files(); - if (m_file_progress.empty()) - { - // This is the first time the client asks for file progress. - // allocate it and make sure it's up to date + // if this is the first time the client asks for file progress. + // allocate it and make sure it's up to date - // we cover the case where we're a seed above - TORRENT_ASSERT(has_picker()); + // we cover the case where we're a seed above + TORRENT_ASSERT(has_picker()); + m_file_progress.init(picker(), m_torrent_file->files()); - initialize_file_progress(m_file_progress - , picker(), m_torrent_file->files()); - } - - fp.resize(num_files, 0); - - std::copy(m_file_progress.begin(), m_file_progress.end(), fp.begin()); + m_file_progress.export_progress(fp); if (flags & torrent_handle::piece_granularity) return; diff --git a/test/Jamfile b/test/Jamfile index de0bf73ac..8a3274fee 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -141,7 +141,8 @@ test-suite libtorrent : test_peer_classes.cpp test_settings_pack.cpp test_fence.cpp - test_dos_blocker.cpp ] + test_dos_blocker.cpp + test_file_progress.cpp ] [ run test_storage.cpp ] [ run test_session.cpp ] diff --git a/test/Makefile.am b/test/Makefile.am index a62babf43..820451bbb 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -32,7 +32,8 @@ test_programs = \ test_session \ test_web_seed \ test_url_seed \ - test_remap_files + test_remap_files \ + test_file_progress if ENABLE_TESTS check_PROGRAMS = $(test_programs) diff --git a/test/test_file_progress.cpp b/test/test_file_progress.cpp new file mode 100644 index 000000000..1c3d76caf --- /dev/null +++ b/test/test_file_progress.cpp @@ -0,0 +1,110 @@ +/* + +Copyright (c) 2015, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "test_utils.hpp" +#include "libtorrent/aux_/file_progress.hpp" +#include "libtorrent/file_storage.hpp" +#include "libtorrent/piece_picker.hpp" + +using namespace libtorrent; + +TORRENT_TEST(init) +{ + // test the init function to make sure it assigns + // the correct number of bytes across the files + const int piece_size = 256; + + file_storage fs; + fs.add_file("torrent/1", 0); + fs.add_file("torrent/2", 10); + fs.add_file("torrent/3", 20); + fs.add_file("torrent/4", 30); + fs.add_file("torrent/5", 40); + fs.add_file("torrent/6", 100000); + fs.add_file("torrent/7", 30); + fs.set_piece_length(piece_size); + fs.set_num_pieces((fs.total_size() + piece_size - 1) / piece_size); + + for (int idx = 0; idx < fs.num_pieces(); ++idx) + { + piece_picker picker; + picker.init(4, fs.total_size() % 4, fs.num_pieces()); + picker.we_have(idx); + + aux::file_progress fp; + fp.init(picker, fs); + + std::vector vec; + fp.export_progress(vec); + + boost::uint64_t sum = 0; + for (int i = 0; i < int(vec.size()); ++i) + sum += vec[i]; + + TEST_EQUAL(sum, fs.piece_size(idx)); + } +} + +TORRENT_TEST(init2) +{ + // test the init function to make sure it assigns + // the correct number of bytes across the files + const int piece_size = 256; + + file_storage fs; + fs.add_file("torrent/1", 100000); + fs.add_file("torrent/2", 10); + fs.set_piece_length(piece_size); + fs.set_num_pieces((fs.total_size() + piece_size - 1) / piece_size); + + for (int idx = 0; idx < fs.num_pieces(); ++idx) + { + piece_picker picker; + picker.init(4, fs.total_size() % 4, fs.num_pieces()); + picker.we_have(idx); + + std::vector vec; + aux::file_progress fp; + + fp.init(picker, fs); + fp.export_progress(vec); + + boost::uint64_t sum = 0; + for (int i = 0; i < vec.size(); ++i) + sum += vec[i]; + + TEST_EQUAL(int(sum), fs.piece_size(idx)); + } +} + +// TODO: test the update function too + diff --git a/test/test_torrent.cpp b/test/test_torrent.cpp index 6c656a073..bcf7f6bb3 100644 --- a/test/test_torrent.cpp +++ b/test/test_torrent.cpp @@ -204,68 +204,6 @@ TORRENT_TEST(torrent) test_running_torrent(info, 0); } - { - // test the initialize_file_progress function to make sure it assigns - // the correct number of bytes across the files - const int piece_size = 256; - - file_storage fs; - fs.add_file("torrent/1", 0); - fs.add_file("torrent/2", 10); - fs.add_file("torrent/3", 20); - fs.add_file("torrent/4", 30); - fs.add_file("torrent/5", 40); - fs.add_file("torrent/6", 100000); - fs.add_file("torrent/7", 30); - fs.set_piece_length(piece_size); - fs.set_num_pieces((fs.total_size() + piece_size - 1) / piece_size); - - for (int idx = 0; idx < fs.num_pieces(); ++idx) - { - piece_picker picker; - picker.init(4, fs.total_size() % 4, fs.num_pieces()); - picker.we_have(idx); - - std::vector fp; - - initialize_file_progress(fp, picker, fs); - - boost::uint64_t sum = 0; - for (int i = 0; i < int(fp.size()); ++i) - sum += fp[i]; - - TEST_EQUAL(sum, fs.piece_size(idx)); - } - } - - { - // test the initialize_file_progress function to make sure it assigns - // the correct number of bytes across the files - const int piece_size = 256; - - file_storage fs; - fs.add_file("torrent/1", 100000); - fs.add_file("torrent/2", 10); - fs.set_piece_length(piece_size); - fs.set_num_pieces((fs.total_size() + piece_size - 1) / piece_size); - - for (int idx = 0; idx < fs.num_pieces(); ++idx) - { - piece_picker picker; - picker.init(4, fs.total_size() % 4, fs.num_pieces()); - picker.we_have(idx); - - std::vector fp; - - initialize_file_progress(fp, picker, fs); - - boost::uint64_t sum = 0; - for (int i = 0; i < fp.size(); ++i) - sum += fp[i]; - - TEST_EQUAL(int(sum), fs.piece_size(idx)); - } - } }