Browse Source

Fat Trie and tests for it.

cl-refactor
Gav Wood 10 years ago
parent
commit
49d7cdf1d4
  1. 4
      libdevcore/FixedHash.h
  2. 5
      libdevcrypto/MemoryDB.h
  3. 75
      libdevcrypto/TrieDB.h

4
libdevcore/FixedHash.h

@ -65,10 +65,10 @@ public:
FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }
/// Explicitly construct, copying from a byte array.
explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else if (_t != FailIfDifferent) { m_data.fill(0); auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } }
/// Explicitly construct, copying from a byte array.
explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else if (_t != FailIfDifferent) { m_data.fill(0); auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } }
/// Explicitly construct, copying from a bytes in memory with given pointer.
explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); }

5
libdevcrypto/MemoryDB.h

@ -51,9 +51,8 @@ public:
bool kill(h256 _h);
void purge();
bytes lookupAux(h256 _h) const { auto h = aux(_h); return m_aux.count(h) ? m_aux.at(h) : bytes(); }
void removeAux(h256 _h) { m_auxActive.erase(aux(_h)); }
void insertAux(h256 _h, bytesConstRef _v) { auto h = aux(_h); m_auxActive.insert(h); m_aux[h] = _v.toBytes(); }
bytes lookupAux(h256 _h) const { return asBytes(lookup(h256(sha3(_h).ref().cropped(16), h256::AlignRight))); }
void insertAux(h256 _h, bytesConstRef _v) { return insert(h256(sha3(_h).ref().cropped(16), h256::AlignRight), _v); }
std::set<h256> keys() const;

75
libdevcrypto/TrieDB.h

@ -68,7 +68,7 @@ class GenericTrieDB
public:
using DB = _DB;
GenericTrieDB(DB* _db = nullptr): m_db(_db) {}
GenericTrieDB(DB* _db): m_db(_db) {}
GenericTrieDB(DB* _db, h256 _root) { open(_db, _root); }
~GenericTrieDB() {}
@ -294,7 +294,7 @@ public:
using DB = typename Generic::DB;
using KeyType = _KeyType;
SpecificTrieDB(DB* _db = nullptr): Generic(_db) {}
SpecificTrieDB(DB* _db): Generic(_db) {}
SpecificTrieDB(DB* _db, h256 _root): Generic(_db, _root) {}
std::string operator[](KeyType _k) const { return at(_k); }
@ -334,19 +334,20 @@ std::ostream& operator<<(std::ostream& _out, SpecificTrieDB<Generic, KeyType> co
return _out;
}
template <class DB>
class SecureGenericTrieDB: private TrieDB<h256, DB>
template <class _DB>
class HashedGenericTrieDB: private SpecificTrieDB<GenericTrieDB<_DB>, h256>
{
using Super = TrieDB<h256, DB>;
using Super = SpecificTrieDB<GenericTrieDB<_DB>, h256>;
public:
SecureGenericTrieDB(DB* _db): Super(_db) {}
SecureGenericTrieDB(DB* _db, h256 _root): Super(_db, _root) {}
using DB = _DB;
HashedGenericTrieDB(DB* _db): Super(_db) {}
HashedGenericTrieDB(DB* _db, h256 _root): Super(_db, _root) {}
using Super::open;
using Super::init;
using Super::setRoot;
using Super::haveRoot;
/// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node).
using Super::isNull;
@ -359,29 +360,63 @@ public:
using Super::check;
std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); }
bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); }
void insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(sha3(_key), _value); }
void remove(bytesConstRef _key) { Super::remove(sha3(_key)); }
bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); }
// empty from the PoV of the iterator interface.
using iterator = void*;
iterator begin() const { return nullptr; }
iterator end() const { return nullptr; }
iterator lower_bound(bytesConstRef) const { return end(); }
};
template <class KeyType, class DB>
class SecureTrieDB: public SecureGenericTrieDB<DB>
// Hashed & Basic
template <class DB>
class FatGenericTrieDB: public GenericTrieDB<DB>
{
using Super = SecureGenericTrieDB<DB>;
using Super = GenericTrieDB<DB>;
public:
SecureTrieDB(DB* _db): Super(_db) {}
SecureTrieDB(DB* _db, h256 _root): Super(_db, _root) {}
FatGenericTrieDB(DB* _db): Super(_db), m_secure(_db) {}
FatGenericTrieDB(DB* _db, h256 _root) { open(_db, _root); }
std::string operator[](KeyType _k) const { return at(_k); }
void open(DB* _db, h256 _root) { Super::open(_db); m_secure.open(_db); setRoot(_root); }
bool contains(KeyType _k) const { return Super::contains(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
std::string at(KeyType _k) const { return Super::at(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
void insert(KeyType _k, bytesConstRef _value) { Super::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); }
void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); }
void remove(KeyType _k) { Super::remove(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
void init() { Super::init(); m_secure.init(); syncRoot(); }
void setRoot(h256 _root)
{
m_secure.setRoot(_root);
Super::setRoot(h256(Super::db()->lookupAux(m_secure.root())));
}
h256 root() const { return m_secure.root(); }
void insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(_key, _value); m_secure.insert(_key, _value); syncRoot(); }
void remove(bytesConstRef _key) { Super::remove(_key); m_secure.remove(_key); syncRoot(); }
std::set<h256> leftOvers(std::ostream* = nullptr) const { return {}; }
bool check(bool) const { return m_secure.check(false) && Super::check(false); }
private:
void syncRoot()
{
// Root changed. Need to record the mapping so we can determine on setRoot.
Super::db()->insertAux(m_secure.root(), Super::root().ref());
}
HashedGenericTrieDB<DB> m_secure;
};
template <class KeyType, class DB> using TrieDB = SpecificTrieDB<GenericTrieDB<DB>, KeyType>;
#if ETH_FAT_DB
template <class KeyType, class DB> using SecureTrieDB = SpecificTrieDB<FatGenericTrieDB<DB>, KeyType>;
#else
template <class KeyType, class DB> using SecureTrieDB = SpecificTrieDB<HashedGenericTrieDB<DB>, KeyType>;
#endif
}
// Template implementations...

Loading…
Cancel
Save