Inline zero_encode implementation to speed up it 25% more.

This commit is contained in:
levlam 2023-07-26 15:07:15 +03:00
parent c50afa3820
commit 65710fcec6
1 changed files with 50 additions and 42 deletions

View File

@ -203,34 +203,14 @@ string buffer_to_hex(Slice buffer) {
return res;
}
namespace {
template <class F>
string x_decode(Slice s, F &&f) {
string zero_encode(Slice data) {
auto buffer = StackAllocator::alloc(1024);
auto res = StringBuilder(buffer.as_slice(), true);
for (size_t n = s.size(), i = 0; i < n; i++) {
if (i + 1 < n && f(s[i])) {
for (int cnt = static_cast<unsigned char>(s[i + 1]); cnt > 0; cnt--) {
res.push_back(s[i]);
}
i++;
continue;
}
res.push_back(s[i]);
}
return res.as_cslice().str();
}
template <class F>
string x_encode(Slice s, F &&f) {
auto buffer = StackAllocator::alloc(1024);
auto res = StringBuilder(buffer.as_slice(), true);
for (size_t n = s.size(), i = 0; i < n; i++) {
res.push_back(s[i]);
if (f(s[i])) {
for (size_t n = data.size(), i = 0; i < n; i++) {
res.push_back(data[i]);
if (data[i] == 0) {
unsigned char cnt = 1;
while (cnt < 250 && i + cnt < n && s[i + cnt] == s[i]) {
while (cnt < 250 && i + cnt < n && data[i + cnt] == data[i]) {
cnt++;
}
res.push_back(static_cast<char>(cnt));
@ -240,27 +220,55 @@ string x_encode(Slice s, F &&f) {
return res.as_cslice().str();
}
bool is_zero(unsigned char c) {
return c == 0;
string zero_decode(Slice data) {
auto buffer = StackAllocator::alloc(1024);
auto res = StringBuilder(buffer.as_slice(), true);
for (size_t n = data.size(), i = 0; i < n; i++) {
if (data[i] == 0 && i + 1 < n) {
for (int cnt = static_cast<unsigned char>(data[i + 1]); cnt > 0; cnt--) {
res.push_back(data[i]);
}
i++;
continue;
}
res.push_back(data[i]);
}
return res.as_cslice().str();
}
bool is_zero_or_one(unsigned char c) {
return c == 0 || c == 0xff;
string zero_one_encode(Slice data) {
auto buffer = StackAllocator::alloc(1024);
auto res = StringBuilder(buffer.as_slice(), true);
for (size_t n = data.size(), i = 0; i < n; i++) {
res.push_back(data[i]);
auto c = static_cast<unsigned char>(data[i]);
if (c == 0 || c == 0xff) {
unsigned char cnt = 1;
while (cnt < 250 && i + cnt < n && data[i + cnt] == data[i]) {
cnt++;
}
res.push_back(static_cast<char>(cnt));
i += cnt - 1;
}
}
return res.as_cslice().str();
}
} // namespace
std::string zero_encode(Slice data) {
return x_encode(data, is_zero);
}
std::string zero_decode(Slice data) {
return x_decode(data, is_zero);
}
std::string zero_one_encode(Slice data) {
return x_encode(data, is_zero_or_one);
}
std::string zero_one_decode(Slice data) {
return x_decode(data, is_zero_or_one);
string zero_one_decode(Slice data) {
auto buffer = StackAllocator::alloc(1024);
auto res = StringBuilder(buffer.as_slice(), true);
for (size_t n = data.size(), i = 0; i < n; i++) {
auto c = static_cast<unsigned char>(data[i]);
if ((c == 0 || c == 0xff) && i + 1 < n) {
for (int cnt = static_cast<unsigned char>(data[i + 1]); cnt > 0; cnt--) {
res.push_back(data[i]);
}
i++;
continue;
}
res.push_back(data[i]);
}
return res.as_cslice().str();
}
} // namespace td