Browse Source

partial untested torrent chages. will use leveldb for storage, no more multi-files per torrent, number of pieces may increase.

miguelfreitas
miguel 12 years ago
parent
commit
6b9c27048e
  1. 7
      libtorrent/include/libtorrent/peer_request.hpp
  2. 3
      libtorrent/include/libtorrent/piece_picker.hpp
  3. 4
      libtorrent/include/libtorrent/storage.hpp
  4. 2
      libtorrent/include/libtorrent/torrent.hpp
  5. 1
      libtorrent/include/libtorrent/torrent_info.hpp
  6. 2
      libtorrent/src/Makefile.am
  7. 18
      libtorrent/src/file_storage.cpp
  8. 2
      libtorrent/src/peer_connection.cpp
  9. 44
      libtorrent/src/piece_picker.cpp
  10. 6
      libtorrent/src/storage.cpp
  11. 449
      libtorrent/src/torrent.cpp
  12. 17
      libtorrent/src/torrent_info.cpp
  13. 2
      libtorrent/test/Makefile.am
  14. 2
      src/main.cpp
  15. 3
      src/twister.cpp

7
libtorrent/include/libtorrent/peer_request.hpp

@ -40,9 +40,14 @@ namespace libtorrent @@ -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

3
libtorrent/include/libtorrent/piece_picker.hpp

@ -212,7 +212,8 @@ namespace libtorrent @@ -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
{

4
libtorrent/include/libtorrent/storage.hpp

@ -33,6 +33,8 @@ POSSIBILITY OF SUCH DAMAGE. @@ -33,6 +33,8 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TORRENT_STORAGE_HPP_INCLUDE
#define TORRENT_STORAGE_HPP_INCLUDE
#include "../../src/leveldb.h"
#include <vector>
#include <sys/types.h>
@ -186,7 +188,7 @@ namespace libtorrent @@ -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

2
libtorrent/include/libtorrent/torrent.hpp

@ -734,6 +734,8 @@ namespace libtorrent @@ -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);

1
libtorrent/include/libtorrent/torrent_info.hpp

@ -307,6 +307,7 @@ namespace libtorrent @@ -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(); }

2
libtorrent/src/Makefile.am

@ -119,7 +119,7 @@ libtorrent_rasterbar_la_LIBADD = @BOOST_SYSTEM_LIB@ @OPENSSL_LIBS@ @@ -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@

18
libtorrent/src/file_storage.cpp

@ -56,7 +56,8 @@ namespace libtorrent @@ -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 @@ -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 @@ -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<internal_file_entry>::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_slice> file_storage::map_block(int piece, size_type offset

2
libtorrent/src/peer_connection.cpp

@ -2303,7 +2303,7 @@ namespace libtorrent @@ -2303,7 +2303,7 @@ namespace libtorrent
piece_picker& picker = t->picker();
piece_manager& fs = t->filesystem();
std::vector<piece_block> finished_blocks;
//std::vector<piece_block> finished_blocks;
piece_block block_finished(p.piece, p.start / t->block_size());
TORRENT_ASSERT(verify_piece(p));

44
libtorrent/src/piece_picker.cpp

@ -134,6 +134,45 @@ namespace libtorrent @@ -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<piece_pos>::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<piece_pos>::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 @@ -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;
}

6
libtorrent/src/storage.cpp

@ -385,7 +385,9 @@ namespace libtorrent @@ -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<boost::uint8_t> 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: @@ -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)

449
libtorrent/src/torrent.cpp

@ -689,113 +689,6 @@ namespace libtorrent @@ -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<torrent_info> 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<torrent> me(shared_from_this());
m_ses.remove_torrent_impl(me, 0);
if (alerts().should_post<torrent_update_alert>())
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<announce_entry> new_trackers = m_torrent_file->trackers();
for (std::vector<announce_entry>::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<metadata_received_alert>())
{
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 @@ -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<http_connection> 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 @@ -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 @@ -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 @@ -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 @@ -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<file_completed_alert>())
{
// 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 @@ -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<torrent_paused_alert>())
{
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 @@ -4158,30 +3976,19 @@ namespace libtorrent
// initialize the piece priorities to 0, then only allow
// setting higher priorities
std::vector<int> 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 @@ -4287,44 +4094,8 @@ namespace libtorrent
void torrent::filter_files(std::vector<bool> 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<bool> 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<announce_entry> const& urls)
{
@ -5145,8 +4916,25 @@ namespace libtorrent @@ -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 @@ -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 @@ -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 @@ -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<entry::string_type> peers(ret["peers"].string());
@ -6550,16 +6309,6 @@ namespace libtorrent @@ -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 @@ -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<piece_picker::downloading_piece>& q
= m_picker->get_download_queue();
for (std::vector<piece_picker::downloading_piece>::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<policy::peer*>(info[k].peer);
if (p && p->connection)
{
boost::optional<piece_block_progress> 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;
}
}

17
libtorrent/src/torrent_info.cpp

@ -838,11 +838,26 @@ namespace libtorrent @@ -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;

2
libtorrent/test/Makefile.am

@ -131,7 +131,7 @@ test_web_seed_SOURCES = test_web_seed.cpp @@ -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@

2
src/main.cpp

@ -1941,7 +1941,7 @@ bool static LoadBlockIndexDB() @@ -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();

3
src/twister.cpp

@ -351,7 +351,8 @@ void ThreadSessionAlerts() @@ -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);
}
}

Loading…
Cancel
Save