blob: 7fd34d7f44d6e00ccb5d54a6f123fedf93d51307 [file]
/*
* 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_ALP_DECODER_H
#define ENCODING_ALP_DECODER_H
#include <stdint.h>
#include <algorithm>
#include <vector>
#include "alp_scalar.h"
#include "common/db_common.h"
#include "encoding/decoder.h"
#include "utils/errno_define.h"
namespace storage {
template <typename T>
class AlpDecoderBase : public Decoder {
public:
AlpDecoderBase() : initialized_(false), read_index_(0) {}
~AlpDecoderBase() override { destroy(); }
bool owns_resources() const override { return true; }
void destroy() override {
std::vector<T>().swap(values_);
std::vector<uint8_t>().swap(page_buffer_);
initialized_ = false;
read_index_ = 0;
}
void reset() override {
values_.clear();
page_buffer_.clear();
initialized_ = false;
read_index_ = 0;
}
bool has_remaining(const common::ByteStream& in) override {
if (initialized_) {
return read_index_ < values_.size();
}
return in.has_remaining();
}
int read_boolean(bool&, common::ByteStream&) override {
return common::E_TYPE_NOT_MATCH;
}
int read_int32(int32_t&, common::ByteStream&) override {
return common::E_TYPE_NOT_MATCH;
}
int read_int64(int64_t&, common::ByteStream&) override {
return common::E_TYPE_NOT_MATCH;
}
int read_String(common::String&, common::PageArena&,
common::ByteStream&) override {
return common::E_TYPE_NOT_MATCH;
}
int read_float(float& ret_value, common::ByteStream& in) override {
if (sizeof(T) != sizeof(float)) {
return common::E_TYPE_NOT_MATCH;
}
const int ret = ensure_initialized(in);
if (ret != common::E_OK) {
return ret;
}
if (read_index_ >= values_.size()) {
return common::E_NO_MORE_DATA;
}
ret_value = static_cast<float>(values_[read_index_++]);
return common::E_OK;
}
int read_double(double& ret_value, common::ByteStream& in) override {
if (sizeof(T) != sizeof(double)) {
return common::E_TYPE_NOT_MATCH;
}
const int ret = ensure_initialized(in);
if (ret != common::E_OK) {
return ret;
}
if (read_index_ >= values_.size()) {
return common::E_NO_MORE_DATA;
}
ret_value = static_cast<double>(values_[read_index_++]);
return common::E_OK;
}
int read_batch_float(float* out, int capacity, int& actual,
common::ByteStream& in) override {
if (sizeof(T) != sizeof(float)) {
return common::E_TYPE_NOT_MATCH;
}
return read_batch_impl(out, capacity, actual, in);
}
int read_batch_double(double* out, int capacity, int& actual,
common::ByteStream& in) override {
if (sizeof(T) != sizeof(double)) {
return common::E_TYPE_NOT_MATCH;
}
return read_batch_impl(out, capacity, actual, in);
}
int skip_float(int count, int& skipped, common::ByteStream& in) override {
if (sizeof(T) != sizeof(float)) {
return common::E_TYPE_NOT_MATCH;
}
return skip_impl(count, skipped, in);
}
int skip_double(int count, int& skipped, common::ByteStream& in) override {
if (sizeof(T) != sizeof(double)) {
return common::E_TYPE_NOT_MATCH;
}
return skip_impl(count, skipped, in);
}
private:
int ensure_initialized(common::ByteStream& in) {
if (initialized_) {
return common::E_OK;
}
initialized_ = true;
const uint64_t remaining = in.remaining_size();
if (remaining == 0) {
return common::E_OK;
}
if (remaining > static_cast<uint64_t>(UINT32_MAX)) {
return common::E_INVALID_ARG;
}
const uint8_t* data = NULL;
if (in.is_wrapped()) {
// The TsFile reader wraps the page value buffer directly. Decode
// from it without copying the whole page into page_buffer_.
data = reinterpret_cast<const uint8_t*>(in.get_wrapped_buf() +
in.read_pos());
in.wrapped_buf_advance_read_pos(remaining);
} else {
page_buffer_.resize(static_cast<uint32_t>(remaining));
uint32_t read_len = 0;
const int ret = in.read_buf(
&page_buffer_[0], static_cast<uint32_t>(remaining), read_len);
if (ret != common::E_OK && ret != common::E_PARTIAL_READ) {
return ret;
}
if (read_len != remaining) {
return common::E_PARTIAL_READ;
}
data = &page_buffer_[0];
}
const alp::AlpStatus status =
alp::AlpDecodePage(data, static_cast<uint32_t>(remaining), values_);
if (status != alp::ALP_OK) {
values_.clear();
return common::E_DECODE_ERR;
}
return common::E_OK;
}
int read_batch_impl(float* out, int capacity, int& actual,
common::ByteStream& in) {
return read_batch_generic(out, capacity, actual, in);
}
int read_batch_impl(double* out, int capacity, int& actual,
common::ByteStream& in) {
return read_batch_generic(out, capacity, actual, in);
}
template <typename Out>
int read_batch_generic(Out* out, int capacity, int& actual,
common::ByteStream& in) {
actual = 0;
if (capacity <= 0 || out == NULL) {
return common::E_OK;
}
const int ret = ensure_initialized(in);
if (ret != common::E_OK) {
return ret;
}
const size_t remaining = values_.size() - read_index_;
const size_t count = std::min(static_cast<size_t>(capacity), remaining);
for (size_t i = 0; i < count; ++i) {
out[i] = static_cast<Out>(values_[read_index_ + i]);
}
read_index_ += count;
actual = static_cast<int>(count);
return common::E_OK;
}
int skip_impl(int count, int& skipped, common::ByteStream& in) {
skipped = 0;
if (count <= 0) {
return common::E_OK;
}
const int ret = ensure_initialized(in);
if (ret != common::E_OK) {
return ret;
}
const size_t remaining = values_.size() - read_index_;
const size_t skipped_count =
std::min(static_cast<size_t>(count), remaining);
read_index_ += skipped_count;
skipped = static_cast<int>(skipped_count);
return common::E_OK;
}
std::vector<T> values_;
std::vector<uint8_t> page_buffer_;
bool initialized_;
size_t read_index_;
};
class FloatAlpDecoder : public AlpDecoderBase<float> {
public:
FloatAlpDecoder() {}
};
class DoubleAlpDecoder : public AlpDecoderBase<double> {
public:
DoubleAlpDecoder() {}
};
} // namespace storage
#endif // ENCODING_ALP_DECODER_H