Improve levelDB performance by eliminating GetHex calls and allocate/copy/free cycles.

Sorry, this invalidates existing levelDB databases. Please remove them.
This commit is contained in:
JoelKatz
2013-04-26 13:53:26 -07:00
parent 1605a74864
commit d508bba147
2 changed files with 21 additions and 17 deletions

View File

@@ -50,13 +50,17 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index,
HashedObject::pointer object = boost::make_shared<HashedObject>(type, index, data, hash); HashedObject::pointer object = boost::make_shared<HashedObject>(type, index, data, hash);
if (!mCache.canonicalize(hash, object)) if (!mCache.canonicalize(hash, object))
{ {
Serializer s(9 + data.size()); std::vector<unsigned char> rawData(9 + data.size());
s.add8(static_cast<unsigned char>(type)); unsigned char* bufPtr = &rawData.front();
s.add32(index);
s.add32(index); *reinterpret_cast<uint32*>(bufPtr + 0) = ntohl(index);
s.addRaw(data); *reinterpret_cast<uint32*>(bufPtr + 4) = ntohl(index);
leveldb::Status st = theApp->getHashNodeDB()->Put(leveldb::WriteOptions(), hash.GetHex(), *(bufPtr + 8) = static_cast<unsigned char>(type);
leveldb::Slice(reinterpret_cast<const char *>(s.getDataPtr()), s.getLength())); memcpy(bufPtr + 9, &data.front(), data.size());
leveldb::Status st = theApp->getHashNodeDB()->Put(leveldb::WriteOptions(),
leveldb::Slice(reinterpret_cast<const char *>(hash.begin()), hash.size()),
leveldb::Slice(reinterpret_cast<const char *>(bufPtr), 9 + data.size()));
if (!st.ok()) if (!st.ok())
{ {
cLog(lsFATAL) << "Failed to store hash node"; cLog(lsFATAL) << "Failed to store hash node";
@@ -85,23 +89,20 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
} }
std::string sData; std::string sData;
leveldb::Status st = theApp->getHashNodeDB()->Get(leveldb::ReadOptions(), hash.GetHex(), &sData); leveldb::Status st = theApp->getHashNodeDB()->Get(leveldb::ReadOptions(),
leveldb::Slice(reinterpret_cast<const char *>(hash.begin()), hash.size()), &sData);
if (!st.ok()) if (!st.ok())
{ {
assert(st.IsNotFound()); assert(st.IsNotFound());
return obj; return obj;
} }
Serializer s(sData); const unsigned char* bufPtr = reinterpret_cast<const unsigned char*>(&sData.front());
uint32 index = htonl(*reinterpret_cast<const uint32*>(bufPtr));
int htype = bufPtr[8];
int htype; obj = boost::make_shared<HashedObject>(static_cast<HashedObjectType>(htype), index,
uint32 index; bufPtr + 9, sData.size() - 9, hash);
std::vector<unsigned char> data;
s.get8(htype, 0);
s.get32(index, 1);
s.getRaw(data, 9, s.getLength() - 9);
obj = boost::make_shared<HashedObject>(static_cast<HashedObjectType>(htype), index, data, hash);
mCache.canonicalize(hash, obj); mCache.canonicalize(hash, obj);
cLog(lsTRACE) << "HOS: " << hash << " fetch: in db"; cLog(lsTRACE) << "HOS: " << hash << " fetch: in db";

View File

@@ -37,6 +37,9 @@ public:
HashedObject(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data, const uint256& hash) : HashedObject(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data, const uint256& hash) :
mType(type), mHash(hash), mLedgerIndex(index), mData(data) { ; } mType(type), mHash(hash), mLedgerIndex(index), mData(data) { ; }
HashedObject(HashedObjectType type, uint32 index, const unsigned char *data, int dlen, const uint256& hash) :
mType(type), mHash(hash), mLedgerIndex(index), mData(data, data + dlen) { ; }
const std::vector<unsigned char>& getData() const { return mData; } const std::vector<unsigned char>& getData() const { return mData; }
const uint256& getHash() const { return mHash; } const uint256& getHash() const { return mHash; }
HashedObjectType getType() const { return mType; } HashedObjectType getType() const { return mType; }