Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@Shamzik
Copy link
Contributor

@Shamzik Shamzik commented Dec 16, 2025

The goal is to implement functions:

  • deflate_init;
  • deflate_add.

DeflateContext was implemented too as it is used in deflate functions.

@Shamzik Shamzik added this to the next milestone Dec 16, 2025
@Shamzik Shamzik self-assigned this Dec 16, 2025
@Shamzik Shamzik added the k2 k2 related label Dec 16, 2025
@Shamzik Shamzik marked this pull request as ready for review December 16, 2025 11:07
@Shamzik Shamzik requested a review from apolyakov December 16, 2025 11:07
@Shamzik Shamzik requested a review from apolyakov December 18, 2025 10:03
Copy link
Contributor

@astrophysik astrophysik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, maybe remove prefixes `deflate_add()/deflate_init'? The location of the error should be clear from the trace

@Shamzik Shamzik requested a review from astrophysik December 19, 2025 11:34
void zlib_static_free([[maybe_unused]] voidpf opaque, [[maybe_unused]] voidpf address) noexcept {}

voidpf zlib_dynamic_alloc([[maybe_unused]] voidpf opaque, uInt items, uInt size) noexcept {
auto* mem{kphp::memory::script::calloc(items, size)};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please explain the reason you chose calloc instead of alloc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because old KPHP runtime does

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Let's then rename it to zlib_dynamic_calloc

}

z_stream* stream{std::addressof(context.get()->stream)};
auto out_size{deflateBound(stream, data.size()) + 30};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this magic constant mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. =)

I got it from old KPHP runtime

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to figure this out


z_stream* stream{std::addressof(context.get()->stream)};
auto out_size{deflateBound(stream, data.size()) + 30};
out_size = out_size < 64 ? 64 : out_size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave them names. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a solution we want tbh

@Shamzik Shamzik requested a review from apolyakov December 19, 2025 14:05
int32_t window{15};
auto strategy{Z_DEFAULT_STRATEGY};
constexpr auto extract_int_option{[](int32_t lbound, int32_t ubound, const array_iterator<const mixed>& option, int32_t& dst) noexcept {
if (const mixed & value{option.get_value()}; value.is_int() && value.as_int() >= lbound && value.as_int() <= ubound) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: something is wrong with your formatter as it should be const mixed&

dst = value.as_int();
return true;
} else {
kphp::log::warning("option {} should be number between {}..{}", option.get_string_key().c_str(), lbound, ubound);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: a number

class_instance<C$DeflateContext> f$deflate_init(int64_t encoding, const array<mixed>& options) noexcept {
int32_t level{-1};
int32_t memory{8};
int32_t window{15};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not have such magic constants?


class_instance<C$DeflateContext> f$deflate_init(int64_t encoding, const array<mixed>& options = {}) noexcept;

Optional<string> f$deflate_add(const class_instance<C$DeflateContext>& context, const string& data, int64_t flush_type = Z_SYNC_FLUSH) noexcept;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing include for zlib here


struct C$DeflateContext : public refcountable_php_classes<C$DeflateContext>, private DummyVisitorMethods {
C$DeflateContext() noexcept = default;
using DummyVisitorMethods::accept;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd swap these two lines

int32_t memory{8};
int32_t window{15};
auto strategy{Z_DEFAULT_STRATEGY};
constexpr auto extract_int_option{[](int32_t lbound, int32_t ubound, const array_iterator<const mixed>& option, int32_t& dst) noexcept {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see this refactored as now it's hard to undersand

}

const auto& key{option.get_string_key()};
if (std::string_view{key.c_str(), key.size()} == "level") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can have const std::string_view key_view{...} defined once

}
}

class_instance<C$DeflateContext> context;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: there is a nice make_instance function that also allocates a class instance

stream->zfree = zlib_dynamic_free;
stream->opaque = nullptr;

if (encoding < 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get rid of all the magic constants

}

if (auto err{deflateInit2(stream, level, Z_DEFLATED, encoding, memory, strategy)}; err != Z_OK) {
kphp::log::warning("zlib error {}", zError(err));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a common pattern here to just print the error number


if (auto err{deflateInit2(stream, level, Z_DEFLATED, encoding, memory, strategy)}; err != Z_OK) {
kphp::log::warning("zlib error {}", zError(err));
context.destroy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it enough to just wait for C$DeflateContext's destructor to be invoked?

context.destroy();
return {};
}
return context;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that we allocate a class_instance<C$DeflateContext> even in the case of error. Can we create a zstream, try to make deflateInit2 on it, and then somehow move the stream?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

k2 k2 related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants