made storage pimpled

This commit is contained in:
Daniel Wallin 2003-12-09 08:49:49 +00:00
parent ef5a49b694
commit 22bfad216f
5 changed files with 157 additions and 65 deletions

View File

@ -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)
{ {

View File

@ -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>

View File

@ -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"

View File

@ -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;*/
}; };
} }

View File

@ -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;