blob: becf4a4dd0d3e098eab2e7088ace825c2ddae1c4 [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 COMMON_CONTAINER_BYTE_BUFFER_H
#define COMMON_CONTAINER_BYTE_BUFFER_H
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "common/allocator/alloc_base.h"
#include "common/global.h"
#include "utils/util_define.h"
namespace common {
class ByteBuffer {
public:
ByteBuffer()
: data_(nullptr),
variable_type_len_(sizeof(uint32_t)),
real_data_size_(0),
reserved_size_(0) {}
~ByteBuffer() {
if (data_ && (reserved_size_ > 0)) {
mem_free(data_);
data_ = nullptr;
real_data_size_ = 0;
reserved_size_ = 0;
}
}
FORCE_INLINE void init(uint32_t size) {
data_ = static_cast<char *>(mem_alloc(size, MOD_TSBLOCK));
reserved_size_ = size;
}
FORCE_INLINE void reset() { real_data_size_ = 0; }
FORCE_INLINE void extend_memory(uint32_t new_size) {
ASSERT(new_size > reserved_size_);
data_ = static_cast<char *>(mem_realloc(data_, new_size));
reserved_size_ = new_size;
}
FORCE_INLINE void append_variable_value(const char *value, uint32_t len) {
// dynamic growth
if (UNLIKELY((real_data_size_ + len + variable_type_len_) >
reserved_size_)) {
// extreme scenarios, when encountering very long string
uint32_t growth_size =
g_config_value_.tsblock_mem_inc_step_size_ > len
? g_config_value_.tsblock_mem_inc_step_size_
: (len + 1);
extend_memory(reserved_size_ + growth_size);
}
ASSERT(data_);
// append len
memcpy(&data_[real_data_size_], reinterpret_cast<char *>(&len),
variable_type_len_);
real_data_size_ += variable_type_len_;
if (len > 0) {
// append data
memcpy(&data_[real_data_size_], value, len);
real_data_size_ += len;
}
}
FORCE_INLINE void append_fixed_value(const char *value, uint32_t len) {
// dynamic growth
if (UNLIKELY(real_data_size_ + len > reserved_size_)) {
// extreme scenarios, when encountering very long string
uint32_t growth_size =
g_config_value_.tsblock_mem_inc_step_size_ > len
? g_config_value_.tsblock_mem_inc_step_size_
: (len + 1);
extend_memory(reserved_size_ + growth_size);
}
ASSERT(data_);
memcpy(&data_[real_data_size_], value, len);
real_data_size_ += len;
}
// for fixed len value
FORCE_INLINE char *read(uint32_t offset, uint32_t len) {
ASSERT((offset + len) <= real_data_size_);
char *p = &data_[offset];
return p;
}
// for variable len value
FORCE_INLINE char *read(uint32_t offset, uint32_t *len) {
uint32_t tmp;
// Directly memcpy to avoid potential alignment issues when casting
// int32_t array pointer
std::memcpy(&tmp, data_ + offset, sizeof(tmp));
*len = tmp;
char *p = &data_[offset + variable_type_len_];
return p;
}
FORCE_INLINE char *get_data() { return data_; }
private:
char *data_;
uint8_t variable_type_len_;
uint32_t real_data_size_;
uint32_t reserved_size_; // malloc memory size from system
};
} // namespace common
#endif // COMMON_CONTAINER_BYTE_BUFFER_H