Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace DifferenceTransform with DifferenceFormatter in #18112
Browse files Browse the repository at this point in the history
ryanofsky committed Feb 15, 2020
1 parent 40fdd5f commit f777879
Showing 3 changed files with 30 additions and 26 deletions.
25 changes: 16 additions & 9 deletions src/blockencodings.h
Original file line number Diff line number Diff line change
@@ -35,18 +35,25 @@ struct Uint48Formatter
}
};

template<bool Unser>
class DifferenceTransform
class DifferenceFormatter
{
int32_t m_shift = 0;
uint64_t m_shift = 0;

public:
uint16_t operator()(uint16_t val)
template<typename Stream, typename I>
void Ser(Stream& s, I v)
{
int32_t out = m_shift + val;
if (out < 0 || out > 0xffff) throw std::ios_base::failure("differential value overflow");
m_shift = Unser ? out + 1 : (-(int32_t)val) - 1;
return uint16_t(out);
if (v < m_shift || v >= std::numeric_limits<uint64_t>::max()) throw std::ios_base::failure("differential value overflow");
WriteCompactSize(s, v - m_shift);
m_shift = v + 1;
}
template<typename Stream, typename I>
void Unser(Stream& s, I& v)
{
uint64_t n = ReadCompactSize(s);
m_shift += n;
if (m_shift < n || m_shift >= std::numeric_limits<uint64_t>::max() || m_shift < std::numeric_limits<I>::min() || m_shift > std::numeric_limits<I>::max()) throw std::ios_base::failure("differential value overflow");
v = m_shift++;
}
};

@@ -58,7 +65,7 @@ class BlockTransactionsRequest {

SERIALIZE_METHODS(BlockTransactionsRequest, obj)
{
READWRITE(obj.blockhash, Using<VectorFormatter<CompactSizeFormatter, DifferenceTransform<false>, DifferenceTransform<true>>>(obj.indexes));
READWRITE(obj.blockhash, Using<VectorFormatter<DifferenceFormatter>>(obj.indexes));
}
};

9 changes: 7 additions & 2 deletions src/prevector.h
Original file line number Diff line number Diff line change
@@ -424,15 +424,20 @@ class prevector {
return first;
}

void push_back(const T& value) {
template<typename... Args>
void emplace_back(Args&&... args) {
size_type new_size = size() + 1;
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
new(item_ptr(size())) T(value);
new(item_ptr(size())) T(std::forward<Args>(args)...);
_size++;
}

void push_back(const T& value) {
emplace_back(value);
}

void pop_back() {
erase(end() - 1, end());
}
22 changes: 7 additions & 15 deletions src/serialize.h
Original file line number Diff line number Diff line change
@@ -602,13 +602,6 @@ class LimitedString
template<typename I>
BigEndian<I> WrapBigEndian(I& n) { return BigEndian<I>(n); }

/** Identity functor. Identical to C++20's std::identity. */
struct Identity
{
template<typename T>
constexpr T&& operator()(T&& t) const noexcept { return std::forward<T>(t); }
};

/** Formatter to serialize/deserialize vector elements using another formatter
*
* Example:
@@ -620,28 +613,28 @@ struct Identity
* as a vector of VarInt-encoded integers.
*
* V is not required to be an std::vector type. It works for any class that
* exposes a value_type, size, reserve, push_back, and const iterators.
* exposes a value_type, size, reserve, emplace_back, and const iterators.
*
* SerTrans and UnserTrans are functors that apply a transformation to the data
* before serialization and deserialization respectively.
*/
template<class Formatter, class SerTrans = Identity, class UnserTrans = Identity>
template<class Formatter>
struct VectorFormatter
{
template<typename Stream, typename V>
void Ser(Stream& s, const V& v)
{
SerTrans trans;
Formatter formatter;
WriteCompactSize(s, v.size());
for (const typename V::value_type& elem : v) {
s << Using<Formatter>(trans(elem));
formatter.Ser(s, elem);
}
}

template<typename Stream, typename V>
void Unser(Stream& s, V& v)
{
UnserTrans trans;
Formatter formatter;
v.clear();
size_t size = ReadCompactSize(s);
size_t allocated = 0;
@@ -653,9 +646,8 @@ struct VectorFormatter
allocated = std::min(size, allocated + MAX_VECTOR_ALLOCATE / sizeof(typename V::value_type));
v.reserve(allocated);
while (v.size() < allocated) {
typename V::value_type val;
s >> Using<Formatter>(val);
v.push_back(trans(std::move(val)));
v.emplace_back();
formatter.Unser(s, v.back());
}
}
};

0 comments on commit f777879

Please sign in to comment.