Adding hash check queue.

git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@278 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2005-02-15 15:37:06 +00:00
parent ce4c09c143
commit f348196f2e
9 changed files with 160 additions and 22 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
SUBDIRS = src
EXTRA_DIST= \
autogen.sh
autogen.sh \
scripts/checks.m4
+2
View File
@@ -5,6 +5,8 @@ libsub_core_a_SOURCES = \
curl_get.h \
curl_stack.cc \
curl_stack.h \
hash_queue.cc \
hash_queue.h \
http_queue.cc \
http_queue.h \
download.cc \
+1 -2
View File
@@ -19,10 +19,9 @@ public:
void open() { m_download.open(); }
void close() { m_download.close(); }
void start() { m_download.start(); }
void stop() { m_download.stop(); }
void hash_check(bool resume = false) { m_download.hash_check(resume); }
bool operator == (const std::string& str) { return str == m_download.get_hash(); }
private:
-12
View File
@@ -17,8 +17,6 @@ DownloadList::insert(std::istream* str) {
iterator itr = Base::insert(end(), Download());
itr->set_download(d);
itr->get_download().signal_hash_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_hash_done),
itr->get_hash()));
return itr;
}
@@ -32,14 +30,4 @@ DownloadList::erase(iterator itr) {
Base::erase(itr);
}
void
DownloadList::receive_hash_done(const std::string& str) {
iterator itr = std::find(begin(), end(), str);
if (itr == end())
throw torrent::client_error("DownloadList received hash check done, but couldn't find the download");
itr->get_download().start();
}
}
-3
View File
@@ -26,9 +26,6 @@ public:
iterator insert(std::istream* str);
void erase(iterator itr);
private:
void receive_hash_done(const std::string& str);
};
}
+68
View File
@@ -0,0 +1,68 @@
#include "config.h"
#include <algorithm>
#include <stdexcept>
#include <sigc++/bind.h>
#include "download.h"
#include "functional.h"
#include "hash_queue.h"
namespace core {
void
HashQueue::insert(Download* d, Slot s) {
if (std::find_if(begin(), end(), func::equal(d, std::mem_fun(&HashQueueNode::get_download))) != end())
throw std::logic_error("core::HashQueue::insert(...) received a Download that is already queued");
if (d->get_download().is_hash_checked()) {
s();
return;
}
iterator itr = Base::insert(end(), new HashQueueNode(d, s));
(*itr)->set_connection(d->get_download().signal_hash_done(sigc::bind(sigc::mem_fun(*this, &HashQueue::receive_hash_done), itr)));
fill_queue();
}
void
HashQueue::remove(Download* d) {
iterator itr = std::find_if(begin(), end(), func::equal(d, std::mem_fun(&HashQueueNode::get_download)));
if (itr == end())
return;
if ((*itr)->get_download()->get_download().is_hash_checking())
// What do we do if we're already checking?
;
delete *itr;
Base::erase(itr);
fill_queue();
}
void
HashQueue::receive_hash_done(Base::iterator itr) {
Slot s = (*itr)->get_slot();
delete *itr;
Base::erase(itr);
s();
}
void
HashQueue::fill_queue() {
if (empty() || front()->get_download()->get_download().is_hash_checking())
return;
if (front()->get_download()->get_download().is_hash_checked())
throw std::logic_error("core::HashQueue::fill_queue() encountered a checked hash");
front()->get_download()->get_download().hash_check();
}
}
+65
View File
@@ -0,0 +1,65 @@
#ifndef RTORRENT_CORE_HASH_QUEUE_H
#define RTORRENT_CORE_HASH_QUEUE_H
#include <list>
#include <sigc++/slot.h>
#include <sigc++/connection.h>
namespace core {
class Download;
class HashQueueNode;
class HashQueue : private std::list<HashQueueNode*> {
public:
typedef std::list<HashQueueNode*> Base;
typedef sigc::slot0<void> Slot;
using Base::iterator;
using Base::const_iterator;
using Base::reverse_iterator;
using Base::const_reverse_iterator;
using Base::begin;
using Base::end;
using Base::rbegin;
using Base::rend;
using Base::front;
using Base::back;
using Base::empty;
using Base::size;
// Should it be safe to try inserting already present/checked downloads?
void insert(Download* d, Slot s);
// It's safe to try to remove downloads not in the queue.
void remove(Download* d);
private:
void receive_hash_done(Base::iterator itr);
void fill_queue();
};
class HashQueueNode {
public:
HashQueueNode(Download* d, HashQueue::Slot s) : m_download(d), m_slot(s) {}
~HashQueueNode() { m_connection.disconnect(); }
Download* get_download() { return m_download; }
HashQueue::Slot get_slot() { return m_slot; }
void set_connection(sigc::connection c) { m_connection = c; }
private:
Download* m_download;
HashQueue::Slot m_slot;
sigc::connection m_connection;
};
}
#endif
+17 -4
View File
@@ -19,6 +19,21 @@ Manager::insert(const std::string& uri) {
create_http(uri);
}
void
Manager::start(Download* d) {
if (d->get_download().is_active())
return;
if (d->get_download().is_open()) {
d->start();
} else {
d->open();
m_hashQueue.insert(d, sigc::mem_fun(*d, &Download::start));
}
}
void
Manager::create_file(const std::string& uri) {
DownloadList::iterator itr = m_downloadList.end();
@@ -28,8 +43,7 @@ Manager::create_file(const std::string& uri) {
itr = m_downloadList.insert(&f);
itr->open();
itr->hash_check();
start(&*itr);
} catch (torrent::local_error& e) {
// What to do? Keep in list for now.
@@ -51,8 +65,7 @@ Manager::receive_http_done(torrent::Http* http) {
try {
itr = m_downloadList.insert(http->get_stream());
itr->open();
itr->hash_check();
start(&*itr);
} catch (torrent::local_error& e) {
// What to do? Keep in list for now.
+5
View File
@@ -2,6 +2,7 @@
#define RTORRENT_CORE_MANAGER_H
#include "download_list.h"
#include "hash_queue.h"
#include "http_queue.h"
namespace core {
@@ -12,10 +13,13 @@ public:
typedef sigc::slot0<void> SlotFailed;
DownloadList& get_download_list() { return m_downloadList; }
HashQueue& get_hash_queue() { return m_hashQueue; }
HttpQueue& get_http_queue() { return m_httpQueue; }
void insert(const std::string& uri);
void start(Download* d);
private:
void receive_http_done(torrent::Http* http);
@@ -23,6 +27,7 @@ private:
void create_http(const std::string& uri);
DownloadList m_downloadList;
HashQueue m_hashQueue;
HttpQueue m_httpQueue;
};