Browse Source

Add DownloadMan for download management.

cl-refactor
Gav Wood 11 years ago
parent
commit
8ec86bb362
  1. 24
      exp/main.cpp
  2. 25
      libdevcore/RangeMask.cpp
  3. 13
      libdevcore/RangeMask.h
  4. 70
      libethereum/DownloadMan.cpp
  5. 118
      libethereum/DownloadMan.h
  6. 5
      libethereum/EthereumHost.cpp
  7. 40
      libethereum/EthereumHost.h
  8. 3
      libethereum/EthereumPeer.h

24
exp/main.cpp

@ -19,12 +19,14 @@
* @date 2014 * @date 2014
* Ethereum client. * Ethereum client.
*/ */
#include <functional>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libp2p/All.h> #include <libp2p/All.h>
#include <libdevcore/RangeMask.h> #include <libdevcore/RangeMask.h>
#include <libethereum/DownloadMan.h>
#include <libwhisper/WhisperPeer.h> #include <libwhisper/WhisperPeer.h>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -34,7 +36,25 @@ using namespace dev::shh;
int main() int main()
{ {
RangeMask<unsigned> m(0, 100); DownloadMan man;
DownloadSub s0(&man);
DownloadSub s1(&man);
DownloadSub s2(&man);
man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}));
cnote << s0.nextFetch(2);
cnote << s1.nextFetch(2);
cnote << s2.nextFetch(2);
s0.noteBlock(u256(0));
s0.doneFetch();
cnote << s0.nextFetch(2);
s1.noteBlock(u256(2));
s1.noteBlock(u256(3));
s1.doneFetch();
cnote << s1.nextFetch(2);
s0.doneFetch();
cnote << s0.nextFetch(2);
/* RangeMask<unsigned> m(0, 100);
cnote << m; cnote << m;
m += UnsignedRange(3, 10); m += UnsignedRange(3, 10);
cnote << m; cnote << m;
@ -45,7 +65,7 @@ int main()
cnote << ~m; cnote << ~m;
cnote << (~m).lowest(10); cnote << (~m).lowest(10);
for (auto i: (~m).lowest(10)) for (auto i: (~m).lowest(10))
cnote << i; cnote << i;*/
return 0; return 0;
} }

25
libdevcore/RangeMask.cpp

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

13
libdevcore/RangeMask.h

