|
30 | 30 |
|
31 | 31 | #pragma once |
32 | 32 |
|
| 33 | +#include <algorithm> |
33 | 34 | #include <cstdint> |
34 | 35 | #include <cstddef> |
| 36 | +#include <limits> |
35 | 37 | #include <string> |
36 | 38 | #include <type_traits> |
37 | 39 |
|
| 40 | +#include "serialization/serialization.h" |
| 41 | + |
38 | 42 | namespace serialization |
39 | 43 | { |
40 | 44 | namespace detail |
@@ -76,7 +80,26 @@ namespace serialization |
76 | 80 | template<typename... C> |
77 | 81 | void do_reserve(const C&...) {} |
78 | 82 | template<typename C> |
79 | | - auto do_reserve(C &c, std::size_t N) -> decltype(c.reserve(N)) { return c.reserve(N); } |
| 83 | + auto do_reserve(C &c, std::size_t N, std::size_t B) -> decltype(c.reserve(N)) |
| 84 | + { |
| 85 | + using T = typename C::value_type; |
| 86 | + |
| 87 | + static constexpr std::size_t max_compression_ratio = |
| 88 | + is_blob_type<T>::type::value ? 1 : |
| 89 | + use_container_varint<T>() ? sizeof(T) : |
| 90 | + (std::is_same<T, char>::value || std::is_same<T, unsigned char>::value) ? 1: |
| 91 | + 4; // default |
| 92 | + |
| 93 | + // max compression ratio for upfront memory usage |
| 94 | + B /= sizeof(T); |
| 95 | + B = std::max(std::size_t(1), B); |
| 96 | + if (std::numeric_limits<std::size_t>::max() / max_compression_ratio <= B) |
| 97 | + B = std::numeric_limits<std::size_t>::max(); |
| 98 | + else |
| 99 | + B *= max_compression_ratio; |
| 100 | + |
| 101 | + return c.reserve(std::min(N, B)); |
| 102 | + } |
80 | 103 |
|
81 | 104 | // The value_type of STL map-like containers come in the form std::pair<const K, V>. |
82 | 105 | // Since we can't {de}serialize const types in this lib, we must convert this to std::pair<K, V> |
@@ -104,7 +127,7 @@ bool do_serialize_container(Archive<false> &ar, C &v) |
104 | 127 | return false; |
105 | 128 | } |
106 | 129 |
|
107 | | - ::serialization::detail::do_reserve(v, cnt); |
| 130 | + ::serialization::detail::do_reserve(v, cnt, ar.remaining_bytes()); |
108 | 131 |
|
109 | 132 | for (size_t i = 0; i < cnt; i++) { |
110 | 133 | if (i > 0) |
|
0 commit comments