patch 4.0
This commit is contained in:
768
src/storage/blocksstable/ob_datum_row.cpp
Normal file
768
src/storage/blocksstable/ob_datum_row.cpp
Normal file
@ -0,0 +1,768 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX STORAGE
|
||||
#include "ob_datum_row.h"
|
||||
#include "share/schema/ob_table_param.h"
|
||||
#include "share/ob_force_print_log.h"
|
||||
#include "storage/ob_i_store.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
namespace blocksstable
|
||||
{
|
||||
static int nonext_nonext_compare(const ObStorageDatum &left, const ObStorageDatum &right, const common::ObCmpFunc &cmp_func, int &cmp_ret)
|
||||
{
|
||||
cmp_ret = cmp_func.cmp_func_(left, right);
|
||||
STORAGE_LOG(DEBUG, "chaser debug compare datum", K(left), K(right), K(cmp_ret));
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
static int nonext_ext_compare(const ObStorageDatum &left, const ObStorageDatum &right, const common::ObCmpFunc &cmp_func, int &cmp_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSEDx(left, cmp_func);
|
||||
if (right.is_max()) {
|
||||
cmp_ret = -1;
|
||||
} else if (right.is_min()) {
|
||||
cmp_ret = 1;
|
||||
} else {
|
||||
ret = OB_ERR_SYS;
|
||||
STORAGE_LOG(ERROR, "Unexpected datum in rowkey to compare", K(ret), K(right));
|
||||
}
|
||||
STORAGE_LOG(DEBUG, "chaser debug compare datum", K(ret), K(left), K(right), K(cmp_ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ext_nonext_compare(const ObStorageDatum &left, const ObStorageDatum &right, const common::ObCmpFunc &cmp_func, int &cmp_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSEDx(right, cmp_func);
|
||||
if (left.is_max()) {
|
||||
cmp_ret = 1;
|
||||
} else if (left.is_min()) {
|
||||
cmp_ret = -1;
|
||||
} else {
|
||||
ret = OB_ERR_SYS;
|
||||
STORAGE_LOG(ERROR, "Unexpected datum in rowkey to compare", K(ret), K(left));
|
||||
}
|
||||
STORAGE_LOG(DEBUG, "chaser debug compare datum", K(ret), K(left), K(right), K(cmp_ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ext_ext_compare(const ObStorageDatum &left, const ObStorageDatum &right, const common::ObCmpFunc &cmp_func, int &cmp_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSEDx(cmp_func);
|
||||
int64_t lv = left.is_max() - left.is_min();
|
||||
int64_t rv = right.is_max() - right.is_min();
|
||||
if (OB_UNLIKELY(0 == lv || 0 == rv)) {
|
||||
ret = OB_ERR_SYS;
|
||||
STORAGE_LOG(ERROR, "Unexpected datum in rowkey to compare", K(ret), K(left), K(right));
|
||||
} else {
|
||||
cmp_ret = lv - rv;
|
||||
}
|
||||
STORAGE_LOG(DEBUG, "chaser debug compare datum", K(ret), K(left), K(right), K(cmp_ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef int (*ExtSafeCompareFunc)(const ObStorageDatum &left, const ObStorageDatum &right, const common::ObCmpFunc &cmp_func, int &cmp_ret);
|
||||
static ExtSafeCompareFunc ext_safe_cmp_funcs[2][2] = {
|
||||
{nonext_nonext_compare, nonext_ext_compare},
|
||||
{ext_nonext_compare, ext_ext_compare}
|
||||
};
|
||||
|
||||
int ObStorageDatumCmpFunc::compare(const ObStorageDatum &left, const ObStorageDatum &right, int &cmp_ret) const
|
||||
{
|
||||
return ext_safe_cmp_funcs[left.is_ext()][right.is_ext()](left, right, cmp_func_, cmp_ret);
|
||||
}
|
||||
|
||||
|
||||
const char *get_dml_str(ObDmlFlag dml_flag)
|
||||
{
|
||||
STATIC_ASSERT(static_cast<int64_t>(DF_MAX) == ARRAYSIZEOF(ObDmlFlagStr), "dml str len is mismatch");
|
||||
const char *ret_str = nullptr;
|
||||
if (dml_flag >= DF_MAX) {
|
||||
ret_str = "invalid_dml";
|
||||
} else {
|
||||
ret_str = ObDmlFlagStr[dml_flag];
|
||||
}
|
||||
return ret_str;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObDmlRowFlag, whole_flag_);
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObMultiVersionRowFlag, flag_);
|
||||
|
||||
/*
|
||||
*ObStorageDatumBuffer
|
||||
*/
|
||||
ObStorageDatumBuffer::ObStorageDatumBuffer(common::ObIAllocator *allocator)
|
||||
: capacity_(LOCAL_BUFFER_ARRAY),
|
||||
local_datums_(),
|
||||
datums_(local_datums_),
|
||||
allocator_(allocator),
|
||||
is_inited_(nullptr != allocator)
|
||||
{}
|
||||
|
||||
void ObStorageDatumBuffer::reset()
|
||||
{
|
||||
if (datums_ != local_datums_ && nullptr != allocator_) {
|
||||
allocator_->free(datums_);
|
||||
}
|
||||
allocator_ = nullptr;
|
||||
datums_ = local_datums_;
|
||||
capacity_ = LOCAL_BUFFER_ARRAY;
|
||||
for (int64_t i = 0; i < capacity_; i++) {
|
||||
datums_[i].reuse();
|
||||
}
|
||||
is_inited_ = false;
|
||||
}
|
||||
|
||||
int ObStorageDatumBuffer::init(common::ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (IS_INIT) {
|
||||
ret = OB_INIT_TWICE;
|
||||
STORAGE_LOG(WARN, "ObStorageDatumBuffer init twice", K(ret), K(*this));
|
||||
} else {
|
||||
OB_ASSERT(datums_ == local_datums_);
|
||||
allocator_ = &allocator;
|
||||
is_inited_ = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStorageDatumBuffer::reserve(const int64_t count, const bool keep_data)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
void *buf = nullptr;
|
||||
|
||||
if (IS_NOT_INIT) {
|
||||
ret = OB_NOT_INIT;
|
||||
STORAGE_LOG(WARN, "ObStorageDatumBuffer is not inited", K(ret), K(*this));
|
||||
} else if (OB_UNLIKELY(count <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid argument to reserve datum buffer", K(ret), K(count));
|
||||
} else if (count <= capacity_){
|
||||
} else if (OB_ISNULL(buf = allocator_->alloc(sizeof(ObStorageDatum) * count))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
STORAGE_LOG(WARN, "Failed to alloc memory", K(ret), K(count));
|
||||
} else {
|
||||
ObStorageDatum *new_datums = new (buf) ObStorageDatum [count];
|
||||
if (keep_data) {
|
||||
for (int64_t i = 0; i < capacity_; i++) {
|
||||
new_datums[i] = datums_[i];
|
||||
}
|
||||
}
|
||||
if (nullptr != datums_ && datums_ != local_datums_) {
|
||||
allocator_->free(datums_);
|
||||
}
|
||||
datums_ = new_datums;
|
||||
capacity_ = count;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*ObDatumRow
|
||||
*/
|
||||
|
||||
ObDatumRow::ObDatumRow()
|
||||
: local_allocator_("ObDatumRow"),
|
||||
count_(0),
|
||||
fast_filter_skipped_(false),
|
||||
have_uncommited_row_(false),
|
||||
row_flag_(),
|
||||
mvcc_row_flag_(),
|
||||
trans_id_(),
|
||||
scan_index_(0),
|
||||
group_idx_(0),
|
||||
snapshot_version_(0),
|
||||
storage_datums_(nullptr),
|
||||
datum_buffer_(),
|
||||
old_row_(),
|
||||
obj_buf_()
|
||||
{}
|
||||
|
||||
ObDatumRow::~ObDatumRow()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
int ObDatumRow::init(ObIAllocator &allocator, const int64_t capacity)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(is_valid())) {
|
||||
ret = OB_INIT_TWICE;
|
||||
STORAGE_LOG(WARN, "ObDatumRow init twice", K(ret), K(*this));
|
||||
} else if (OB_FAIL(obj_buf_.init(&allocator))) {
|
||||
STORAGE_LOG(WARN, "Failed to init obj_buf array", K(ret));
|
||||
} else if (OB_FAIL(datum_buffer_.init(allocator))) {
|
||||
STORAGE_LOG(WARN, "Failed to init datum buffer", K(ret));
|
||||
} else if (OB_FAIL(datum_buffer_.reserve(capacity))) {
|
||||
STORAGE_LOG(WARN, "Failed to reserve datum buffer", K(ret), K(capacity));
|
||||
} else {
|
||||
storage_datums_ = datum_buffer_.get_datums();
|
||||
count_ = capacity;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
int ObDatumRow::init(const int64_t capacity)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(is_valid())) {
|
||||
ret = OB_INIT_TWICE;
|
||||
STORAGE_LOG(WARN, "ObDatumRow init twice", K(ret), K(*this));
|
||||
} else if (OB_UNLIKELY(capacity <= 0 || capacity > 2 * OB_USER_ROW_MAX_COLUMNS_COUNT)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid argument to init datumrow", K(ret), K(capacity));
|
||||
} else {
|
||||
ret = init(local_allocator_, capacity);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//// only for transformer which never use old_row_
|
||||
//int ObDatumRow::init_buf(char *buf, const int64_t buf_size, const int64_t capacity)
|
||||
//{
|
||||
//int ret = OB_SUCCESS;
|
||||
|
||||
//if (OB_UNLIKELY(is_valid())) {
|
||||
//ret = OB_INIT_TWICE;
|
||||
//STORAGE_LOG(WARN, "ObDatumRow init twice", K(ret), K(*this));
|
||||
//} else if (OB_UNLIKELY(nullptr == buf || capacity <= 0 || buf_size < capacity * sizeof(ObStorageDatum))) {
|
||||
//ret = OB_INVALID_ARGUMENT;
|
||||
//STORAGE_LOG(WARN, "Invalid argument to init datum row", K(ret), KP(buf), K(buf_size), K(capacity));
|
||||
//} else {
|
||||
//storage_datums_ = new (buf) ObStorageDatum [capacity];
|
||||
//count_ = capacity_ = capacity;
|
||||
//allocator_ = nullptr;
|
||||
//old_row_.reset();
|
||||
//}
|
||||
|
||||
//return ret;
|
||||
//}
|
||||
|
||||
int ObDatumRow::reserve(const int64_t capacity, const bool keep_data)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
void *buf = nullptr;
|
||||
|
||||
if (OB_UNLIKELY(!is_valid())) {
|
||||
STORAGE_LOG(WARN, "ObDatumRow is not inited", K(ret), K(*this));
|
||||
} else if (OB_UNLIKELY(capacity <= 0 || capacity > 2 * OB_USER_ROW_MAX_COLUMNS_COUNT)) {
|
||||
STORAGE_LOG(WARN, "Invalid argument to reserve datum row", K(ret), K(capacity));
|
||||
} else if (capacity <= get_capacity()) {
|
||||
// skip
|
||||
} else if (OB_FAIL(datum_buffer_.reserve(capacity))) {
|
||||
STORAGE_LOG(WARN, "Failed to reserve datum buffer", K(ret), K(capacity));
|
||||
} else {
|
||||
storage_datums_ = datum_buffer_.get_datums();
|
||||
old_row_.reset();
|
||||
obj_buf_.reset();
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
mvcc_row_flag_.reset();
|
||||
trans_id_.reset();
|
||||
scan_index_ = 0;
|
||||
group_idx_ = 0;
|
||||
snapshot_version_ = 0;
|
||||
fast_filter_skipped_ = false;
|
||||
have_uncommited_row_ = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ObDatumRow::reset()
|
||||
{
|
||||
old_row_.reset();
|
||||
obj_buf_.reset();
|
||||
fast_filter_skipped_ = false;
|
||||
datum_buffer_.reset();
|
||||
storage_datums_ = nullptr;
|
||||
snapshot_version_ = 0;
|
||||
group_idx_ = 0;
|
||||
scan_index_ = 0;
|
||||
trans_id_.reset();
|
||||
mvcc_row_flag_.reset();
|
||||
row_flag_.reset();
|
||||
count_ = 0;
|
||||
local_allocator_.reset();
|
||||
}
|
||||
|
||||
void ObDatumRow::reuse()
|
||||
{
|
||||
if (nullptr != storage_datums_) {
|
||||
for (int64_t i = 0; i < count_; i++) {
|
||||
storage_datums_[i].reuse();
|
||||
}
|
||||
}
|
||||
mvcc_row_flag_.reset();
|
||||
trans_id_.reset();
|
||||
scan_index_ = 0;
|
||||
group_idx_ = 0;
|
||||
snapshot_version_ = 0;
|
||||
fast_filter_skipped_ = false;
|
||||
have_uncommited_row_ = false;
|
||||
}
|
||||
|
||||
int ObDatumRow::deep_copy(const ObDatumRow &src, ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(!src.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid argument to deep copy datum row", K(ret), K(src));
|
||||
} else if (OB_UNLIKELY(get_capacity() < src.count_ || nullptr == storage_datums_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
STORAGE_LOG(WARN, "Unexpected local datum row to deep copy", K(ret), KPC(this));
|
||||
} else {
|
||||
count_ = src.count_;
|
||||
row_flag_ = src.row_flag_;
|
||||
mvcc_row_flag_ = src.mvcc_row_flag_;
|
||||
trans_id_ = src.trans_id_;
|
||||
scan_index_ = src.scan_index_;
|
||||
group_idx_ = src.group_idx_;
|
||||
snapshot_version_ = src.snapshot_version_;
|
||||
fast_filter_skipped_ = src.fast_filter_skipped_;
|
||||
have_uncommited_row_ = src.have_uncommited_row_;
|
||||
for(int64_t i = 0; OB_SUCC(ret) && i < count_; i++) {
|
||||
if (OB_FAIL(storage_datums_[i].deep_copy(src.storage_datums_[i], allocator))) {
|
||||
STORAGE_LOG(WARN, "Failed to deep copy storage datum", K(ret), K(src.storage_datums_[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDatumRow::prepare_new_row(const ObIArray<share::schema::ObColDesc> &out_cols)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(!is_valid())) {
|
||||
STORAGE_LOG(WARN, "ObDatumRow is not inited", K(ret), K(*this));
|
||||
} else if (OB_UNLIKELY(out_cols.count() < count_)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid argument to prepare new row", K(ret), K(count_), K(out_cols));
|
||||
} else if (OB_FAIL(obj_buf_.reserve(count_))) {
|
||||
STORAGE_LOG(WARN, "Failed to reserve buf for obj buf", K(ret), K(count_));
|
||||
} else {
|
||||
old_row_.cells_ = obj_buf_.get_data();
|
||||
old_row_.count_ = count_;
|
||||
old_row_.projector_ = nullptr;
|
||||
old_row_.projector_size_ = 0;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < out_cols.count(); i++) {
|
||||
if (OB_FAIL(storage_datums_[i].to_obj_enhance(old_row_.cells_[i], out_cols.at(i).col_type_))) {
|
||||
STORAGE_LOG(WARN, "Failed to transform datum to obj", K(ret), K(i), K(storage_datums_[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDatumRow::to_store_row(const ObIArray<share::schema::ObColDesc> &out_cols,
|
||||
storage::ObStoreRow &store_row)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(!is_valid())) {
|
||||
STORAGE_LOG(WARN, "ObDatumRow is not inited", K(ret), K(*this));
|
||||
} else if (OB_FAIL(prepare_new_row(out_cols))) {
|
||||
STORAGE_LOG(WARN, "Failed to prepare new row", K(ret));
|
||||
} else {
|
||||
store_row.reset();
|
||||
store_row.row_val_ = old_row_;
|
||||
store_row.capacity_ = count_;
|
||||
store_row.flag_ = row_flag_;
|
||||
store_row.row_type_flag_ = mvcc_row_flag_;
|
||||
store_row.trans_id_ = trans_id_;
|
||||
store_row.scan_index_ = scan_index_;
|
||||
store_row.group_idx_ = group_idx_;
|
||||
store_row.snapshot_version_ = snapshot_version_;
|
||||
store_row.fast_filter_skipped_ = fast_filter_skipped_;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDatumRow::from_store_row(const storage::ObStoreRow &store_row)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(!is_valid())) {
|
||||
STORAGE_LOG(WARN, "ObDatumRow is not inited", K(ret), K(*this));
|
||||
} else if (OB_FAIL(reserve(store_row.row_val_.count_))) {
|
||||
STORAGE_LOG(WARN, "Failed to reserve datums", K(ret), K(store_row));
|
||||
} else {
|
||||
count_ = store_row.row_val_.count_;
|
||||
row_flag_ = store_row.flag_;
|
||||
mvcc_row_flag_ = store_row.row_type_flag_;
|
||||
trans_id_ = store_row.trans_id_;
|
||||
scan_index_ = store_row.scan_index_;
|
||||
group_idx_ = store_row.group_idx_;
|
||||
snapshot_version_ = store_row.snapshot_version_;
|
||||
fast_filter_skipped_ = store_row.fast_filter_skipped_;
|
||||
have_uncommited_row_ = false;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < count_; i++) {
|
||||
if (OB_FAIL(storage_datums_[i].from_obj_enhance(store_row.row_val_.cells_[i]))) {
|
||||
STORAGE_LOG(WARN, "Failed to transfer obj to datum", K(ret), K(i), K(store_row.row_val_.cells_[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE(ObDatumRow)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LST_DO_CODE(OB_UNIS_ENCODE,
|
||||
row_flag_,
|
||||
mvcc_row_flag_,
|
||||
trans_id_,
|
||||
scan_index_,
|
||||
group_idx_,
|
||||
snapshot_version_);
|
||||
OB_UNIS_ENCODE_ARRAY(storage_datums_, count_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(ObDatumRow)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
fast_filter_skipped_ = false;
|
||||
have_uncommited_row_ = false;
|
||||
LST_DO_CODE(OB_UNIS_DECODE,
|
||||
row_flag_,
|
||||
mvcc_row_flag_,
|
||||
trans_id_,
|
||||
scan_index_,
|
||||
group_idx_,
|
||||
snapshot_version_);
|
||||
OB_UNIS_DECODE(count_);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (get_capacity() < count_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
STORAGE_LOG(WARN, "ObDatumRow has not keep enough datums for deserialize", K(ret), K_(datum_buffer), K_(count));
|
||||
} else {
|
||||
OB_UNIS_DECODE_ARRAY(storage_datums_, count_);
|
||||
fast_filter_skipped_ = false;
|
||||
have_uncommited_row_ = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(ObDatumRow)
|
||||
{
|
||||
int64_t len = 0;
|
||||
LST_DO_CODE(OB_UNIS_ADD_LEN,
|
||||
row_flag_,
|
||||
mvcc_row_flag_,
|
||||
trans_id_,
|
||||
scan_index_,
|
||||
group_idx_,
|
||||
snapshot_version_);
|
||||
OB_UNIS_ADD_LEN_ARRAY(storage_datums_, count_);
|
||||
return len;
|
||||
}
|
||||
|
||||
DEF_TO_STRING(ObDatumRow)
|
||||
{
|
||||
int64_t pos = 0;
|
||||
J_OBJ_START();
|
||||
J_KV(K_(row_flag), K_(trans_id), K_(scan_index), K_(mvcc_row_flag),
|
||||
K_(snapshot_version), K_(fast_filter_skipped), K_(have_uncommited_row), K_(group_idx), K_(count), K_(datum_buffer));
|
||||
if (NULL != buf && buf_len >= 0) {
|
||||
if (NULL != storage_datums_) {
|
||||
J_ARRAY_START();
|
||||
for (int64_t i = 0; i < count_; ++i) {
|
||||
databuff_printf(buf, buf_len, pos, "col_id=%ld:", i);
|
||||
pos += storage_datums_[i].storage_to_string(buf + pos, buf_len - pos);
|
||||
databuff_printf(buf, buf_len, pos, ",");
|
||||
}
|
||||
J_ARRAY_END();
|
||||
}
|
||||
}
|
||||
J_OBJ_END();
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool ObDatumRow::operator==(const ObDatumRow &other) const
|
||||
{
|
||||
bool is_equal = true;
|
||||
if (count_ != other.count_) {
|
||||
is_equal = false;
|
||||
STORAGE_LOG(WARN, "datum row count no equal", K(other), K(*this));
|
||||
} else {
|
||||
for (int64_t i = 0; is_equal && i < count_; i++) {
|
||||
is_equal = storage_datums_[i] == other.storage_datums_[i];
|
||||
if (!is_equal) {
|
||||
STORAGE_LOG(WARN, "obj and datum no equal", K(i), K(other), K(*this));
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_equal;
|
||||
}
|
||||
|
||||
bool ObDatumRow::operator==(const ObNewRow &other) const
|
||||
{
|
||||
bool is_equal = true;
|
||||
if (count_ != other.count_) {
|
||||
is_equal = false;
|
||||
STORAGE_LOG(WARN, "datum row count no equal", K(other), K(*this));
|
||||
} else {
|
||||
int ret = OB_SUCCESS;
|
||||
for (int64_t i = 0; is_equal && i < count_; i++) {
|
||||
is_equal = storage_datums_[i] == other.cells_[i];
|
||||
if (!is_equal) {
|
||||
STORAGE_LOG(WARN, "obj and datum no equal", K(i), K(other), K(*this));
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_equal;
|
||||
}
|
||||
|
||||
/*
|
||||
*ObStorageDatumUtils
|
||||
*/
|
||||
ObStorageDatumUtils::ObStorageDatumUtils()
|
||||
: rowkey_cnt_(0),
|
||||
col_cnt_(0),
|
||||
cmp_funcs_(),
|
||||
hash_funcs_(),
|
||||
ext_hash_func_(),
|
||||
allocator_(nullptr),
|
||||
is_oracle_mode_(false),
|
||||
is_inited_(false)
|
||||
{}
|
||||
|
||||
ObStorageDatumUtils::~ObStorageDatumUtils()
|
||||
{}
|
||||
|
||||
int ObStorageDatumUtils::transform_multi_version_col_desc(const ObIArray<share::schema::ObColDesc> &col_descs,
|
||||
const int64_t schema_rowkey_cnt,
|
||||
ObIArray<share::schema::ObColDesc> &mv_col_descs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_UNLIKELY(schema_rowkey_cnt > col_descs.count())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid argument to transform mv col descs", K(ret), K(schema_rowkey_cnt), K(col_descs));
|
||||
} else {
|
||||
mv_col_descs.reuse();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < schema_rowkey_cnt; i++) {
|
||||
if (OB_FAIL(mv_col_descs.push_back(col_descs.at(i)))) {
|
||||
STORAGE_LOG(WARN, "Failed to push back col desc", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(storage::ObMultiVersionRowkeyHelpper::add_extra_rowkey_cols(mv_col_descs))) {
|
||||
STORAGE_LOG(WARN, "Fail to add extra_rowkey_cols", K(ret), K(schema_rowkey_cnt));
|
||||
} else {
|
||||
for (int64_t i = schema_rowkey_cnt; OB_SUCC(ret) && i < col_descs.count(); i++) {
|
||||
const share::schema::ObColDesc &col_desc = col_descs.at(i);
|
||||
if (col_desc.col_id_ == common::OB_HIDDEN_TRANS_VERSION_COLUMN_ID
|
||||
|| col_desc.col_id_ == common::OB_HIDDEN_SQL_SEQUENCE_COLUMN_ID) {
|
||||
continue;
|
||||
} else if (OB_FAIL(mv_col_descs.push_back(col_desc))) {
|
||||
STORAGE_LOG(WARN, "Failed to push back col desc", K(ret), K(col_desc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStorageDatumUtils::init(const ObIArray<share::schema::ObColDesc> &col_descs,
|
||||
const int64_t schema_rowkey_cnt,
|
||||
const bool is_oracle_mode,
|
||||
ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<share::schema::ObColDesc, 32> mv_col_descs;
|
||||
|
||||
if (IS_INIT) {
|
||||
ret = OB_INIT_TWICE;
|
||||
STORAGE_LOG(WARN, "ObStorageDatumUtils init twice", K(ret), K(*this));
|
||||
} else if (OB_UNLIKELY(schema_rowkey_cnt < 0 || schema_rowkey_cnt >= OB_MAX_ROWKEY_COLUMN_NUMBER
|
||||
|| schema_rowkey_cnt > col_descs.count())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid argument to init storage datum utils", K(ret), K(col_descs), K(schema_rowkey_cnt));
|
||||
} else if (OB_FAIL(transform_multi_version_col_desc(col_descs, schema_rowkey_cnt, mv_col_descs))) {
|
||||
STORAGE_LOG(WARN, "Failed to transform multi version col descs", K(ret));
|
||||
} else {
|
||||
is_oracle_mode_ = is_oracle_mode;
|
||||
cmp_funcs_.set_allocator(&allocator);
|
||||
hash_funcs_.set_allocator(&allocator);
|
||||
if (OB_FAIL(cmp_funcs_.reserve(mv_col_descs.count()))) {
|
||||
STORAGE_LOG(WARN, "Failed to reserve cmp func array", K(ret));
|
||||
} else if (OB_FAIL(hash_funcs_.reserve(mv_col_descs.count()))) {
|
||||
STORAGE_LOG(WARN, "Failed to reserve hash func array", K(ret));
|
||||
} else {
|
||||
// support column order index until next task done
|
||||
// https://aone.alibaba-inc.com/task/39441116
|
||||
// we could use the cmp funcs in the basic funcs directlly
|
||||
bool is_null_last = is_oracle_mode_;
|
||||
ObCmpFunc cmp_func;
|
||||
ObHashFunc hash_func;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < mv_col_descs.count(); i++) {
|
||||
const share::schema::ObColDesc &col_desc = mv_col_descs.at(i);
|
||||
//TODO @hanhui support desc rowkey
|
||||
bool is_ascending = true || col_desc.col_order_ == ObOrderType::ASC;
|
||||
sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(col_desc.col_type_.get_type(),
|
||||
col_desc.col_type_.get_collation_type(),
|
||||
is_oracle_mode);
|
||||
if (OB_UNLIKELY(nullptr == basic_funcs
|
||||
|| nullptr == basic_funcs->null_last_cmp_
|
||||
|| nullptr == basic_funcs->murmur_hash_)) {
|
||||
ret = OB_ERR_SYS;
|
||||
STORAGE_LOG(ERROR, "Unexpected null basic funcs", K(ret), K(col_desc));
|
||||
} else {
|
||||
cmp_func.cmp_func_ = is_null_last ? basic_funcs->null_last_cmp_ : basic_funcs->null_first_cmp_;
|
||||
hash_func.hash_func_ = basic_funcs->murmur_hash_;
|
||||
if (OB_FAIL(hash_funcs_.push_back(hash_func))) {
|
||||
STORAGE_LOG(WARN, "Failed to push back hash func", K(ret), K(i), K(col_desc));
|
||||
} else if (is_ascending) {
|
||||
if (OB_FAIL(cmp_funcs_.push_back(ObStorageDatumCmpFunc(cmp_func)))) {
|
||||
STORAGE_LOG(WARN, "Failed to push back cmp func", K(ret), K(i), K(col_desc));
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_SYS;
|
||||
STORAGE_LOG(WARN, "Unsupported desc column order", K(ret), K(col_desc), K(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(ObExtendType, CS_TYPE_BINARY);
|
||||
if (OB_UNLIKELY(nullptr == basic_funcs || nullptr == basic_funcs->murmur_hash_)) {
|
||||
ret = OB_ERR_SYS;
|
||||
STORAGE_LOG(ERROR, "Unexpected null basic funcs for extend type", K(ret));
|
||||
} else {
|
||||
ext_hash_func_.hash_func_ = basic_funcs->murmur_hash_;
|
||||
rowkey_cnt_ = schema_rowkey_cnt + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt();
|
||||
col_cnt_ = mv_col_descs.count();
|
||||
allocator_ = &allocator;
|
||||
is_inited_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObStorageDatumUtils::reset()
|
||||
{
|
||||
rowkey_cnt_ = 0;
|
||||
col_cnt_ = 0;
|
||||
cmp_funcs_.reset();
|
||||
hash_funcs_.reset();
|
||||
allocator_ = nullptr;
|
||||
ext_hash_func_.hash_func_ = nullptr;
|
||||
is_inited_ = false;
|
||||
}
|
||||
|
||||
int ObGhostRowUtil::is_ghost_row(
|
||||
const blocksstable::ObMultiVersionRowFlag &flag,
|
||||
bool &is_ghost_row)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_ghost_row = false;
|
||||
if (flag.is_ghost_row()) {
|
||||
is_ghost_row = true;
|
||||
if (OB_UNLIKELY(!flag.is_last_multi_version_row())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
FLOG_ERROR("ghost row should only be last row", K(ret), K(flag));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGhostRowUtil::make_ghost_row(
|
||||
const int64_t sql_sequence_col_idx,
|
||||
const ObQueryFlag &query_flag,
|
||||
blocksstable::ObDatumRow &row)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY((!query_flag.is_sstable_cut()
|
||||
&& (!row.mvcc_row_flag_.is_uncommitted_row() || !row.trans_id_.is_valid()))
|
||||
|| !row.mvcc_row_flag_.is_last_multi_version_row()
|
||||
|| row.get_column_count() < sql_sequence_col_idx)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "invalid argument", K(ret), K(row), K(sql_sequence_col_idx));
|
||||
} else {
|
||||
row.row_flag_.set_flag(ObDmlFlag::DF_UPDATE);
|
||||
row.mvcc_row_flag_.reset();
|
||||
row.mvcc_row_flag_.set_ghost_row(true);
|
||||
row.mvcc_row_flag_.set_last_multi_version_row(true);
|
||||
row.trans_id_.reset();
|
||||
row.storage_datums_[sql_sequence_col_idx - 1].set_int(GHOST_NUM);
|
||||
row.storage_datums_[sql_sequence_col_idx].set_int(GHOST_NUM);
|
||||
for (int i = sql_sequence_col_idx + 1; i < row.get_column_count(); ++i) {
|
||||
row.storage_datums_[i].set_nop();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void format_dml_str(const int32_t flag, char *str, int len) {
|
||||
OB_ASSERT(len >= 16);
|
||||
int32_t bit;
|
||||
int32_t count = 0;
|
||||
uint32_t f = flag;
|
||||
memset(str, 0, len);
|
||||
if (f & (1<<7)) {
|
||||
strncat(str, ObDmlTypeStr[1], 16 - strlen(str));
|
||||
} else {
|
||||
strncat(str, ObDmlTypeStr[0], 16 - strlen(str));
|
||||
}
|
||||
f = f & ((1<<7) - 1);
|
||||
strncat(str, "|", 16 - strlen(str));
|
||||
strncat(str, ObDmlFlagStr[f], 16 - strlen(str));
|
||||
}
|
||||
|
||||
|
||||
void format_mvcc_str(const int32_t flag, char *str, int len) {
|
||||
OB_ASSERT(len >= 16);
|
||||
int32_t bit;
|
||||
int32_t count = 0;
|
||||
uint32_t f = flag;
|
||||
memset(str, 0, len);
|
||||
while (0 != f && count < MvccFlagCount) {
|
||||
bit = __builtin_ffs(f);
|
||||
if (0 < count) {
|
||||
strncat(str, "|", 16 - strlen(str));
|
||||
}
|
||||
strncat(str, ObMvccFlagStr[bit], 16 - strlen(str));
|
||||
f = f & (0xFFFFFFFF << bit);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blocksstable
|
||||
} // namespace oceanbase
|
||||
Reference in New Issue
Block a user