From d508bba147e304d5b637a75640ad56c85b4579b7 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 26 Apr 2013 13:53:26 -0700 Subject: [PATCH] Improve levelDB performance by eliminating GetHex calls and allocate/copy/free cycles. Sorry, this invalidates existing levelDB databases. Please remove them. --- src/cpp/ripple/HashedObject.cpp | 35 +++++++++++++++++---------------- src/cpp/ripple/HashedObject.h | 3 +++ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/cpp/ripple/HashedObject.cpp b/src/cpp/ripple/HashedObject.cpp index ba8283c7f..cadddea37 100644 --- a/src/cpp/ripple/HashedObject.cpp +++ b/src/cpp/ripple/HashedObject.cpp @@ -50,13 +50,17 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index, HashedObject::pointer object = boost::make_shared(type, index, data, hash); if (!mCache.canonicalize(hash, object)) { - Serializer s(9 + data.size()); - s.add8(static_cast(type)); - s.add32(index); - s.add32(index); - s.addRaw(data); - leveldb::Status st = theApp->getHashNodeDB()->Put(leveldb::WriteOptions(), hash.GetHex(), - leveldb::Slice(reinterpret_cast(s.getDataPtr()), s.getLength())); + std::vector rawData(9 + data.size()); + unsigned char* bufPtr = &rawData.front(); + + *reinterpret_cast(bufPtr + 0) = ntohl(index); + *reinterpret_cast(bufPtr + 4) = ntohl(index); + *(bufPtr + 8) = static_cast(type); + memcpy(bufPtr + 9, &data.front(), data.size()); + + leveldb::Status st = theApp->getHashNodeDB()->Put(leveldb::WriteOptions(), + leveldb::Slice(reinterpret_cast(hash.begin()), hash.size()), + leveldb::Slice(reinterpret_cast(bufPtr), 9 + data.size())); if (!st.ok()) { cLog(lsFATAL) << "Failed to store hash node"; @@ -85,23 +89,20 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash) } 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(hash.begin()), hash.size()), &sData); if (!st.ok()) { assert(st.IsNotFound()); return obj; } - Serializer s(sData); + const unsigned char* bufPtr = reinterpret_cast(&sData.front()); + uint32 index = htonl(*reinterpret_cast(bufPtr)); + int htype = bufPtr[8]; - int htype; - uint32 index; - std::vector data; - s.get8(htype, 0); - s.get32(index, 1); - s.getRaw(data, 9, s.getLength() - 9); - - obj = boost::make_shared(static_cast(htype), index, data, hash); + obj = boost::make_shared(static_cast(htype), index, + bufPtr + 9, sData.size() - 9, hash); mCache.canonicalize(hash, obj); cLog(lsTRACE) << "HOS: " << hash << " fetch: in db"; diff --git a/src/cpp/ripple/HashedObject.h b/src/cpp/ripple/HashedObject.h index 74fc7a142..177eb68d5 100644 --- a/src/cpp/ripple/HashedObject.h +++ b/src/cpp/ripple/HashedObject.h @@ -37,6 +37,9 @@ public: HashedObject(HashedObjectType type, uint32 index, const std::vector& data, const uint256& hash) : 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& getData() const { return mData; } const uint256& getHash() const { return mHash; } HashedObjectType getType() const { return mType; }