From 54229196bd11913ef0ac2c44b9f090cf619d29d8 Mon Sep 17 00:00:00 2001 From: Lee Clagett Date: Sat, 14 Mar 2026 12:24:55 -0400 Subject: Improve unpack reserve handling --- src/serialization/container.h | 34 +++++++++++++++++++++++++++++++--- src/serialization/containers.h | 1 - 2 files changed, 31 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/serialization/container.h b/src/serialization/container.h index c64549c1e..7ba4d307f 100644 --- a/src/serialization/container.h +++ b/src/serialization/container.h @@ -28,6 +28,12 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include +#include +#include +#include +#include + namespace serialization { namespace detail @@ -57,8 +63,30 @@ namespace serialization return true; } - template - void do_reserve(C &c, size_t N) {} + //! @brief Reserve space for N elements if applicable for container. + template + void do_reserve(const C&...) {} + template + auto do_reserve(C &c, std::size_t N, std::size_t B) -> decltype(c.reserve(N)) + { + using T = typename C::value_type; + + static constexpr std::size_t max_compression_ratio = + is_blob_type::type::value ? 1 : + use_container_varint() ? sizeof(T) : + (std::is_same::value || std::is_same::value) ? 1: + 4; // default + + // max compression ratio for upfront memory usage + B /= sizeof(T); + B = std::max(std::size_t(1), B); + if (std::numeric_limits::max() / max_compression_ratio <= B) + B = std::numeric_limits::max(); + else + B *= max_compression_ratio; + + return c.reserve(std::min(N, B)); + } } } @@ -77,7 +105,7 @@ bool do_serialize_container(Archive &ar, C &v) return false; } - ::serialization::detail::do_reserve(v, cnt); + ::serialization::detail::do_reserve(v, cnt, ar.remaining_bytes()); for (size_t i = 0; i < cnt; i++) { if (i > 0) diff --git a/src/serialization/containers.h b/src/serialization/containers.h index dd2de829a..d4c3b6626 100644 --- a/src/serialization/containers.h +++ b/src/serialization/containers.h @@ -87,7 +87,6 @@ namespace serialization { namespace detail { - template void do_reserve(std::vector &c, size_t N) { c.reserve(N); } template void do_add(std::vector &c, T &&e) { c.emplace_back(std::forward(e)); } template void do_add(std::deque &c, T &&e) { c.emplace_back(std::forward(e)); } -- cgit v1.2.3