forked from premiere/premiere-libtorrent
made storage pimpled
This commit is contained in:
parent
ef5a49b694
commit
22bfad216f
|
@ -163,7 +163,7 @@ int main(int argc, char* argv[])
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
// TEMPORARY
|
// TEMPORARY
|
||||||
// boost::filesystem::path::default_name_check(boost::filesystem::no_check);
|
boost::filesystem::path::default_name_check(boost::filesystem::no_check);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_DEBUG_HPP_INCLUDED
|
#define TORRENT_DEBUG_HPP_INCLUDED
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
|
#include "libtorrent/piece_picker.hpp"
|
||||||
#include "libtorrent/stat.hpp"
|
#include "libtorrent/stat.hpp"
|
||||||
#include "libtorrent/debug.hpp"
|
#include "libtorrent/debug.hpp"
|
||||||
|
|
||||||
|
|
|
@ -32,25 +32,22 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef TORRENT_STORAGE_HPP_INCLUDE
|
#ifndef TORRENT_STORAGE_HPP_INCLUDE
|
||||||
#define TORRENT_STORAGE_HPP_INCLUDE
|
#define TORRENT_STORAGE_HPP_INCLUDE
|
||||||
|
/*
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <algorithm>
|
#include <algorithm>*/
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
|
||||||
#include <list>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
//#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/policy.hpp"
|
//#include "libtorrent/policy.hpp"
|
||||||
|
#include "libtorrent/opaque_value_ptr.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file declares the following functions:
|
* This file declares the following functions:
|
||||||
|
@ -219,11 +216,6 @@ namespace libtorrent
|
||||||
const torrent_info& info
|
const torrent_info& info
|
||||||
, const boost::filesystem::path& path);
|
, const boost::filesystem::path& path);
|
||||||
|
|
||||||
~storage();
|
|
||||||
|
|
||||||
storage(const storage&);
|
|
||||||
void operator=(const storage&);
|
|
||||||
|
|
||||||
void swap(storage&);
|
void swap(storage&);
|
||||||
|
|
||||||
typedef entry::integer_type size_type;
|
typedef entry::integer_type size_type;
|
||||||
|
@ -232,8 +224,8 @@ namespace libtorrent
|
||||||
void write(const char* buf, int slot, size_type offset, size_type size);
|
void write(const char* buf, int slot, size_type offset, size_type size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct pimpl;
|
struct impl;
|
||||||
std::auto_ptr<pimpl> m_pimpl;
|
opaque_value_ptr<impl> m_pimpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
class piece_manager : boost::noncopyable
|
class piece_manager : boost::noncopyable
|
||||||
|
@ -256,18 +248,12 @@ namespace libtorrent
|
||||||
size_type read(char* buf, int piece_index, size_type offset, size_type size);
|
size_type read(char* buf, int piece_index, size_type offset, size_type size);
|
||||||
void write(const char* buf, int piece_index, size_type offset, size_type size);
|
void write(const char* buf, int piece_index, size_type offset, size_type size);
|
||||||
|
|
||||||
const boost::filesystem::path& save_path() const
|
const boost::filesystem::path& save_path() const;
|
||||||
{ return m_save_path; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct impl;
|
||||||
// returns the slot currently associated with the given
|
opaque_value_ptr<impl, false> m_pimpl;
|
||||||
// piece or assigns the given piece_index to a free slot
|
/*
|
||||||
int slot_for_piece(int piece_index);
|
|
||||||
|
|
||||||
void check_invariant() const;
|
|
||||||
void debug_log() const;
|
|
||||||
|
|
||||||
storage m_storage;
|
storage m_storage;
|
||||||
|
|
||||||
// total number of bytes left to be downloaded
|
// total number of bytes left to be downloaded
|
||||||
|
@ -298,7 +284,7 @@ namespace libtorrent
|
||||||
|
|
||||||
bool m_allocating;
|
bool m_allocating;
|
||||||
boost::mutex m_allocating_monitor;
|
boost::mutex m_allocating_monitor;
|
||||||
boost::condition m_allocating_condition;
|
boost::condition m_allocating_condition;*/
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
180
src/storage.cpp
180
src/storage.cpp
|
@ -1328,15 +1328,15 @@ namespace libtorrent {
|
||||||
int slot;
|
int slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct storage::pimpl : thread_safe_storage
|
struct storage::impl : thread_safe_storage
|
||||||
{
|
{
|
||||||
pimpl(const torrent_info& info, const fs::path& path)
|
impl(const torrent_info& info, const fs::path& path)
|
||||||
: thread_safe_storage(info.num_pieces())
|
: thread_safe_storage(info.num_pieces())
|
||||||
, info(info)
|
, info(info)
|
||||||
, save_path(path)
|
, save_path(path)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
pimpl(const pimpl& x)
|
impl(const impl& x)
|
||||||
: thread_safe_storage(x.info.num_pieces())
|
: thread_safe_storage(x.info.num_pieces())
|
||||||
, info(x.info)
|
, info(x.info)
|
||||||
, save_path(x.save_path)
|
, save_path(x.save_path)
|
||||||
|
@ -1347,27 +1347,14 @@ namespace libtorrent {
|
||||||
};
|
};
|
||||||
|
|
||||||
storage::storage(const torrent_info& info, const fs::path& path)
|
storage::storage(const torrent_info& info, const fs::path& path)
|
||||||
: m_pimpl(new pimpl(info, path))
|
: m_pimpl(new impl(info, path))
|
||||||
{
|
{
|
||||||
assert(info.begin_files() != info.end_files());
|
assert(info.begin_files() != info.end_files());
|
||||||
}
|
}
|
||||||
|
|
||||||
storage::~storage()
|
|
||||||
{}
|
|
||||||
|
|
||||||
storage::storage(const storage& other)
|
|
||||||
: m_pimpl(new pimpl(*other.m_pimpl))
|
|
||||||
{}
|
|
||||||
|
|
||||||
void storage::swap(storage& other)
|
void storage::swap(storage& other)
|
||||||
{
|
{
|
||||||
std::swap(m_pimpl, other.m_pimpl);
|
m_pimpl.swap(other.m_pimpl);
|
||||||
}
|
|
||||||
|
|
||||||
void storage::operator=(const storage& other)
|
|
||||||
{
|
|
||||||
storage tmp(other);
|
|
||||||
tmp.swap(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
storage::size_type storage::read(
|
storage::size_type storage::read(
|
||||||
|
@ -1379,7 +1366,7 @@ namespace libtorrent {
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
slot_lock lock(*m_pimpl, slot);
|
slot_lock lock(*m_pimpl, slot);
|
||||||
|
|
||||||
size_type start = slot * m_pimpl->info.piece_length() + offset;
|
size_type start = slot * m_pimpl->info.piece_length() + offset;
|
||||||
|
|
||||||
// find the file iterator and file offset
|
// find the file iterator and file offset
|
||||||
|
@ -1534,42 +1521,136 @@ namespace libtorrent {
|
||||||
out.open(path, std::ios_base::binary);
|
out.open(path, std::ios_base::binary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
piece_manager::piece_manager(
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -- piece_manager -----------------------------------------------------
|
||||||
|
|
||||||
|
class piece_manager::impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef entry::integer_type size_type;
|
||||||
|
|
||||||
|
impl(
|
||||||
|
const torrent_info& info
|
||||||
|
, const boost::filesystem::path& path);
|
||||||
|
|
||||||
|
void check_pieces(
|
||||||
|
boost::mutex& mutex
|
||||||
|
, detail::piece_checker_data& data
|
||||||
|
, std::vector<bool>& pieces);
|
||||||
|
|
||||||
|
void allocate_slots(int num_slots);
|
||||||
|
|
||||||
|
size_type read(char* buf, int piece_index, size_type offset, size_type size);
|
||||||
|
void write(const char* buf, int piece_index, size_type offset, size_type size);
|
||||||
|
|
||||||
|
const boost::filesystem::path& save_path() const
|
||||||
|
{ return m_save_path; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// returns the slot currently associated with the given
|
||||||
|
// piece or assigns the given piece_index to a free slot
|
||||||
|
int slot_for_piece(int piece_index);
|
||||||
|
|
||||||
|
void check_invariant() const;
|
||||||
|
void debug_log() const;
|
||||||
|
|
||||||
|
storage m_storage;
|
||||||
|
|
||||||
|
// total number of bytes left to be downloaded
|
||||||
|
size_type m_bytes_left;
|
||||||
|
|
||||||
|
// a bitmask representing the pieces we have
|
||||||
|
std::vector<bool> m_have_piece;
|
||||||
|
|
||||||
|
const torrent_info& m_info;
|
||||||
|
|
||||||
|
// maps piece index to slot index. -1 means the piece
|
||||||
|
// doesn't exist
|
||||||
|
std::vector<int> m_piece_to_slot;
|
||||||
|
// slots that hasn't had any file storage allocated
|
||||||
|
std::vector<int> m_unallocated_slots;
|
||||||
|
// slots that has file storage, but isn't assigned to a piece
|
||||||
|
std::vector<int> m_free_slots;
|
||||||
|
|
||||||
|
// index here is a slot number in the file
|
||||||
|
// -1 : the slot is unallocated
|
||||||
|
// -2 : the slot is allocated but not assigned to a piece
|
||||||
|
// * : the slot is assigned to this piece
|
||||||
|
std::vector<int> m_slot_to_piece;
|
||||||
|
|
||||||
|
boost::filesystem::path m_save_path;
|
||||||
|
|
||||||
|
mutable boost::recursive_mutex m_mutex;
|
||||||
|
|
||||||
|
bool m_allocating;
|
||||||
|
boost::mutex m_allocating_monitor;
|
||||||
|
boost::condition m_allocating_condition;
|
||||||
|
};
|
||||||
|
|
||||||
|
piece_manager::impl::impl(
|
||||||
const torrent_info& info
|
const torrent_info& info
|
||||||
, const fs::path& save_path)
|
, const fs::path& save_path)
|
||||||
: m_storage(info, save_path)
|
: m_storage(info, save_path)
|
||||||
, m_info(info)
|
, m_info(info)
|
||||||
, m_save_path(save_path)
|
, m_save_path(save_path)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
piece_manager::size_type piece_manager::read(
|
piece_manager::piece_manager(
|
||||||
|
const torrent_info& info
|
||||||
|
, const fs::path& save_path)
|
||||||
|
: m_pimpl(new impl(info, save_path))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
piece_manager::size_type piece_manager::impl::read(
|
||||||
char* buf
|
char* buf
|
||||||
, int piece_index
|
, int piece_index
|
||||||
, piece_manager::size_type offset
|
, piece_manager::size_type offset
|
||||||
, piece_manager::size_type size)
|
, piece_manager::size_type size)
|
||||||
{
|
{
|
||||||
assert(m_piece_to_slot[piece_index] >= 0);
|
assert(m_piece_to_slot[piece_index] >= 0);
|
||||||
int slot = m_piece_to_slot[piece_index];
|
int slot = m_piece_to_slot[piece_index];
|
||||||
return m_storage.read(buf, slot, offset, size);
|
return m_storage.read(buf, slot, offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_manager::write(
|
piece_manager::size_type piece_manager::read(
|
||||||
|
char* buf
|
||||||
|
, int piece_index
|
||||||
|
, piece_manager::size_type offset
|
||||||
|
, piece_manager::size_type size)
|
||||||
|
{
|
||||||
|
return m_pimpl->read(buf, piece_index, offset, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void piece_manager::impl::write(
|
||||||
const char* buf
|
const char* buf
|
||||||
, int piece_index
|
, int piece_index
|
||||||
, piece_manager::size_type offset
|
, piece_manager::size_type offset
|
||||||
, piece_manager::size_type size)
|
, piece_manager::size_type size)
|
||||||
{
|
{
|
||||||
int slot = slot_for_piece(piece_index);
|
int slot = slot_for_piece(piece_index);
|
||||||
m_storage.write(buf, slot, offset, size);
|
m_storage.write(buf, slot, offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_manager::check_pieces(
|
void piece_manager::write(
|
||||||
|
const char* buf
|
||||||
|
, int piece_index
|
||||||
|
, piece_manager::size_type offset
|
||||||
|
, piece_manager::size_type size)
|
||||||
|
{
|
||||||
|
m_pimpl->write(buf, piece_index, offset, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void piece_manager::impl::check_pieces(
|
||||||
boost::mutex& mutex
|
boost::mutex& mutex
|
||||||
, detail::piece_checker_data& data
|
, detail::piece_checker_data& data
|
||||||
, std::vector<bool>& pieces)
|
, std::vector<bool>& pieces)
|
||||||
{
|
{
|
||||||
// synchronization ------------------------------------------------------
|
// synchronization ------------------------------------------------------
|
||||||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||||
|
@ -1774,7 +1855,15 @@ namespace libtorrent {
|
||||||
check_invariant();
|
check_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
int piece_manager::slot_for_piece(int piece_index)
|
void piece_manager::check_pieces(
|
||||||
|
boost::mutex& mutex
|
||||||
|
, detail::piece_checker_data& data
|
||||||
|
, std::vector<bool>& pieces)
|
||||||
|
{
|
||||||
|
m_pimpl->check_pieces(mutex, data, pieces);
|
||||||
|
}
|
||||||
|
|
||||||
|
int piece_manager::impl::slot_for_piece(int piece_index)
|
||||||
{
|
{
|
||||||
// synchronization ------------------------------------------------------
|
// synchronization ------------------------------------------------------
|
||||||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||||
|
@ -1873,8 +1962,13 @@ namespace libtorrent {
|
||||||
|
|
||||||
return slot_index;
|
return slot_index;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void piece_manager::allocate_slots(int num_slots)
|
int piece_manager::slot_for_piece(int piece_index)
|
||||||
|
{
|
||||||
|
return m_pimpl->slot_for_piece(piece_index);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void piece_manager::impl::allocate_slots(int num_slots)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_allocating_monitor);
|
boost::mutex::scoped_lock lock(m_allocating_monitor);
|
||||||
|
@ -1933,8 +2027,18 @@ namespace libtorrent {
|
||||||
|
|
||||||
check_invariant();
|
check_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void piece_manager::allocate_slots(int num_slots)
|
||||||
|
{
|
||||||
|
m_pimpl->allocate_slots(num_slots);
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& piece_manager::save_path() const
|
||||||
|
{
|
||||||
|
return m_pimpl->save_path();
|
||||||
|
}
|
||||||
|
|
||||||
void piece_manager::check_invariant() const
|
void piece_manager::impl::check_invariant() const
|
||||||
{
|
{
|
||||||
// synchronization ------------------------------------------------------
|
// synchronization ------------------------------------------------------
|
||||||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||||
|
@ -1947,7 +2051,7 @@ namespace libtorrent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_manager::debug_log() const
|
void piece_manager::impl::debug_log() const
|
||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue