2003-10-23 01:00:57 +02:00
|
|
|
/*
|
|
|
|
|
|
|
|
Copyright (c) 2003, 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_STORAGE_HPP_INCLUDE
|
|
|
|
#define TORRENT_STORAGE_HPP_INCLUDE
|
2003-12-10 01:39:47 +01:00
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
#include <vector>
|
2009-10-26 02:29:39 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2004-01-25 19:18:36 +01:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma warning(push, 1)
|
|
|
|
#endif
|
|
|
|
|
2009-11-23 09:38:50 +01:00
|
|
|
#include <boost/function/function2.hpp>
|
2003-10-23 01:00:57 +02:00
|
|
|
#include <boost/limits.hpp>
|
2004-04-14 14:14:28 +02:00
|
|
|
#include <boost/shared_ptr.hpp>
|
2009-11-23 09:38:50 +01:00
|
|
|
#include <boost/scoped_ptr.hpp>
|
2007-09-01 05:00:31 +02:00
|
|
|
#include <boost/intrusive_ptr.hpp>
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2004-01-25 19:18:36 +01:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma warning(pop)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2003-10-23 01:00:57 +02:00
|
|
|
#include "libtorrent/torrent_info.hpp"
|
2007-05-08 13:13:13 +02:00
|
|
|
#include "libtorrent/piece_picker.hpp"
|
2007-06-10 22:46:09 +02:00
|
|
|
#include "libtorrent/intrusive_ptr_base.hpp"
|
|
|
|
#include "libtorrent/peer_request.hpp"
|
|
|
|
#include "libtorrent/hasher.hpp"
|
2005-11-01 19:30:39 +01:00
|
|
|
#include "libtorrent/config.hpp"
|
2009-01-03 09:11:31 +01:00
|
|
|
#include "libtorrent/file.hpp"
|
2009-01-11 03:02:34 +01:00
|
|
|
#include "libtorrent/disk_buffer_holder.hpp"
|
2009-10-20 04:49:56 +02:00
|
|
|
#include "libtorrent/thread.hpp"
|
2009-11-23 09:38:50 +01:00
|
|
|
#include "libtorrent/storage_defs.hpp"
|
2003-10-23 01:00:57 +02:00
|
|
|
|
|
|
|
namespace libtorrent
|
|
|
|
{
|
|
|
|
class session;
|
2006-11-15 22:39:58 +01:00
|
|
|
struct file_pool;
|
2007-06-10 22:46:09 +02:00
|
|
|
struct disk_io_job;
|
2009-01-21 08:31:49 +01:00
|
|
|
struct disk_buffer_pool;
|
2003-10-23 01:00:57 +02:00
|
|
|
|
2005-11-01 19:30:39 +01:00
|
|
|
TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes(
|
2008-05-28 10:44:40 +02:00
|
|
|
file_storage const& t
|
2009-10-26 02:29:39 +01:00
|
|
|
, std::string const& p);
|
2004-01-17 21:04:19 +01:00
|
|
|
|
2005-11-01 19:30:39 +01:00
|
|
|
TORRENT_EXPORT bool match_filesizes(
|
2008-05-28 10:44:40 +02:00
|
|
|
file_storage const& t
|
2009-10-26 02:29:39 +01:00
|
|
|
, std::string const& p
|
2005-06-16 17:41:04 +02:00
|
|
|
, std::vector<std::pair<size_type, std::time_t> > const& sizes
|
2007-05-24 20:53:55 +02:00
|
|
|
, bool compact_mode
|
2005-06-16 17:41:04 +02:00
|
|
|
, std::string* error = 0);
|
2004-01-17 21:04:19 +01:00
|
|
|
|
2005-11-01 19:30:39 +01:00
|
|
|
struct TORRENT_EXPORT file_allocation_failed: std::exception
|
2003-10-23 01:00:57 +02:00
|
|
|
{
|
|
|
|
file_allocation_failed(const char* error_msg): m_msg(error_msg) {}
|
|
|
|
virtual const char* what() const throw() { return m_msg.c_str(); }
|
2004-01-13 04:08:59 +01:00
|
|
|
virtual ~file_allocation_failed() throw() {}
|
2003-10-23 01:00:57 +02:00
|
|
|
std::string m_msg;
|
|
|
|
};
|
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
struct TORRENT_EXPORT partial_hash
|
|
|
|
{
|
|
|
|
partial_hash(): offset(0) {}
|
|
|
|
// the number of bytes in the piece that has been hashed
|
|
|
|
int offset;
|
|
|
|
// the sha-1 context
|
|
|
|
hasher h;
|
|
|
|
};
|
|
|
|
|
2007-03-16 06:29:23 +01:00
|
|
|
struct TORRENT_EXPORT storage_interface
|
2003-12-07 02:26:57 +01:00
|
|
|
{
|
2009-01-21 08:31:49 +01:00
|
|
|
storage_interface(): m_disk_pool(0), m_settings(0) {}
|
2007-04-19 05:06:15 +02:00
|
|
|
// create directories and set file sizes
|
2007-04-19 05:32:20 +02:00
|
|
|
// if allocate_files is true.
|
|
|
|
// allocate_files is true if allocation mode
|
|
|
|
// is set to full and sparse files are supported
|
2008-03-08 07:06:31 +01:00
|
|
|
// false return value indicates an error
|
2008-02-14 04:48:20 +01:00
|
|
|
virtual bool initialize(bool allocate_files) = 0;
|
2007-04-19 05:06:15 +02:00
|
|
|
|
2009-04-10 09:22:27 +02:00
|
|
|
virtual bool has_any_file() = 0;
|
|
|
|
|
2009-01-11 03:02:34 +01:00
|
|
|
virtual int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs);
|
|
|
|
virtual int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs);
|
2009-01-03 09:11:31 +01:00
|
|
|
|
2008-02-14 04:48:20 +01:00
|
|
|
// negative return value indicates an error
|
2008-04-05 23:18:27 +02:00
|
|
|
virtual int read(char* buf, int slot, int offset, int size) = 0;
|
2004-01-25 19:18:36 +01:00
|
|
|
|
2008-02-14 04:48:20 +01:00
|
|
|
// negative return value indicates an error
|
2008-04-05 23:18:27 +02:00
|
|
|
virtual int write(const char* buf, int slot, int offset, int size) = 0;
|
2003-12-07 02:26:57 +01:00
|
|
|
|
2009-09-05 09:21:10 +02:00
|
|
|
virtual size_type physical_offset(int slot, int offset) = 0;
|
|
|
|
|
2009-02-17 01:11:38 +01:00
|
|
|
// returns the end of the sparse region the slot 'start'
|
|
|
|
// resides in i.e. the next slot with content. If start
|
|
|
|
// is not in a sparse region, start itself is returned
|
|
|
|
virtual int sparse_end(int start) const { return start; }
|
|
|
|
|
2008-02-14 04:48:20 +01:00
|
|
|
// non-zero return value indicates an error
|
2009-10-26 02:29:39 +01:00
|
|
|
virtual bool move_storage(std::string const& save_path) = 0;
|
2004-07-18 02:39:58 +02:00
|
|
|
|
2007-05-24 20:53:55 +02:00
|
|
|
// verify storage dependent fast resume entries
|
2009-06-28 02:36:41 +02:00
|
|
|
virtual bool verify_resume_data(lazy_entry const& rd, error_code& error) = 0;
|
2007-03-28 01:49:05 +02:00
|
|
|
|
2007-05-24 20:53:55 +02:00
|
|
|
// write storage dependent fast resume entries
|
2008-02-14 04:48:20 +01:00
|
|
|
virtual bool write_resume_data(entry& rd) const = 0;
|
2007-05-24 20:53:55 +02:00
|
|
|
|
2007-05-16 03:16:08 +02:00
|
|
|
// moves (or copies) the content in src_slot to dst_slot
|
2008-02-14 04:48:20 +01:00
|
|
|
virtual bool move_slot(int src_slot, int dst_slot) = 0;
|
2007-04-30 03:06:29 +02:00
|
|
|
|
2007-05-16 03:16:08 +02:00
|
|
|
// swaps the data in slot1 and slot2
|
2008-02-14 04:48:20 +01:00
|
|
|
virtual bool swap_slots(int slot1, int slot2) = 0;
|
2007-05-16 03:16:08 +02:00
|
|
|
|
|
|
|
// swaps the puts the data in slot1 in slot2, the data in slot2
|
|
|
|
// in slot3 and the data in slot3 in slot1
|
2008-02-14 04:48:20 +01:00
|
|
|
virtual bool swap_slots3(int slot1, int slot2, int slot3) = 0;
|
2007-05-16 03:16:08 +02:00
|
|
|
|
2004-12-21 13:30:09 +01:00
|
|
|
// this will close all open files that are opened for
|
|
|
|
// writing. This is called when a torrent has finished
|
|
|
|
// downloading.
|
2008-02-14 04:48:20 +01:00
|
|
|
// non-zero return value indicates an error
|
|
|
|
virtual bool release_files() = 0;
|
2007-10-13 05:33:33 +02:00
|
|
|
|
2008-05-28 10:44:40 +02:00
|
|
|
// this will rename the file specified by index.
|
|
|
|
virtual bool rename_file(int index, std::string const& new_filename) = 0;
|
|
|
|
|
2007-10-13 05:33:33 +02:00
|
|
|
// this will close all open files and delete them
|
2008-02-14 04:48:20 +01:00
|
|
|
// non-zero return value indicates an error
|
|
|
|
virtual bool delete_files() = 0;
|
|
|
|
|
2009-01-21 08:31:49 +01:00
|
|
|
disk_buffer_pool* disk_pool() { return m_disk_pool; }
|
|
|
|
session_settings const& settings() const { return *m_settings; }
|
2009-01-11 03:02:34 +01:00
|
|
|
|
2009-10-26 02:29:39 +01:00
|
|
|
void set_error(std::string const& file, error_code const& ec) const
|
2008-04-13 00:08:07 +02:00
|
|
|
{
|
2009-10-26 02:29:39 +01:00
|
|
|
m_error_file = file;
|
2008-07-18 01:41:46 +02:00
|
|
|
m_error = ec;
|
2008-04-13 00:08:07 +02:00
|
|
|
}
|
|
|
|
|
2008-07-18 01:41:46 +02:00
|
|
|
error_code const& error() const { return m_error; }
|
2008-04-13 00:08:07 +02:00
|
|
|
std::string const& error_file() const { return m_error_file; }
|
2009-11-28 23:41:21 +01:00
|
|
|
void clear_error() { m_error = error_code(); m_error_file.resize(0); }
|
2008-04-13 00:08:07 +02:00
|
|
|
|
2008-07-18 01:41:46 +02:00
|
|
|
mutable error_code m_error;
|
2008-04-13 00:08:07 +02:00
|
|
|
mutable std::string m_error_file;
|
2007-10-13 05:33:33 +02:00
|
|
|
|
2007-03-16 06:29:23 +01:00
|
|
|
virtual ~storage_interface() {}
|
2009-01-11 03:02:34 +01:00
|
|
|
|
2009-01-21 08:31:49 +01:00
|
|
|
disk_buffer_pool* m_disk_pool;
|
|
|
|
session_settings* m_settings;
|
2007-03-16 06:29:23 +01:00
|
|
|
};
|
2004-12-21 13:30:09 +01:00
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
struct disk_io_thread;
|
2007-04-18 02:36:09 +02:00
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
class TORRENT_EXPORT piece_manager
|
|
|
|
: public intrusive_ptr_base<piece_manager>
|
|
|
|
, boost::noncopyable
|
2003-11-26 15:11:25 +01:00
|
|
|
{
|
2007-06-10 22:46:09 +02:00
|
|
|
friend class invariant_access;
|
|
|
|
friend struct disk_io_thread;
|
2003-11-26 15:11:25 +01:00
|
|
|
public:
|
2003-12-07 02:26:57 +01:00
|
|
|
|
|
|
|
piece_manager(
|
2007-06-10 22:46:09 +02:00
|
|
|
boost::shared_ptr<void> const& torrent
|
2008-05-28 10:44:40 +02:00
|
|
|
, boost::intrusive_ptr<torrent_info const> info
|
2009-10-26 02:29:39 +01:00
|
|
|
, std::string const& path
|
2007-03-16 06:29:23 +01:00
|
|
|
, file_pool& fp
|
2007-06-10 22:46:09 +02:00
|
|
|
, disk_io_thread& io
|
2008-03-08 07:06:31 +01:00
|
|
|
, storage_constructor_type sc
|
|
|
|
, storage_mode_t sm);
|
2003-12-07 02:26:57 +01:00
|
|
|
|
2004-01-04 13:54:38 +01:00
|
|
|
~piece_manager();
|
|
|
|
|
2008-05-28 10:44:40 +02:00
|
|
|
boost::intrusive_ptr<torrent_info const> info() const { return m_info; }
|
2008-04-13 20:54:36 +02:00
|
|
|
void write_resume_data(entry& rd) const;
|
2007-06-10 22:46:09 +02:00
|
|
|
|
2008-07-01 01:14:31 +02:00
|
|
|
void async_check_fastresume(lazy_entry const* resume_data
|
2008-03-08 07:06:31 +01:00
|
|
|
, boost::function<void(int, disk_io_job const&)> const& handler);
|
2007-10-08 22:01:36 +02:00
|
|
|
|
2008-03-08 07:06:31 +01:00
|
|
|
void async_check_files(boost::function<void(int, disk_io_job const&)> const& handler);
|
|
|
|
|
2009-06-10 10:30:55 +02:00
|
|
|
int queued_bytes() const;
|
|
|
|
|
2008-05-28 10:44:40 +02:00
|
|
|
void async_rename_file(int index, std::string const& name
|
|
|
|
, boost::function<void(int, disk_io_job const&)> const& handler);
|
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
void async_read(
|
|
|
|
peer_request const& r
|
2007-09-11 19:45:20 +02:00
|
|
|
, boost::function<void(int, disk_io_job const&)> const& handler
|
2007-09-16 03:34:06 +02:00
|
|
|
, int priority = 0);
|
2007-06-10 22:46:09 +02:00
|
|
|
|
2009-02-03 08:46:24 +01:00
|
|
|
void async_read_and_hash(
|
|
|
|
peer_request const& r
|
|
|
|
, boost::function<void(int, disk_io_job const&)> const& handler
|
|
|
|
, int priority = 0);
|
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
void async_write(
|
|
|
|
peer_request const& r
|
2008-04-10 12:03:23 +02:00
|
|
|
, disk_buffer_holder& buffer
|
2007-06-10 22:46:09 +02:00
|
|
|
, boost::function<void(int, disk_io_job const&)> const& f);
|
|
|
|
|
|
|
|
void async_hash(int piece, boost::function<void(int, disk_io_job const&)> const& f);
|
|
|
|
|
2007-06-11 23:24:14 +02:00
|
|
|
void async_release_files(
|
2007-07-02 21:31:46 +02:00
|
|
|
boost::function<void(int, disk_io_job const&)> const& handler
|
|
|
|
= boost::function<void(int, disk_io_job const&)>());
|
|
|
|
|
2008-11-17 02:19:46 +01:00
|
|
|
void abort_disk_io();
|
|
|
|
|
2008-07-18 17:31:22 +02:00
|
|
|
void async_clear_read_cache(
|
|
|
|
boost::function<void(int, disk_io_job const&)> const& handler
|
|
|
|
= boost::function<void(int, disk_io_job const&)>());
|
|
|
|
|
2007-10-13 05:33:33 +02:00
|
|
|
void async_delete_files(
|
|
|
|
boost::function<void(int, disk_io_job const&)> const& handler
|
|
|
|
= boost::function<void(int, disk_io_job const&)>());
|
|
|
|
|
2009-10-26 02:29:39 +01:00
|
|
|
void async_move_storage(std::string const& p
|
2007-06-11 23:24:14 +02:00
|
|
|
, boost::function<void(int, disk_io_job const&)> const& handler);
|
2007-06-10 22:46:09 +02:00
|
|
|
|
2008-04-13 20:54:36 +02:00
|
|
|
void async_save_resume_data(
|
|
|
|
boost::function<void(int, disk_io_job const&)> const& handler);
|
|
|
|
|
2008-03-08 07:06:31 +01:00
|
|
|
enum return_t
|
|
|
|
{
|
|
|
|
// return values from check_fastresume and check_files
|
|
|
|
no_error = 0,
|
|
|
|
need_full_check = -1,
|
|
|
|
fatal_disk_error = -2,
|
2008-06-09 06:46:34 +02:00
|
|
|
disk_check_aborted = -3
|
2008-03-08 07:06:31 +01:00
|
|
|
};
|
|
|
|
|
2008-09-04 18:20:19 +02:00
|
|
|
storage_interface* get_storage_impl() { return m_storage.get(); }
|
|
|
|
|
2008-03-08 07:06:31 +01:00
|
|
|
private:
|
|
|
|
|
2009-10-26 02:29:39 +01:00
|
|
|
std::string save_path() const;
|
2008-03-08 07:06:31 +01:00
|
|
|
|
2009-06-28 02:36:41 +02:00
|
|
|
bool verify_resume_data(lazy_entry const& rd, error_code& error)
|
2008-03-08 07:06:31 +01:00
|
|
|
{ return m_storage->verify_resume_data(rd, error); }
|
|
|
|
|
|
|
|
bool is_allocating() const
|
|
|
|
{ return m_state == state_expand_pieces; }
|
|
|
|
|
|
|
|
void mark_failed(int index);
|
|
|
|
|
2008-07-18 01:41:46 +02:00
|
|
|
error_code const& error() const { return m_storage->error(); }
|
2008-04-13 00:08:07 +02:00
|
|
|
std::string const& error_file() const { return m_storage->error_file(); }
|
2009-05-31 21:44:56 +02:00
|
|
|
int last_piece() const { return m_last_piece; }
|
2009-06-01 00:41:53 +02:00
|
|
|
int last_operation() const { return m_last_op; }
|
2008-03-08 07:06:31 +01:00
|
|
|
void clear_error() { m_storage->clear_error(); }
|
|
|
|
|
|
|
|
int slot_for(int piece) const;
|
|
|
|
int piece_for(int slot) const;
|
|
|
|
|
|
|
|
// helper functions for check_dastresume
|
2009-06-28 02:36:41 +02:00
|
|
|
int check_no_fastresume(error_code& error);
|
|
|
|
int check_init_storage(error_code& error);
|
2008-03-08 07:06:31 +01:00
|
|
|
|
|
|
|
// if error is set and return value is 'no_error' or 'need_full_check'
|
|
|
|
// the error message indicates that the fast resume data was rejected
|
|
|
|
// if 'fatal_disk_error' is returned, the error message indicates what
|
|
|
|
// when wrong in the disk access
|
2009-06-28 02:36:41 +02:00
|
|
|
int check_fastresume(lazy_entry const& rd, error_code& error);
|
2008-03-08 07:06:31 +01:00
|
|
|
|
|
|
|
// this function returns true if the checking is complete
|
2009-06-28 02:36:41 +02:00
|
|
|
int check_files(int& current_slot, int& have_piece, error_code& error);
|
2007-06-10 22:46:09 +02:00
|
|
|
|
|
|
|
bool compact_allocation() const
|
2007-10-08 22:01:36 +02:00
|
|
|
{ return m_storage_mode == storage_mode_compact; }
|
2007-06-10 22:46:09 +02:00
|
|
|
|
2008-11-29 22:33:21 +01:00
|
|
|
#ifdef TORRENT_DEBUG
|
2007-09-01 05:00:31 +02:00
|
|
|
std::string name() const { return m_info->name(); }
|
2007-06-10 22:46:09 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
bool allocate_slots(int num_slots, bool abort_on_disk = false);
|
|
|
|
|
2009-05-21 18:15:05 +02:00
|
|
|
// updates the ph.h hasher object with the data at the given slot
|
|
|
|
// and optionally a 'small hash' as well, the hash for
|
|
|
|
// the partial slot. Returns the number of bytes read
|
|
|
|
int hash_for_slot(int slot, partial_hash& h, int piece_size
|
|
|
|
, int small_piece_size = 0, sha1_hash* small_hash = 0);
|
|
|
|
|
2008-04-05 23:18:27 +02:00
|
|
|
int read_impl(
|
2009-01-03 09:11:31 +01:00
|
|
|
file::iovec_t* bufs
|
2004-01-25 19:18:36 +01:00
|
|
|
, int piece_index
|
|
|
|
, int offset
|
2009-01-03 09:11:31 +01:00
|
|
|
, int num_bufs);
|
2004-01-25 19:18:36 +01:00
|
|
|
|
2008-04-05 23:18:27 +02:00
|
|
|
int write_impl(
|
2009-01-03 09:11:31 +01:00
|
|
|
file::iovec_t* bufs
|
2004-01-25 19:18:36 +01:00
|
|
|
, int piece_index
|
|
|
|
, int offset
|
2009-01-03 09:11:31 +01:00
|
|
|
, int num_bufs);
|
2003-12-07 06:53:04 +01:00
|
|
|
|
2009-09-05 09:21:10 +02:00
|
|
|
size_type physical_offset(int piece_index, int offset);
|
|
|
|
|
2009-02-14 05:31:08 +01:00
|
|
|
// returns the number of pieces left in the
|
|
|
|
// file currently being checked
|
|
|
|
int skip_file() const;
|
|
|
|
// -1=error 0=ok >0=skip this many pieces
|
2008-07-18 01:41:46 +02:00
|
|
|
int check_one_piece(int& have_piece);
|
2008-03-08 07:06:31 +01:00
|
|
|
int identify_data(
|
2009-05-21 18:15:05 +02:00
|
|
|
sha1_hash const& large_hash
|
|
|
|
, sha1_hash const& small_hash
|
2008-03-08 07:06:31 +01:00
|
|
|
, int current_slot);
|
2008-02-14 04:48:20 +01:00
|
|
|
|
2007-10-08 22:01:36 +02:00
|
|
|
void switch_to_full_mode();
|
2007-06-10 22:46:09 +02:00
|
|
|
sha1_hash hash_for_piece_impl(int piece);
|
2003-11-26 15:11:25 +01:00
|
|
|
|
2008-02-14 04:48:20 +01:00
|
|
|
int release_files_impl() { return m_storage->release_files(); }
|
|
|
|
int delete_files_impl() { return m_storage->delete_files(); }
|
2008-05-28 10:44:40 +02:00
|
|
|
int rename_file_impl(int index, std::string const& new_filename)
|
|
|
|
{ return m_storage->rename_file(index, new_filename); }
|
2003-12-25 13:11:31 +01:00
|
|
|
|
2009-10-26 02:29:39 +01:00
|
|
|
int move_storage_impl(std::string const& save_path);
|
2007-04-17 23:54:40 +02:00
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
int allocate_slot_for_piece(int piece_index);
|
2008-11-29 22:33:21 +01:00
|
|
|
#ifdef TORRENT_DEBUG
|
2007-06-10 22:46:09 +02:00
|
|
|
void check_invariant() const;
|
|
|
|
#ifdef TORRENT_STORAGE_DEBUG
|
|
|
|
void debug_log() const;
|
|
|
|
#endif
|
|
|
|
#endif
|
2008-05-28 10:44:40 +02:00
|
|
|
boost::intrusive_ptr<torrent_info const> m_info;
|
|
|
|
file_storage const& m_files;
|
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
boost::scoped_ptr<storage_interface> m_storage;
|
|
|
|
|
2007-10-08 22:01:36 +02:00
|
|
|
storage_mode_t m_storage_mode;
|
2007-06-10 22:46:09 +02:00
|
|
|
|
|
|
|
// slots that haven't had any file storage allocated
|
|
|
|
std::vector<int> m_unallocated_slots;
|
|
|
|
// slots that have file storage, but isn't assigned to a piece
|
|
|
|
std::vector<int> m_free_slots;
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
has_no_slot = -3 // the piece has no storage
|
|
|
|
};
|
|
|
|
|
|
|
|
// maps piece indices to slots. If a piece doesn't
|
|
|
|
// have any storage, it is set to 'has_no_slot'
|
|
|
|
std::vector<int> m_piece_to_slot;
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
unallocated = -1, // the slot is unallocated
|
|
|
|
unassigned = -2 // the slot is allocated but not assigned to a piece
|
|
|
|
};
|
|
|
|
|
|
|
|
// maps slots to piece indices, if a slot doesn't have a piece
|
|
|
|
// it can either be 'unassigned' or 'unallocated'
|
|
|
|
std::vector<int> m_slot_to_piece;
|
|
|
|
|
2009-10-26 02:29:39 +01:00
|
|
|
std::string m_save_path;
|
2007-06-10 22:46:09 +02:00
|
|
|
|
2009-10-20 04:49:56 +02:00
|
|
|
mutable mutex m_mutex;
|
2007-06-10 22:46:09 +02:00
|
|
|
|
|
|
|
enum {
|
|
|
|
// the default initial state
|
|
|
|
state_none,
|
|
|
|
// the file checking is complete
|
|
|
|
state_finished,
|
|
|
|
// checking the files
|
|
|
|
state_full_check,
|
2007-10-08 22:01:36 +02:00
|
|
|
// move pieces to their final position
|
|
|
|
state_expand_pieces
|
2007-06-10 22:46:09 +02:00
|
|
|
} m_state;
|
|
|
|
int m_current_slot;
|
2007-10-08 22:01:36 +02:00
|
|
|
// used during check. If any piece is found
|
|
|
|
// that is not in its final position, this
|
|
|
|
// is set to true
|
|
|
|
bool m_out_of_place;
|
|
|
|
// used to move pieces while expanding
|
|
|
|
// the storage from compact allocation
|
|
|
|
// to full allocation
|
2009-01-11 03:02:34 +01:00
|
|
|
disk_buffer_holder m_scratch_buffer;
|
|
|
|
disk_buffer_holder m_scratch_buffer2;
|
2007-10-08 22:01:36 +02:00
|
|
|
// the piece that is in the scratch buffer
|
|
|
|
int m_scratch_piece;
|
2009-05-31 21:44:56 +02:00
|
|
|
|
|
|
|
// the last piece we wrote to or read from
|
|
|
|
int m_last_piece;
|
|
|
|
|
2009-06-01 00:41:53 +02:00
|
|
|
// the last operation we did (read or write)
|
|
|
|
int m_last_op;
|
|
|
|
|
2007-09-01 05:00:31 +02:00
|
|
|
// this is saved in case we need to instantiate a new
|
|
|
|
// storage (osed when remapping files)
|
|
|
|
storage_constructor_type m_storage_constructor;
|
|
|
|
|
2007-06-10 22:46:09 +02:00
|
|
|
// this maps a piece hash to piece index. It will be
|
|
|
|
// build the first time it is used (to save time if it
|
2009-05-31 21:44:56 +02:00
|
|
|
// isn't needed)
|
2007-06-10 22:46:09 +02:00
|
|
|
std::multimap<sha1_hash, int> m_hash_to_piece;
|
|
|
|
|
2007-09-01 05:00:31 +02:00
|
|
|
// this map contains partial hashes for downloading
|
2007-09-19 21:55:11 +02:00
|
|
|
// pieces. This is only accessed from within the
|
|
|
|
// disk-io thread.
|
2007-06-10 22:46:09 +02:00
|
|
|
std::map<int, partial_hash> m_piece_hasher;
|
|
|
|
|
|
|
|
disk_io_thread& m_io_thread;
|
|
|
|
|
|
|
|
// the reason for this to be a void pointer
|
|
|
|
// is to avoid creating a dependency on the
|
|
|
|
// torrent. This shared_ptr is here only
|
|
|
|
// to keep the torrent object alive until
|
|
|
|
// the piece_manager destructs. This is because
|
|
|
|
// the torrent_info object is owned by the torrent.
|
|
|
|
boost::shared_ptr<void> m_torrent;
|
2003-10-23 01:00:57 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // TORRENT_STORAGE_HPP_INCLUDED
|
2003-11-26 15:11:25 +01:00
|
|
|
|