Add optimized CSizeComputer serializers
To get the advantages of faster GetSerializeSize() implementations back that were removed in "Make GetSerializeSize a wrapper on top of CSizeComputer", reintroduce them in the few places in the form of a specialized Serialize() implementation. This actually gets us in a better state than before, as these even get used when they're invoked indirectly in the serialization of another object.
This commit is contained in:
parent
a2929a26f5
commit
25a211aa9e
2 changed files with 40 additions and 0 deletions
|
@ -210,6 +210,11 @@ struct CExtPubKey {
|
|||
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
|
||||
bool Derive(CExtPubKey& out, unsigned int nChild) const;
|
||||
|
||||
void Serialize(CSizeComputer& s) const
|
||||
{
|
||||
// Optimized implementation for ::GetSerializeSize that avoids copying.
|
||||
s.seek(BIP32_EXTKEY_SIZE + 1); // add one byte for the size (compact int)
|
||||
}
|
||||
template <typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
{
|
||||
|
|
|
@ -151,6 +151,8 @@ inline float ser_uint32_to_float(uint32_t y)
|
|||
// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
|
||||
//
|
||||
|
||||
class CSizeComputer;
|
||||
|
||||
enum
|
||||
{
|
||||
// primary actions
|
||||
|
@ -225,6 +227,8 @@ inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
|
|||
else return sizeof(unsigned char) + sizeof(uint64_t);
|
||||
}
|
||||
|
||||
inline void WriteCompactSize(CSizeComputer& os, uint64_t nSize);
|
||||
|
||||
template<typename Stream>
|
||||
void WriteCompactSize(Stream& os, uint64_t nSize)
|
||||
{
|
||||
|
@ -319,6 +323,9 @@ inline unsigned int GetSizeOfVarInt(I n)
|
|||
return nRet;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
inline void WriteVarInt(CSizeComputer& os, I n);
|
||||
|
||||
template<typename Stream, typename I>
|
||||
void WriteVarInt(Stream& os, I n)
|
||||
{
|
||||
|
@ -800,6 +807,17 @@ inline void SerReadWrite(Stream& s, T& obj, CSerActionUnserialize ser_action)
|
|||
|
||||
|
||||
|
||||
/* ::GetSerializeSize implementations
|
||||
*
|
||||
* Computing the serialized size of objects is done through a special stream
|
||||
* object of type CSizeComputer, which only records the number of bytes written
|
||||
* to it.
|
||||
*
|
||||
* If your Serialize or SerializationOp method has non-trivial overhead for
|
||||
* serialization, it may be worthwhile to implement a specialized version for
|
||||
* CSizeComputer, which uses the s.seek() method to record bytes that would
|
||||
* be written instead.
|
||||
*/
|
||||
class CSizeComputer
|
||||
{
|
||||
protected:
|
||||
|
@ -815,6 +833,12 @@ public:
|
|||
this->nSize += _nSize;
|
||||
}
|
||||
|
||||
/** Pretend _nSize bytes are written, without specifying them. */
|
||||
void seek(size_t _nSize)
|
||||
{
|
||||
this->nSize += _nSize;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CSizeComputer& operator<<(const T& obj)
|
||||
{
|
||||
|
@ -878,6 +902,17 @@ inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&.
|
|||
::UnserializeMany(s, args...);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
inline void WriteVarInt(CSizeComputer &s, I n)
|
||||
{
|
||||
s.seek(GetSizeOfVarInt<I>(n));
|
||||
}
|
||||
|
||||
inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize)
|
||||
{
|
||||
s.seek(GetSizeOfCompactSize(nSize));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t GetSerializeSize(const T& t, int nType, int nVersion = 0)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue