Skip to content

Commit

Permalink
zlib::service: calculate space needed for deflator/inflator
Browse files Browse the repository at this point in the history
  • Loading branch information
ashtum committed Oct 7, 2024
1 parent dfeb44e commit ae0e9de
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 36 deletions.
52 changes: 22 additions & 30 deletions include/boost/http_proto/service/zlib_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,6 @@ namespace boost {
namespace http_proto {
namespace zlib {

struct decoder_config
{
unsigned max_window_bits = 15;
unsigned mem_level = 8;
};

constexpr
inline
std::size_t
encoding_size_hint(decoder_config cfg = {}) noexcept
{
// from: https://www.zlib.net/zlib_tech.html
//
// Memory Footprint
//
// zlib's memory footprint can also be specified fairly
// precisely. It is larger for compression than for
// decompression, and the exact requirements depend on
// how the library was compiled.
//
// The memory requirements for compression depend on two
// parameters, windowBits and memLevel:
// deflate memory usage (bytes) = (1 << (windowBits+2)) + (1 << (memLevel+9)) + 6 KB
return
(1 << (cfg.max_window_bits + 2)) +
(1 << (cfg.mem_level + 9)) +
(6 * 1024);
}

/** Error codes returned from compression/decompression functions.
Negative values are errors, positive values are used
Expand Down Expand Up @@ -124,9 +95,30 @@ struct BOOST_HTTP_PROTO_DECL
service
: http_proto::service
{
/** The memory requirements for deflator.
@param window_bits The window size.
@param mem_level The memory level.
@return The memory requirements in bytes.
*/
virtual
std::size_t
deflator_space_needed(
int window_bits,
int mem_level) const noexcept = 0;

/** The memory requirements for inflator.
@param window_bits The window size.
@return The memory requirements in bytes.
*/
virtual
std::size_t
space_needed() const noexcept = 0;
inflator_space_needed(
int window_bits) const noexcept = 0;

/** Create a deflator stream by calling zlib `deflateInit2()`.
Expand Down
5 changes: 2 additions & 3 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,8 @@ parser_service(
{
if(cfg.apply_deflate_decoder)
{
zlib_svc = &ctx.get_service<
zlib::service>();
auto const n = zlib_svc->space_needed();
auto const n = ctx.get_service<
zlib::service>().inflator_space_needed(15);
if( max_codec < n)
max_codec = n;
}
Expand Down
30 changes: 28 additions & 2 deletions src_zlib/service/zlib_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,35 @@ struct service_impl
}

std::size_t
space_needed() const noexcept override
deflator_space_needed(
int window_bits,
int mem_level) const noexcept override
{
// TODO: Account for the number of allocations and
// their overhead in the workspace.

// https://www.zlib.net/zlib_tech.html
return
(1 << (window_bits + 2)) +
(1 << (mem_level + 9)) +
(6 * 1024) +
http_proto::detail::
workspace::space_needed<deflator>();
}

std::size_t
inflator_space_needed(
int window_bits) const noexcept override
{
return 0; // TODO
// TODO: Account for the number of allocations and
// their overhead in the workspace.

// https://www.zlib.net/zlib_tech.html
return
(1 << window_bits) +
(7 * 1024) +
http_proto::detail::
workspace::space_needed<inflator>();
}

stream&
Expand Down
3 changes: 2 additions & 1 deletion test/unit/zlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ struct zlib_test
zlib::install_service(ctx);
serializer sr(
ctx,
zlib::encoding_size_hint() + (2 * 1024));
ctx.get_service<
zlib::service>().deflator_space_needed(15, 8) + (2 * 1024));

// prove we can reuse the serializer successfully
for( int i = 0; i < 2; ++i )
Expand Down

0 comments on commit ae0e9de

Please sign in to comment.