Christoph Jentzsch
10 years ago
20 changed files with 388 additions and 202 deletions
@ -1,5 +1,22 @@ |
|||
#include "RangeMask.h" |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
RangeMask::RangeMask() |
|||
{ |
|||
} |
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file RangeMask.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "RangeMask.h" |
|||
|
@ -0,0 +1,75 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file DownloadMan.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "DownloadMan.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
DownloadSub::DownloadSub(DownloadMan& _man): m_man(&_man) |
|||
{ |
|||
WriteGuard l(m_man->x_subs); |
|||
m_man->m_subs.insert(this); |
|||
} |
|||
|
|||
DownloadSub::~DownloadSub() |
|||
{ |
|||
if (m_man) |
|||
{ |
|||
WriteGuard l(m_man->x_subs); |
|||
m_man->m_subs.erase(this); |
|||
} |
|||
} |
|||
|
|||
h256Set DownloadSub::nextFetch(unsigned _n) |
|||
{ |
|||
Guard l(m_fetch); |
|||
|
|||
if (m_remaining.size()) |
|||
return m_remaining; |
|||
|
|||
m_asked.clear(); |
|||
m_indices.clear(); |
|||
m_remaining.clear(); |
|||
|
|||
if (!m_man) |
|||
return h256Set(); |
|||
|
|||
m_asked = (~(m_man->taken() + m_attempted)).lowest(_n); |
|||
if (m_asked.empty()) |
|||
m_asked = (~(m_man->taken(true) + m_attempted)).lowest(_n); |
|||
m_attempted += m_asked; |
|||
for (auto i: m_asked) |
|||
{ |
|||
auto x = m_man->m_chain[i]; |
|||
m_remaining.insert(x); |
|||
m_indices[x] = i; |
|||
} |
|||
return m_remaining; |
|||
} |
|||
|
|||
void DownloadSub::noteBlock(h256 _hash) |
|||
{ |
|||
Guard l(m_fetch); |
|||
if (m_man && m_indices.count(_hash)) |
|||
m_man->m_blocksGot += m_indices[_hash]; |
|||
m_remaining.erase(_hash); |
|||
} |
@ -0,0 +1,128 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file DownloadMan.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <map> |
|||
#include <vector> |
|||
#include <set> |
|||
#include <libdevcore/Guards.h> |
|||
#include <libdevcore/Worker.h> |
|||
#include <libdevcore/RangeMask.h> |
|||
#include <libdevcore/FixedHash.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
class DownloadMan; |
|||
|
|||
class DownloadSub |
|||
{ |
|||
friend class DownloadMan; |
|||
|
|||
public: |
|||
DownloadSub(DownloadMan& _man); |
|||
~DownloadSub(); |
|||
|
|||
/// Finished last fetch - grab the next bunch of block hashes to download.
|
|||
h256Set nextFetch(unsigned _n); |
|||
|
|||
/// Note that we've received a particular block.
|
|||
void noteBlock(h256 _hash); |
|||
|
|||
/// Nothing doing here.
|
|||
void doneFetch() { resetFetch(); } |
|||
|
|||
private: |
|||
void resetFetch() // Called by DownloadMan when we need to reset the download.
|
|||
{ |
|||
Guard l(m_fetch); |
|||
m_remaining.clear(); |
|||
m_indices.clear(); |
|||
m_asked.clear(); |
|||
m_attempted.clear(); |
|||
} |
|||
|
|||
DownloadMan* m_man = nullptr; |
|||
|
|||
Mutex m_fetch; |
|||
h256Set m_remaining; |
|||
std::map<h256, unsigned> m_indices; |
|||
RangeMask<unsigned> m_asked; |
|||
RangeMask<unsigned> m_attempted; |
|||
}; |
|||
|
|||
class DownloadMan |
|||
{ |
|||
friend class DownloadSub; |
|||
|
|||
public: |
|||
~DownloadMan() |
|||
{ |
|||
for (auto i: m_subs) |
|||
i->m_man = nullptr; |
|||
} |
|||
|
|||
void resetToChain(h256s const& _chain) |
|||
{ |
|||
{ |
|||
ReadGuard l(x_subs); |
|||
for (auto i: m_subs) |
|||
i->resetFetch(); |
|||
} |
|||
m_chain.clear(); |
|||
m_chain.reserve(_chain.size()); |
|||
for (auto i = _chain.rbegin(); i != _chain.rend(); ++i) |
|||
m_chain.push_back(*i); |
|||
m_blocksGot = RangeMask<unsigned>(0, m_chain.size()); |
|||
} |
|||
|
|||
RangeMask<unsigned> taken(bool _desperate = false) const |
|||
{ |
|||
auto ret = m_blocksGot; |
|||
if (!_desperate) |
|||
{ |
|||
ReadGuard l(x_subs); |
|||
for (auto i: m_subs) |
|||
ret += i->m_asked; |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
bool isComplete() const |
|||
{ |
|||
return m_blocksGot.full(); |
|||
} |
|||
|
|||
private: |
|||
h256s m_chain; |
|||
RangeMask<unsigned> m_blocksGot; |
|||
|
|||
mutable SharedMutex x_subs; |
|||
std::set<DownloadSub*> m_subs; |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
Loading…
Reference in new issue