blob: 4a540ee28165188e87faa572324131b802af4963 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* License); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef ENCODING_ZIGZAG_DECODER_H
#define ENCODING_ZIGZAG_DECODER_H
#include <vector>
#include "common/allocator/alloc_base.h"
#include "common/allocator/byte_stream.h"
#include "decoder.h"
#include "utils/db_utils.h"
#include "utils/util_define.h"
namespace storage {
template <typename T>
class ZigzagDecoder {
public:
ZigzagDecoder() { init(); }
~ZigzagDecoder() { destroy(); }
void init() {
type_ = common::ZIGZAG;
bits_left_ = 0;
buffer_ = 0;
stored_value_ = 0;
first_bit_of_byte_ = 0;
num_of_sorts_of_zigzag_ = 0;
first_read_ = true;
zigzag_decode_arr_ = nullptr;
}
void reset() {
bits_left_ = 0;
buffer_ = 0;
stored_value_ = 0;
first_bit_of_byte_ = 0;
num_of_sorts_of_zigzag_ = 0;
}
void destroy() {
if (zigzag_decode_arr_ != nullptr) {
common::mem_free(zigzag_decode_arr_);
zigzag_decode_arr_ = nullptr;
}
}
void read_header(common::ByteStream &in) {
common::SerializationUtil::read_var_uint(zigzag_length_, in);
common::SerializationUtil::read_var_uint(int_length_, in);
}
void flush_byte_if_empty(common::ByteStream &in) {
if (bits_left_ == 0) {
uint32_t read_len = 0;
in.read_buf(&buffer_, 1, read_len);
bits_left_ = 8;
}
}
void read_byte_from_list() {
buffer_ = (uint8_t)(list_transit_in_zd_[0]);
list_transit_in_zd_.erase(list_transit_in_zd_.begin());
}
void fill_in_arr() {
buffer_ &= ~(1 << 7);
zigzag_decode_arr_[num_of_sorts_of_zigzag_] = buffer_;
num_of_sorts_of_zigzag_ += 1;
buffer_ = 0;
bits_left_ = 0;
}
void read_the_first_bit_of_byte_() {
first_bit_of_byte_ = (int32_t)((buffer_ >> 7) & 0x1);
}
void splice_bytes_in_arr() {
stored_value_ = 0;
if (num_of_sorts_of_zigzag_ == 1) {
stored_value_ = (uint64_t)(zigzag_decode_arr_[0]);
} else {
stored_value_ = (uint64_t)(zigzag_decode_arr_[0]);
for (int i = 0; i < num_of_sorts_of_zigzag_; i++) {
uint64_t value_shift = (uint64_t)(zigzag_decode_arr_[i])
<< (int)(7 * i);
stored_value_ = value_shift | stored_value_;
}
}
}
int64_t zigzag_decoder(int64_t stored_value_) {
stored_value_ = ((uint64_t)stored_value_ >> 1) ^ -(stored_value_ & 1);
return stored_value_;
}
T decode(common::ByteStream &in);
public:
common::TSEncoding type_;
uint8_t *zigzag_decode_arr_;
uint64_t stored_value_;
int bits_left_;
uint8_t buffer_;
int first_bit_of_byte_;
int num_of_sorts_of_zigzag_;
bool first_read_;
uint32_t zigzag_length_;
uint32_t int_length_;
std::vector<uint8_t> list_transit_in_zd_;
};
template <>
int32_t ZigzagDecoder<int32_t>::decode(common::ByteStream &in) {
if (UNLIKELY(first_read_ == true)) {
read_header(in);
zigzag_decode_arr_ =
(uint8_t *)common::mem_alloc(10, common::MOD_ZIGZAG_OBJ);
buffer_ = 0;
first_read_ = false;
list_transit_in_zd_.clear();
for (uint32_t i = 0; i < zigzag_length_; i++) {
flush_byte_if_empty(in);
list_transit_in_zd_.push_back(buffer_);
buffer_ = 0;
bits_left_ = 0;
}
}
read_byte_from_list();
read_the_first_bit_of_byte_();
while (first_bit_of_byte_ == 1) {
fill_in_arr();
read_byte_from_list();
read_the_first_bit_of_byte_();
}
fill_in_arr();
splice_bytes_in_arr();
int32_t ret_value = (int32_t)(stored_value_);
ret_value = (int32_t)(zigzag_decoder(stored_value_));
reset();
return ret_value;
}
template <>
int64_t ZigzagDecoder<int64_t>::decode(common::ByteStream &in) {
if (UNLIKELY(first_read_ == true)) {
read_header(in);
zigzag_decode_arr_ =
(uint8_t *)common::mem_alloc(10, common::MOD_ZIGZAG_OBJ);
buffer_ = 0;
first_read_ = false;
list_transit_in_zd_.clear();
for (uint32_t i = 0; i < zigzag_length_; i++) {
flush_byte_if_empty(in);
list_transit_in_zd_.push_back(buffer_);
buffer_ = 0;
bits_left_ = 0;
}
}
read_byte_from_list();
read_the_first_bit_of_byte_();
while (first_bit_of_byte_ == 1) {
fill_in_arr();
read_byte_from_list();
read_the_first_bit_of_byte_();
}
fill_in_arr();
splice_bytes_in_arr();
int64_t ret_value = (int64_t)(stored_value_);
ret_value = (int64_t)(zigzag_decoder(stored_value_));
reset();
return ret_value;
}
typedef ZigzagDecoder<int32_t> IntZigzagDecoder;
typedef ZigzagDecoder<int64_t> LongZigzagDecoder;
} // end namespace storage
#endif // ENCODING_zigzag_DECODER_H