@ -24,6 +24,7 @@
#include <map> #include <map>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <iostream>
namespace dev namespace dev
{ {
@ -52,7 +53,7 @@ public:
{ {
RangeMask ret(m_all); RangeMask ret(m_all);
for (auto i = m_ranges.begin(); i != m_ranges.end() && _items; ++i) for (auto i = m_ranges.begin(); i != m_ranges.end() && _items; ++i)
_items -= (ret.m_ranges[i->first] = std::min(i->first + _items, i->second)); _items -= (ret.m_ranges[i->first] = std::min(i->first + _items, i->second)) - i->first;
return ret; return ret;
} }
@ -140,6 +141,16 @@ public:
return it != m_ranges.end() && it->first <= _i && it->second > _i; return it != m_ranges.end() && it->first <= _i && it->second > _i;
} }
bool empty() const
{
return m_ranges.empty();
}
void clear()
{
m_ranges.clear();
}
class const_iterator class const_iterator
{ {
friend class RangeMask; friend class RangeMask;

70
libethereum/DownloadMan.cpp

@ -0,0 +1,70 @@
/*
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);
}
}
h256s DownloadSub::nextFetch(unsigned _n)
{
Guard l(m_fetch);
m_asked.clear();
if (!m_man)
return h256s();
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;
m_indices.clear();
h256s ret;
for (auto i: m_asked)
{
ret.push_back(m_man->m_chain[i]);
m_indices[ret.back()] = i;
}
return ret;
}
void DownloadSub::noteBlock(h256 _hash)
{
Guard l(m_fetch);
if (m_man && m_indices.count(_hash))
m_man->m_blocksGot += m_indices[_hash];
}

118
libethereum/DownloadMan.h

@ -0,0 +1,118 @@
/*
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.
h256s nextFetch(unsigned _n);
/// Note that we've received a particular block.
void noteBlock(h256 _hash);
void doneFetch() { nextFetch(0); }
private:
void resetFetch() // Called by DownloadMan when we need to reset the download.
{
Guard l(m_fetch);
m_indices.clear();
m_asked.clear();
m_attempted.clear();
}
DownloadMan* m_man = nullptr;
Mutex m_fetch;
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 = _chain;
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;
}
private:
h256s m_chain;
RangeMask<unsigned> m_blocksGot;
mutable SharedMutex x_subs;
std::set<DownloadSub*> m_subs;
};
}
}

5
libethereum/EthereumHost.cpp

@ -15,9 +15,7 @@
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file EthereumHost.cpp /** @file EthereumHost.cpp
* @authors: * @author Gav Wood <i@gavwood.com>
* Gav Wood <i@gavwood.com>
* Eric Lombrozo <elombrozo@gmail.com>
* @date 2014 * @date 2014
*/ */
@ -34,6 +32,7 @@
#include "TransactionQueue.h" #include "TransactionQueue.h"
#include "BlockQueue.h" #include "BlockQueue.h"
#include "EthereumPeer.h" #include "EthereumPeer.h"
#include "DownloadMan.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;

40
libethereum/EthereumHost.h

@ -30,6 +30,7 @@
#include <thread> #include <thread>
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include <libdevcore/Worker.h> #include <libdevcore/Worker.h>
#include <libdevcore/RangeMask.h>
#include <libethcore/CommonEth.h> #include <libethcore/CommonEth.h>
#include <libp2p/Common.h> #include <libp2p/Common.h>
#include "CommonNet.h" #include "CommonNet.h"
@ -46,44 +47,6 @@ namespace eth
class TransactionQueue; class TransactionQueue;
class BlockQueue; class BlockQueue;
#if 0
class DownloadSub
{
friend class DownloadMan;
public:
h256s nextFetch();
void noteBlock(h256 _hash, bytesConstRef _data);
private:
void resetFetch(); // Called by DownloadMan when we need to reset the download.
DownloadMan* m_man;
Mutex m_fetch;
h256s m_fetching;
h256s m_activeGet;
bool m_killFetch;
RangeMask m_attempted;
};
class DownloadMan
{
friend class DownloadSub;
public:
void resetToChain(h256s const& _chain);
private:
void cancelFetch(DownloadSub* );
void noteBlock(h256 _hash, bytesConstRef _data);
h256s m_chain;
RangeMask m_complete;
std::map<DownloadSub*, UnsignedRange> m_fetching;
};
#endif
/** /**
* @brief The EthereumHost class * @brief The EthereumHost class
* @warning None of this is thread-safe. You have been warned. * @warning None of this is thread-safe. You have been warned.
@ -156,6 +119,7 @@ private:
mutable std::mutex x_blocksNeeded; mutable std::mutex x_blocksNeeded;
u256 m_totalDifficultyOfNeeded; u256 m_totalDifficultyOfNeeded;
h256s m_blocksNeeded; h256s m_blocksNeeded;
h256Set m_blocksOnWay; h256Set m_blocksOnWay;
h256 m_latestBlockSent; h256 m_latestBlockSent;

3
libethereum/EthereumPeer.h

@ -28,6 +28,7 @@
#include <utility> #include <utility>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include <libdevcore/RangeMask.h>
#include <libethcore/CommonEth.h> #include <libethcore/CommonEth.h>
#include <libp2p/Capability.h> #include <libp2p/Capability.h>
#include "CommonNet.h" #include "CommonNet.h"
@ -85,6 +86,8 @@ private:
h256Set m_askedBlocks; ///< The blocks for which we sent the last GetBlocks for but haven't received a corresponding Blocks. h256Set m_askedBlocks; ///< The blocks for which we sent the last GetBlocks for but haven't received a corresponding Blocks.
bool m_askedBlocksChanged = true; bool m_askedBlocksChanged = true;
RangeMask<unsigned> m_blocksAsked;
bool m_requireTransactions; bool m_requireTransactions;
Mutex x_knownBlocks; Mutex x_knownBlocks;

Loading…
Cancel
Save