From cc44fb175dca670a328a21aa57277b62592e9f8f Mon Sep 17 00:00:00 2001 From: rakshasa Date: Mon, 18 Dec 2006 08:24:01 +0000 Subject: [PATCH] * Cleaned up hash checking, and allow resuming stopped checks. * Fixed setting of TOS so it doesn't always set it to throughput. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@827 e378c898-3ddf-0310-93e7-cc216c733640 --- rak/functional_fun.h | 22 ++++++++++ rak/ranges.h | 101 +++++++++++++++++++++++++++---------------- src/core/manager.cc | 4 +- 3 files changed, 88 insertions(+), 39 deletions(-) diff --git a/rak/functional_fun.h b/rak/functional_fun.h index 7c48cdb8..93cc2243 100644 --- a/rak/functional_fun.h +++ b/rak/functional_fun.h @@ -210,6 +210,22 @@ private: const Arg1 m_arg1; }; +template +class mem_fn1_b2_t : public function_base1 { +public: + typedef Result (Object::*Func)(Arg1, Arg2); + + mem_fn1_b2_t(Object* object, Func func, const Arg2 arg2) : m_object(object), m_func(func), m_arg2(arg2) {} + virtual ~mem_fn1_b2_t() {} + + virtual Result operator () (const Arg1 arg1) { return (m_object->*m_func)(arg1, m_arg2); } + +private: + Object* m_object; + Func m_func; + const Arg2 m_arg2; +}; + template class ptr_fn0_b1_t : public function_base0 { public: @@ -325,6 +341,12 @@ bind_mem_fn(Object* object, Result (Object::*func)(Arg1), const Arg1 arg1) { return new mem_fn0_b1_t(object, func, arg1); } +template +inline function_base1* +bind2_mem_fn(Object* object, Result (Object::*func)(Arg1, Arg2), const Arg2 arg2) { + return new mem_fn1_b2_t(object, func, arg2); +} + template inline function_base0* bind_ptr_fn(Result (*func)(Arg1), const Arg1 arg1) { diff --git a/rak/ranges.h b/rak/ranges.h index f5581e37..3402a258 100644 --- a/rak/ranges.h +++ b/rak/ranges.h @@ -46,25 +46,28 @@ namespace rak { template class ranges : private std::vector > { public: - typedef std::vector > Base; - typedef typename Base::value_type value_type; - typedef typename Base::reference reference; - typedef typename Base::iterator iterator; - typedef typename Base::const_iterator const_iterator; - typedef typename Base::reverse_iterator reverse_iterator; + typedef std::vector > base_type; + typedef typename base_type::value_type value_type; + typedef typename base_type::reference reference; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::reverse_iterator reverse_iterator; - using Base::clear; - using Base::size; - using Base::begin; - using Base::end; - using Base::rbegin; - using Base::rend; + using base_type::clear; + using base_type::size; + using base_type::begin; + using base_type::end; + using base_type::rbegin; + using base_type::rend; + + using base_type::front; + using base_type::back; void insert(Type first, Type last) { insert(std::make_pair(first, last)); } -// void erase(Type first, Type last) { erase(std::make_pair(first, last)); } + void erase(Type first, Type last) { erase(std::make_pair(first, last)); } void insert(value_type r); -// void erase(value_type r); + void erase(value_type r); // Find the first ranges that has an end greater than index. iterator find(Type index); @@ -72,9 +75,6 @@ public: // Use find with no closest match. bool has(Type index) const; - -private: - void unify(iterator itr); }; template @@ -88,20 +88,54 @@ ranges::insert(value_type r) { if (first == end() || r.second < first->first) { // The new range is before the first, after the last or between // two ranges. - Base::insert(first, r); - return; - } - - first->first = std::min(r.first, first->first); - first->second = std::max(r.second, first->second); + base_type::insert(first, r); - unify(first); + } else { + first->first = std::min(r.first, first->first); + first->second = std::max(r.second, first->second); + + iterator last = std::find_if(first, end(), rak::less(first->second, rak::const_mem_ref(&value_type::second))); + + if (last != end() && first->second >= last->first) + first->second = (last++)->second; + + base_type::erase(first + 1, last); + } } -// template -// void -// ranges::erase(value_type r) { -// } +template +void +ranges::erase(value_type r) { + if (r.first >= r.second) + return; + + iterator first = std::find_if(begin(), end(), rak::less(r.first, rak::const_mem_ref(&value_type::second))); + iterator last = std::find_if(first, end(), rak::less(r.second, rak::const_mem_ref(&value_type::second))); + + if (first == end()) + return; + + if (first == last) { + + if (r.first > first->first) { + std::swap(first->first, r.second); + base_type::insert(first, value_type(r.second, r.first)); + + } else if (r.second > first->first) { + first->first = r.second; + } + + } else { + + if (r.first > first->first) + (first++)->second = r.first; + + if (last != end() && r.second > last->first) + last->first = r.second; + + base_type::erase(first, last); + } +} // Find the first ranges that has an end greater than index. template @@ -118,22 +152,13 @@ ranges::find(Type index) const { // Use find with no closest match. template -inline bool +bool ranges::has(Type index) const { const_iterator itr = find(index); return itr != end() && index >= itr->first; } -template -inline void -ranges::unify(iterator first) { - iterator last = std::find_if((first + 1), end(), rak::less(first->second, rak::const_mem_ref(&value_type::first))); - - first->second = std::max(first->second, (last - 1)->second); - Base::erase((first + 1), last); -} - } #endif diff --git a/src/core/manager.cc b/src/core/manager.cc index 9262631e..5c0fe48b 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -503,7 +503,9 @@ Manager::receive_hashing_changed() { if ((*itr)->is_hash_checked()) throw torrent::internal_error("core::Manager::receive_hashing_changed() hash already checked or checking."); - if ((*itr)->is_hash_failed() || (*itr)->variable()->get_value("hashing") != Download::variable_hashing_initial) + if ((*itr)->is_hash_failed() || + (*itr)->variable()->get_value("hashing") != Download::variable_hashing_initial || + (*itr)->download()->chunks_hashed() != 0) continue; m_downloadList->open_throw(*itr);