From 6b9c27048e2d6da0a3f2b247e9fc279b11879c3b Mon Sep 17 00:00:00 2001 From: miguel Date: Sat, 17 Aug 2013 20:12:44 -0300 Subject: [PATCH] partial untested torrent chages. will use leveldb for storage, no more multi-files per torrent, number of pieces may increase. --- .../include/libtorrent/peer_request.hpp | 7 +- .../include/libtorrent/piece_picker.hpp | 3 +- libtorrent/include/libtorrent/storage.hpp | 4 +- libtorrent/include/libtorrent/torrent.hpp | 2 + .../include/libtorrent/torrent_info.hpp | 1 + libtorrent/src/Makefile.am | 2 +- libtorrent/src/file_storage.cpp | 18 +- libtorrent/src/peer_connection.cpp | 2 +- libtorrent/src/piece_picker.cpp | 44 +- libtorrent/src/storage.cpp | 6 +- libtorrent/src/torrent.cpp | 449 ++---------------- libtorrent/src/torrent_info.cpp | 17 +- libtorrent/test/Makefile.am | 2 +- src/main.cpp | 2 +- src/twister.cpp | 3 +- 15 files changed, 131 insertions(+), 431 deletions(-) diff --git a/libtorrent/include/libtorrent/peer_request.hpp b/libtorrent/include/libtorrent/peer_request.hpp index 309b61ba..2c76f54e 100644 --- a/libtorrent/include/libtorrent/peer_request.hpp +++ b/libtorrent/include/libtorrent/peer_request.hpp @@ -40,9 +40,14 @@ namespace libtorrent int piece; int start; int length; + // [MF] don't compare length so we can ask for pieces without knowing size + /* bool operator==(peer_request const& r) const { return piece == r.piece && start == r.start && length == r.length; } - }; + */ + bool operator==(peer_request const& r) const + { return piece == r.piece && start == r.start; } + }; } #endif // TORRENT_PEER_REQUEST_HPP_INCLUDED diff --git a/libtorrent/include/libtorrent/piece_picker.hpp b/libtorrent/include/libtorrent/piece_picker.hpp index d17b01f8..dc14c0e3 100644 --- a/libtorrent/include/libtorrent/piece_picker.hpp +++ b/libtorrent/include/libtorrent/piece_picker.hpp @@ -212,7 +212,8 @@ namespace libtorrent // sets all pieces to dont-have void init(int blocks_per_piece, int blocks_in_last_piece, int total_num_pieces); - int num_pieces() const { return int(m_piece_map.size()); } + void increase_num_pieces(int total_num_pieces); + int num_pieces() const { return int(m_piece_map.size()); } bool have_piece(int index) const { diff --git a/libtorrent/include/libtorrent/storage.hpp b/libtorrent/include/libtorrent/storage.hpp index b9043748..5d06fcd7 100644 --- a/libtorrent/include/libtorrent/storage.hpp +++ b/libtorrent/include/libtorrent/storage.hpp @@ -33,6 +33,8 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_STORAGE_HPP_INCLUDE #define TORRENT_STORAGE_HPP_INCLUDE +#include "../../src/leveldb.h" + #include #include @@ -186,7 +188,7 @@ namespace libtorrent session_settings* m_settings; }; - class TORRENT_EXPORT default_storage : public storage_interface, boost::noncopyable + class TORRENT_EXPORT default_storage : public storage_interface, boost::noncopyable, CLevelDB { public: default_storage(file_storage const& fs, file_storage const* mapped, std::string const& path diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index ccfa9fbb..58a377cf 100644 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -734,6 +734,8 @@ namespace libtorrent torrent_handle get_handle(); + void increase_num_pieces(int num_pieces); + void write_resume_data(entry& rd) const; void read_resume_data(lazy_entry const& rd); diff --git a/libtorrent/include/libtorrent/torrent_info.hpp b/libtorrent/include/libtorrent/torrent_info.hpp index deacb69d..17f01885 100644 --- a/libtorrent/include/libtorrent/torrent_info.hpp +++ b/libtorrent/include/libtorrent/torrent_info.hpp @@ -307,6 +307,7 @@ namespace libtorrent size_type total_size() const { return m_files.total_size(); } int piece_length() const { return m_files.piece_length(); } int num_pieces() const { return m_files.num_pieces(); } + void increase_num_pieces(int n); const sha1_hash& info_hash() const { return m_info_hash; } const std::string& name() const { return m_files.name(); } diff --git a/libtorrent/src/Makefile.am b/libtorrent/src/Makefile.am index 21296db7..c4ccf579 100644 --- a/libtorrent/src/Makefile.am +++ b/libtorrent/src/Makefile.am @@ -119,7 +119,7 @@ libtorrent_rasterbar_la_LIBADD = @BOOST_SYSTEM_LIB@ @OPENSSL_LIBS@ #AM_CXXFLAGS= -ftemplate-depth-100 -I$(top_srcdir)/include @DEBUGFLAGS@ @OPENSSL_INCLUDES@ #AM_CPPFLAGS = -ftemplate-depth-100 -I$(top_srcdir)/include @DEBUGFLAGS@ @OPENSSL_INCLUDES@ -AM_CPPFLAGS = -ftemplate-depth-100 -I$(top_srcdir)/include @DEBUGFLAGS@ @OPENSSL_INCLUDES@ +AM_CPPFLAGS = -ftemplate-depth-100 -I$(top_srcdir)/include -I$(top_srcdir)/../src -I$(top_srcdir)/../src/leveldb/include @DEBUGFLAGS@ @OPENSSL_INCLUDES@ #AM_CFLAGS= -I$(top_srcdir)/include @DEBUGFLAGS@ #AM_LDFLAGS = $(LDFLAGS) @BOOST_SYSTEM_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_THREAD_LIB@ @OPENSSL_LDFLAGS@ @OPENSSL_LIBS@ diff --git a/libtorrent/src/file_storage.cpp b/libtorrent/src/file_storage.cpp index a2cf924b..b9d18f88 100644 --- a/libtorrent/src/file_storage.cpp +++ b/libtorrent/src/file_storage.cpp @@ -56,7 +56,8 @@ namespace libtorrent int file_storage::piece_size(int index) const { TORRENT_ASSERT(index >= 0 && index < num_pieces()); - if (index == num_pieces()-1) + /* [MF] always report the max (16KB) + if (index == num_pieces()-1) { size_type size_except_last = num_pieces() - 1; size_except_last *= size_type(piece_length()); @@ -65,7 +66,7 @@ namespace libtorrent TORRENT_ASSERT(size <= piece_length()); return int(size); } - else + else */ return piece_length(); } @@ -208,17 +209,8 @@ namespace libtorrent file_storage::iterator file_storage::file_at_offset(size_type offset) const { - // find the file iterator and file offset - internal_file_entry target; - target.offset = offset; - TORRENT_ASSERT(!compare_file_offset(target, m_files.front())); - - std::vector::const_iterator file_iter = std::upper_bound( - begin(), end(), target, compare_file_offset); - - TORRENT_ASSERT(file_iter != begin()); - --file_iter; - return file_iter; + //[MF] only one "file" + return begin(); } std::vector file_storage::map_block(int piece, size_type offset diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index 784e8c97..a7d811eb 100644 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -2303,7 +2303,7 @@ namespace libtorrent piece_picker& picker = t->picker(); piece_manager& fs = t->filesystem(); - std::vector finished_blocks; + //std::vector finished_blocks; piece_block block_finished(p.piece, p.start / t->block_size()); TORRENT_ASSERT(verify_piece(p)); diff --git a/libtorrent/src/piece_picker.cpp b/libtorrent/src/piece_picker.cpp index 2dd76558..e86e78ad 100644 --- a/libtorrent/src/piece_picker.cpp +++ b/libtorrent/src/piece_picker.cpp @@ -134,6 +134,45 @@ namespace libtorrent TORRENT_ASSERT(m_blocks_in_last_piece <= m_blocks_per_piece); } + void piece_picker::increase_num_pieces(int total_num_pieces) + { +#ifdef TORRENT_PICKER_LOG + std::cerr << "piece_picker::increase_num_pieces(" << total_num_pieces << ")" << std::endl; +#endif + int old_num_pieces = m_piece_map.size(); + + // allocate the piece_map to cover all pieces + // and make them invalid + m_piece_map.resize(total_num_pieces, piece_pos(0, 0)); + m_reverse_cursor = int(m_piece_map.size()); + + //[MF] check this + //m_downloads.clear(); + //m_block_info.clear(); + + m_dirty = true; + for (std::vector::iterator i = m_piece_map.begin() + old_num_pieces + , end(m_piece_map.end()); i != end; ++i) + { + i->peer_count = 0; + i->downloading = 0; + i->index = 0; +#ifdef TORRENT_DEBUG_REFCOUNTS + i->have_peers.clear(); +#endif + } + + for (std::vector::reverse_iterator i = m_piece_map.rend() + - m_reverse_cursor; m_reverse_cursor > 0 && (i->have() || i->filtered()); + ++i, --m_reverse_cursor); + + // the piece index is stored in 20 bits, which limits the allowed + // number of pieces somewhat + TORRENT_ASSERT(m_piece_map.size() < piece_pos::we_have_index); + + update_pieces(); + } + void piece_picker::piece_info(int index, piece_picker::downloading_piece& st) const { #ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS @@ -1831,9 +1870,10 @@ namespace libtorrent { TORRENT_ASSERT(index >= 0); TORRENT_ASSERT(index < (int)m_piece_map.size() || m_piece_map.empty()); - if (index+1 == (int)m_piece_map.size()) + /* [MF] + if (index+1 == (int)m_piece_map.size()) return m_blocks_in_last_piece; - else + else */ return m_blocks_per_piece; } diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index 12556ac6..d8067370 100644 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -385,7 +385,9 @@ namespace libtorrent default_storage::default_storage(file_storage const& fs, file_storage const* mapped, std::string const& path , file_pool& fp, std::vector const& file_prio) - : m_files(fs) + // [MF] FIXME CLevelDB use path directly, cacheSize = 256K. + : CLevelDB(boost::filesystem::path(path), 256*1024, false, false) + , m_files(fs) , m_file_priority(file_prio) , m_pool(fp) , m_page_size(page_size()) @@ -1488,7 +1490,7 @@ ret: : m_info(info) , m_files(m_info->files()) , m_storage(sc(m_info->orig_files(), &m_info->files() != &m_info->orig_files() - ? &m_info->files() : 0, save_path, fp, file_prio)) + ? &m_info->files() : 0, save_path + to_hex(m_info->info_hash().to_string()), fp, file_prio)) , m_storage_mode(sm) , m_save_path(complete(save_path)) , m_state(state_none) diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 2dae99a9..20c67acd 100644 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -689,113 +689,6 @@ namespace libtorrent void torrent::on_torrent_download(error_code const& ec , http_parser const& parser, char const* data, int size) { - if (m_abort) return; - - if (ec && ec != asio::error::eof) - { - set_error(ec, m_url); - pause(); - return; - } - - if (parser.status_code() != 200) - { - // #error there should really be an error code category for HTTP - set_error(errors::http_error, parser.message()); - pause(); - return; - } - - error_code e; - intrusive_ptr tf(new torrent_info(data, size, e)); - if (e) - { - set_error(e, m_url); - pause(); - return; - } - - // update our torrent_info object and move the - // torrent from the old info-hash to the new one - // as we replace the torrent_info object -#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS - int num_torrents = m_ses.m_torrents.size(); -#endif - - // we're about to erase the session's reference to this - // torrent, create another reference - boost::shared_ptr me(shared_from_this()); - - m_ses.remove_torrent_impl(me, 0); - - if (alerts().should_post()) - alerts().post_alert(torrent_update_alert(get_handle(), info_hash(), tf->info_hash())); - - m_torrent_file = tf; - - // now, we might already have this torrent in the session. - session_impl::torrent_map::iterator i = m_ses.m_torrents.find(m_torrent_file->info_hash()); - if (i != m_ses.m_torrents.end()) - { - if (!m_uuid.empty() && i->second->uuid().empty()) - i->second->set_uuid(m_uuid); - if (!m_url.empty() && i->second->url().empty()) - i->second->set_url(m_url); - if (!m_source_feed_url.empty() && i->second->source_feed_url().empty()) - i->second->set_source_feed_url(m_source_feed_url); - - // insert this torrent in the uuid index - if (!m_uuid.empty() || !m_url.empty()) - { - m_ses.m_uuids.insert(std::make_pair(m_uuid.empty() - ? m_url : m_uuid, i->second)); - } - set_error(error_code(errors::duplicate_torrent, get_libtorrent_category()), ""); - abort(); - return; - } - - m_ses.m_torrents.insert(std::make_pair(m_torrent_file->info_hash(), me)); - if (!m_uuid.empty()) m_ses.m_uuids.insert(std::make_pair(m_uuid, me)); - - TORRENT_ASSERT(num_torrents == m_ses.m_torrents.size()); - - // if the user added any trackers while downloading the - // .torrent file, serge them into the new tracker list - std::vector new_trackers = m_torrent_file->trackers(); - for (std::vector::iterator i = m_trackers.begin() - , end(m_trackers.end()); i != end; ++i) - { - // if we already have this tracker, ignore it - if (std::find_if(new_trackers.begin(), new_trackers.end() - , boost::bind(&announce_entry::url, _1) == i->url) != new_trackers.end()) - continue; - - // insert the tracker ordered by tier - new_trackers.insert(std::find_if(new_trackers.begin(), new_trackers.end() - , boost::bind(&announce_entry::tier, _1) >= i->tier), *i); - } - m_trackers.swap(new_trackers); - -#ifndef TORRENT_DISABLE_ENCRYPTION - hasher h; - h.update("req2", 4); - h.update((char*)&m_torrent_file->info_hash()[0], 20); - m_obfuscated_hash = h.final(); -#endif - - if (m_ses.m_alerts.should_post()) - { - m_ses.m_alerts.post_alert(metadata_received_alert( - get_handle())); - } - - state_updated(); - - set_state(torrent_status::downloading); - - m_override_resume_data = true; - init(); } #endif @@ -901,17 +794,6 @@ namespace libtorrent void torrent::start_download_url() { - TORRENT_ASSERT(!m_url.empty()); - TORRENT_ASSERT(!m_torrent_file->is_valid()); - boost::shared_ptr conn( - new http_connection(m_ses.m_io_service, m_ses.m_half_open - , boost::bind(&torrent::on_torrent_download, shared_from_this() - , _1, _2, _3, _4) - , true //bottled - , m_ses.settings().max_http_recv_buffer_size //bottled buffer size - )); - conn->get(m_url, seconds(30), 0, 0, 5, m_ses.m_settings.user_agent); - set_state(torrent_status::downloading_metadata); } void torrent::set_apply_ip_filter(bool b) @@ -1005,7 +887,7 @@ namespace libtorrent TORRENT_ASSERT(piece >= 0 && piece < m_torrent_file->num_pieces()); int piece_size = m_torrent_file->piece_size(piece); - int blocks_in_piece = (piece_size + block_size() - 1) / block_size(); + int blocks_in_piece = (piece_size + block_size() - 1) / block_size(); // if blocks_in_piece is 0, rp will leak TORRENT_ASSERT(blocks_in_piece > 0); @@ -1216,6 +1098,7 @@ namespace libtorrent } } + // [MF] test only? void torrent::add_piece(int piece, char const* data, int flags) { TORRENT_ASSERT(m_ses.is_network_thread()); @@ -1710,37 +1593,13 @@ namespace libtorrent #endif TORRENT_ASSERT(block_size() > 0); - int file = 0; - for (file_storage::iterator i = m_torrent_file->files().begin() - , end(m_torrent_file->files().end()); i != end; ++i, ++file) - { - if (!i->pad_file || i->size == 0) continue; - m_padding += i->size; - - peer_request pr = m_torrent_file->map_file(file, 0, m_torrent_file->file_at(file).size); - int off = pr.start & (block_size()-1); - if (off != 0) { pr.length -= block_size() - off; pr.start += block_size() - off; } - TORRENT_ASSERT((pr.start & (block_size()-1)) == 0); - - int block = block_size(); - int blocks_per_piece = m_torrent_file->piece_length() / block; - piece_block pb(pr.piece, pr.start / block); - for (; pr.length >= block; pr.length -= block, ++pb.block_index) - { - if (int(pb.block_index) == blocks_per_piece) { pb.block_index = 0; ++pb.piece_index; } - m_picker->mark_as_finished(pb, 0); - } - // ugly edge case where padfiles are not used they way they're - // supposed to be. i.e. added back-to back or at the end - if (int(pb.block_index) == blocks_per_piece) { pb.block_index = 0; ++pb.piece_index; } - if (pr.length > 0 && ((boost::next(i) != end && boost::next(i)->pad_file) - || boost::next(i) == end)) - { - m_picker->mark_as_finished(pb, 0); - } - } + //[MF] + for( int i = 0; i < m_torrent_file->num_pieces(); i++) { + piece_block pb(i, 0); + m_picker->mark_as_finished(pb, 0); + } - if (m_padding > 0) + if (m_padding > 0) { // if we marked an entire piece as finished, we actually // need to consider it finished @@ -3260,39 +3119,6 @@ namespace libtorrent TORRENT_ASSERT(!have_piece(index)); TORRENT_ASSERT(!m_picker->have_piece(index)); - const int piece_size = m_torrent_file->piece_length(); - size_type off = size_type(index) * piece_size; - file_storage::iterator f = m_torrent_file->files().file_at_offset(off); - int size = m_torrent_file->piece_size(index); - int file_index = f - m_torrent_file->files().begin(); - for (; size > 0; ++f, ++file_index) - { - size_type file_offset = off - f->offset; - TORRENT_ASSERT(f != m_torrent_file->files().end()); - TORRENT_ASSERT(file_offset <= f->size); - int add = (std::min)(f->size - file_offset, (size_type)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.m_alerts.should_post()) - { - // this file just completed, post alert - m_ses.m_alerts.post_alert(file_completed_alert(get_handle() - , file_index)); - } - } - } - size -= add; - off += add; - TORRENT_ASSERT(size >= 0); - } - remove_time_critical_piece(index, true); m_picker->we_have(index); @@ -3747,14 +3573,6 @@ namespace libtorrent void torrent::on_files_released(int ret, disk_io_job const& j) { -/* - TORRENT_ASSERT(m_ses.is_network_thread()); - - if (alerts().should_post()) - { - alerts().post_alert(torrent_paused_alert(get_handle())); - } -*/ } void torrent::on_save_resume_data(int ret, disk_io_job const& j) @@ -4158,30 +3976,19 @@ namespace libtorrent // initialize the piece priorities to 0, then only allow // setting higher priorities std::vector pieces(m_torrent_file->num_pieces(), 0); - int index = 0; - for (file_storage::iterator i = m_torrent_file->files().begin() - , end(m_torrent_file->files().end()); i != end; ++i, ++index) - { - if (index >= m_torrent_file->num_files()) break; - size_type start = position; - size_type size = m_torrent_file->files().file_size(*i); - if (size == 0) continue; - position += size; - if (m_file_priority[index] == 0) continue; - - // mark all pieces of the file with this file's priority - // but only if the priority is higher than the pieces - // already set (to avoid problems with overlapping pieces) - int start_piece = int(start / piece_length); - int last_piece = int((position - 1) / piece_length); - TORRENT_ASSERT(last_piece < int(pieces.size())); - // if one piece spans several files, we might - // come here several times with the same start_piece, end_piece - std::for_each(pieces.begin() + start_piece - , pieces.begin() + last_piece + 1 - , boost::bind(&set_if_greater, _1, m_file_priority[index])); - } - prioritize_pieces(pieces); + + // [MF] just one "file" + // mark all pieces of the file with this file's priority + // but only if the priority is higher than the pieces + // already set (to avoid problems with overlapping pieces) + int start_piece = 0; + int last_piece = m_torrent_file->num_pieces() - 1; + TORRENT_ASSERT(last_piece < int(pieces.size())); + std::for_each(pieces.begin() + start_piece + , pieces.begin() + last_piece + 1 + , boost::bind(&set_if_greater, _1, m_file_priority[0])); + + prioritize_pieces(pieces); } // this is called when piece priorities have been updated @@ -4287,44 +4094,8 @@ namespace libtorrent void torrent::filter_files(std::vector const& bitmask) { - INVARIANT_CHECK; - - // this call is only valid on torrents with metadata - if (!valid_metadata() || is_seed()) return; - - // the bitmask need to have exactly one bit for every file - // in the torrent - TORRENT_ASSERT((int)bitmask.size() == m_torrent_file->num_files()); - - if (int(bitmask.size()) != m_torrent_file->num_files()) return; - - size_type position = 0; - - if (m_torrent_file->num_pieces()) - { - int piece_length = m_torrent_file->piece_length(); - // mark all pieces as filtered, then clear the bits for files - // that should be downloaded - std::vector piece_filter(m_torrent_file->num_pieces(), true); - for (int i = 0; i < (int)bitmask.size(); ++i) - { - size_type start = position; - position += m_torrent_file->files().file_size(i); - // is the file selected for download? - if (!bitmask[i]) - { - // mark all pieces of the file as downloadable - int start_piece = int(start / piece_length); - int last_piece = int(position / piece_length); - // if one piece spans several files, we might - // come here several times with the same start_piece, end_piece - std::fill(piece_filter.begin() + start_piece, piece_filter.begin() - + last_piece + 1, false); - } - } - filter_pieces(piece_filter); - } - } + // [MF] nop + } void torrent::replace_trackers(std::vector const& urls) { @@ -5145,8 +4916,25 @@ namespace libtorrent } #endif + // [MF] num_pieces increases with new twister posts + void torrent::increase_num_pieces(int num_pieces) + { + if( m_torrent_file->num_pieces() > num_pieces ) + return; + + m_torrent_file->increase_num_pieces(num_pieces); + + if(has_picker()) { + m_picker->increase_num_pieces(num_pieces); + } + } + void torrent::read_resume_data(lazy_entry const& rd) { + // [MF] + int num_pieces = rd.dict_find_int_value("num_pieces"); + increase_num_pieces(num_pieces); + m_total_uploaded = rd.dict_find_int_value("total_uploaded"); m_total_downloaded = rd.dict_find_int_value("total_downloaded"); m_active_time = rd.dict_find_int_value("active_time"); @@ -5181,23 +4969,6 @@ namespace libtorrent ? m_url : m_uuid, me)); } - // TODO: make this more generic to not just work if files have been - // renamed, but also if they have been merged into a single file for instance - // maybe use the same format as .torrent files and reuse some code from torrent_info - // The mapped_files needs to be read both in the network thread - // and in the disk thread, since they both have their own mapped files structures - // which are kept in sync - lazy_entry const* mapped_files = rd.dict_find_list("mapped_files"); - if (mapped_files && mapped_files->list_size() == m_torrent_file->num_files()) - { - for (int i = 0; i < m_torrent_file->num_files(); ++i) - { - std::string new_filename = mapped_files->list_string_value_at(i); - if (new_filename.empty()) continue; - m_torrent_file->rename_file(i, new_filename); - } - } - m_added_time = rd.dict_find_int_value("added_time", m_added_time); m_completed_time = rd.dict_find_int_value("completed_time", m_completed_time); if (m_completed_time != 0 && m_completed_time < m_added_time) @@ -5343,6 +5114,9 @@ namespace libtorrent ret["file-version"] = 1; ret["libtorrent-version"] = LIBTORRENT_VERSION; + // [MF] + ret["num_pieces"] = m_torrent_file->num_pieces(); + ret["total_uploaded"] = m_total_uploaded; ret["total_downloaded"] = m_total_downloaded; @@ -5504,21 +5278,6 @@ namespace libtorrent pieces[i] |= m_verified[i] ? 2 : 0; } - // write renamed files - // TODO: 0 make this more generic to not just work if files have been - // renamed, but also if they have been merged into a single file for instance. - // using file_base - if (&m_torrent_file->files() != &m_torrent_file->orig_files() - && m_torrent_file->files().num_files() == m_torrent_file->orig_files().num_files()) - { - entry::list_type& fl = ret["mapped_files"].list(); - for (torrent_info::file_iterator i = m_torrent_file->begin_files() - , end(m_torrent_file->end_files()); i != end; ++i) - { - fl.push_back(m_torrent_file->files().file_path(*i)); - } - } - // write local peers std::back_insert_iterator peers(ret["peers"].string()); @@ -6550,16 +6309,6 @@ namespace libtorrent bool torrent::rename_file(int index, std::string const& name) { - INVARIANT_CHECK; - - TORRENT_ASSERT(index >= 0); - TORRENT_ASSERT(index < m_torrent_file->num_files()); - - if (!m_owning_storage.get()) return false; - - m_owning_storage->async_rename_file(index, name - , boost::bind(&torrent::on_file_renamed, shared_from_this(), _1, _2)); - return true; } void torrent::move_storage(std::string const& save_path, int flags) @@ -8477,119 +8226,9 @@ namespace libtorrent for (int i = 0; i < m_torrent_file->num_files(); ++i) { - peer_request ret = m_torrent_file->files().map_file(i, 0, 0); - size_type size = m_torrent_file->files().file_size(i); - // zero sized files are considered // 100% done all the time - if (size == 0) - { - fp[i] = 0; - continue; - } - - size_type done = 0; - while (size > 0) - { - size_type bytes_step = (std::min)(size_type(m_torrent_file->piece_size(ret.piece) - - ret.start), size); - if (m_picker->have_piece(ret.piece)) done += bytes_step; - ++ret.piece; - ret.start = 0; - size -= bytes_step; - } - TORRENT_ASSERT(size == 0); - - fp[i] = done; - } - - const std::vector& q - = m_picker->get_download_queue(); - - for (std::vector::const_iterator - i = q.begin(), end(q.end()); i != end; ++i) - { - size_type offset = size_type(i->index) * m_torrent_file->piece_length(); - torrent_info::file_iterator file = m_torrent_file->file_at_offset(offset); - int file_index = file - m_torrent_file->begin_files(); - int num_blocks = m_picker->blocks_in_piece(i->index); - piece_picker::block_info const* info = i->info; - for (int k = 0; k < num_blocks; ++k) - { - TORRENT_ASSERT(file != m_torrent_file->end_files()); - TORRENT_ASSERT(offset == size_type(i->index) * m_torrent_file->piece_length() - + k * block_size()); - TORRENT_ASSERT(offset < m_torrent_file->total_size()); - while (offset >= file->offset + file->size) - { - ++file; - ++file_index; - } - TORRENT_ASSERT(file != m_torrent_file->end_files()); - - size_type block = block_size(); - - if (info[k].state == piece_picker::block_info::state_none) - { - offset += block; - continue; - } - - if (info[k].state == piece_picker::block_info::state_requested) - { - block = 0; - policy::peer* p = static_cast(info[k].peer); - if (p && p->connection) - { - boost::optional pbp - = p->connection->downloading_piece_progress(); - if (pbp && pbp->piece_index == i->index && pbp->block_index == k) - block = pbp->bytes_downloaded; - TORRENT_ASSERT(block <= block_size()); - } - - if (block == 0) - { - offset += block_size(); - continue; - } - } - - if (offset + block > file->offset + file->size) - { - int left_over = int(block_size() - block); - // split the block on multiple files - while (block > 0) - { - TORRENT_ASSERT(offset <= file->offset + file->size); - size_type slice = (std::min)(file->offset + file->size - offset - , block); - fp[file_index] += slice; - offset += slice; - block -= slice; - TORRENT_ASSERT(offset <= file->offset + file->size); - if (offset == file->offset + file->size) - { - ++file; - ++file_index; - if (file == m_torrent_file->end_files()) - { - offset += block; - break; - } - } - } - offset += left_over; - TORRENT_ASSERT(offset == size_type(i->index) * m_torrent_file->piece_length() - + (k+1) * block_size()); - } - else - { - fp[file_index] += block; - offset += block_size(); - } - TORRENT_ASSERT(file_index <= m_torrent_file->num_files()); - } + fp[i] = 0; } } diff --git a/libtorrent/src/torrent_info.cpp b/libtorrent/src/torrent_info.cpp index 7d35e2e8..78a76551 100644 --- a/libtorrent/src/torrent_info.cpp +++ b/libtorrent/src/torrent_info.cpp @@ -838,11 +838,26 @@ namespace libtorrent , m_multifile(false) , m_private(false) , m_i2p(false) - {} + { + // [MF] Fake it. + m_files.set_piece_length(16*1024); + m_files.set_num_pieces(1); + file_entry e; + e.size = 1; + m_files.add_file(e); + } torrent_info::~torrent_info() {} + void torrent_info::increase_num_pieces(int n) + { + if( num_pieces() > n ) + return; + + m_files.set_num_pieces(n); + } + void torrent_info::copy_on_write() { INVARIANT_CHECK; diff --git a/libtorrent/test/Makefile.am b/libtorrent/test/Makefile.am index 1af023af..1474c641 100644 --- a/libtorrent/test/Makefile.am +++ b/libtorrent/test/Makefile.am @@ -131,7 +131,7 @@ test_web_seed_SOURCES = test_web_seed.cpp LDADD = $(top_builddir)/src/libtorrent-rasterbar.la libtest.la #AM_CXXFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include -I$(top_srcdir)/include/libtorrent @DEBUGFLAGS@ @PTHREAD_CFLAGS@ -AM_CPPFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include @DEBUGFLAGS@ +AM_CPPFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include -I$(top_srcdir)/../src -I$(top_srcdir)/../src/leveldb/include @DEBUGFLAGS@ #AM_LDFLAGS= @BOOST_SYSTEM_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_THREAD_LIB@ @PTHREAD_LIBS@ @SSL_LDFLAGS@ @SSL_LIBS@ diff --git a/src/main.cpp b/src/main.cpp index 1eae3f81..24961fb5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1941,7 +1941,7 @@ bool static LoadBlockIndexDB() bool readTxIndex; pblocktree->ReadFlag("txindex", readTxIndex); printf("LoadBlockIndexDB(): transaction index %s\n", readTxIndex ? "enabled" : "disabled"); - assert( readTxIndex ); // always true in twister + //assert( readTxIndex ); // always true in twister // Load hashBestChain pointer to end of best chain pindexBest = pcoinsTip->GetBestBlock(); diff --git a/src/twister.cpp b/src/twister.cpp index a51309d9..8601247b 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -351,7 +351,8 @@ void ThreadSessionAlerts() add_torrent_params tparams; tparams.info_hash = ih; tparams.name = dd->m_username; - tparams.save_path="/tmp/"; + boost::filesystem::path torrentPath = GetDataDir() / "swarm" / ""; + tparams.save_path= torrentPath.string(); ses->async_add_torrent(tparams); } }