Files
oceanbase/deps/oblib/src/lib/string/ob_string_holder.h
2022-11-07 03:05:47 +00:00

145 lines
4.3 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef LIB_STRING_OB_STRING_HOLDER_H
#define LIB_STRING_OB_STRING_HOLDER_H
#include "lib/allocator/ob_allocator.h"
#include "lib/allocator/ob_malloc.h"
#include "ob_string.h"
#include <utility>
namespace oceanbase
{
namespace common
{
namespace value_sematic_string
{
class DefaultAllocator : public ObIAllocator
{
public:
virtual void* alloc(const int64_t size) override
{ return ob_malloc(size, "VSStr"); }
virtual void* alloc(const int64_t size, const ObMemAttr &attr) override
{ return ob_malloc(size, attr); }
virtual void free(void *ptr) override
{ ob_free(ptr); }
static DefaultAllocator &get_instance() {
static DefaultAllocator allocator;
return allocator;
}
};
}
class ObStringHolder
{
static constexpr int64_t TINY_STR_SIZE = 16;// no need count '\0'
public:
ObStringHolder() : buffer_(nullptr), len_(0) {}
~ObStringHolder() { reset(); }
void reset() {
if (buffer_ == local_buffer_for_tiny_str_) {// tiny str
buffer_ = nullptr;
len_ = 0;
} else if (OB_ISNULL(buffer_)) {// empty str
len_ = 0;
} else {// big str
value_sematic_string::DefaultAllocator::get_instance().free(buffer_);
buffer_ = nullptr;
len_ = 0;
}
}
// move sematic
ObStringHolder(ObStringHolder &&rhs) : ObStringHolder() { *this = std::move(rhs); }
ObStringHolder &operator=(ObStringHolder &&rhs) {
reset();
if (rhs.buffer_ == rhs.local_buffer_for_tiny_str_) {// tiny str
copy_from_tiny_ob_str_(rhs.get_ob_string());
} else {// big str
std::swap(buffer_, rhs.buffer_);
std::swap(len_, rhs.len_);
}
return *this;
}
// not allow copy construction and copy assignment
ObStringHolder(const ObStringHolder &) = delete;
ObStringHolder &operator=(const ObStringHolder &) = delete;
// copy from assign
int assign(const ObStringHolder &rhs) { return assign(rhs.get_ob_string()); }
int assign(const ObString &str) {
int ret = OB_SUCCESS;
if (OB_LIKELY(!str.empty())) {
if (str.length() <= TINY_STR_SIZE) {// tiny str
copy_from_tiny_ob_str_(str);
} else {// big str
int64_t len = str.length();
char *temp_buffer = nullptr;
if (OB_ISNULL(temp_buffer = (char *)value_sematic_string::DefaultAllocator::get_instance().alloc(len))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
} else {
reset();
buffer_ = temp_buffer;
len_ = len;
memcpy(buffer_, str.ptr(), len_);
}
}
} else {
reset();
}
return ret;
}
// use ObString method to serialize and print
ObString get_ob_string() const { return ObString(len_, buffer_); }
bool empty() const {
return OB_ISNULL(buffer_) && len_ == 0;
}
int64_t to_string(char *buf, const int64_t buf_len) const {
ObString str = get_ob_string();
return str.to_string(buf, buf_len);
}
int64_t get_serialize_size() const {
ObString str = get_ob_string();
return str.get_serialize_size();
}
int serialize(char *buf, const int64_t buf_len, int64_t &pos) const {
ObString str = get_ob_string();
return str.serialize(buf, buf_len, pos);
}
int deserialize(const char *buf, const int64_t data_len, int64_t &pos) {
int ret = OB_SUCCESS;
ObString str;
if (OB_FAIL(str.deserialize(buf, data_len, pos))) {
OB_LOG(WARN, "deserialize ObString failed", K(ret));
} else if (OB_FAIL(assign(str))) {
OB_LOG(WARN, "init ObStringHolder from ObString failed", K(ret), K(str));
}
return ret;
}
private:
void copy_from_tiny_ob_str_(const ObString &tiny_str) {
reset();
OB_ASSERT(tiny_str.length() <= TINY_STR_SIZE);
memcpy(local_buffer_for_tiny_str_, tiny_str.ptr(), tiny_str.length());
buffer_ = local_buffer_for_tiny_str_;
len_ = tiny_str.length();
}
private:
char *buffer_;
int64_t len_;
char local_buffer_for_tiny_str_[TINY_STR_SIZE];
};
}
}
#endif