patch 4.0
This commit is contained in:
@ -12,10 +12,12 @@
|
||||
|
||||
#include "storage/ob_row_fuse.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace oceanbase::common;
|
||||
namespace storage {
|
||||
int ObNopPos::init(ObIAllocator& allocator, const int64_t capacity)
|
||||
namespace storage
|
||||
{
|
||||
int ObNopPos::init(ObIAllocator &allocator, const int64_t capacity)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (capacity <= 0) {
|
||||
@ -25,7 +27,8 @@ int ObNopPos::init(ObIAllocator& allocator, const int64_t capacity)
|
||||
if (capacity <= capacity_) {
|
||||
} else {
|
||||
free();
|
||||
if (NULL == (nops_ = static_cast<int16_t*>(allocator.alloc(sizeof(int16_t) * capacity)))) {
|
||||
if (NULL == (nops_ = static_cast<int16_t*>(allocator.alloc(
|
||||
sizeof(int16_t) * capacity)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
STORAGE_LOG(ERROR, "no memory", K(ret), K(capacity));
|
||||
} else {
|
||||
@ -53,7 +56,7 @@ void ObNopPos::destroy()
|
||||
allocator_ = NULL;
|
||||
}
|
||||
|
||||
int ObNopPos::get_nop_pos(const int64_t idx, int64_t& pos)
|
||||
int ObNopPos::get_nop_pos(const int64_t idx, int64_t &pos)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (idx < 0 || idx >= count_) {
|
||||
@ -91,131 +94,38 @@ int ObNopPos::set_nop_pos(const int64_t idx, const int64_t pos)
|
||||
|
||||
ObObjShallowCopy ObRowFuse::shallow_copy_;
|
||||
|
||||
template <typename T>
|
||||
OB_INLINE static int complex_fuse_row(const ObStoreRow& former, ObStoreRow& result, ObNopPos& nop_pos,
|
||||
bool& final_result, const common::ObIArray<int32_t>* col_idxs, bool* column_changed, const int64_t column_count,
|
||||
T& obj_copy)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!former.is_valid()) || OB_ISNULL(result.row_val_.cells_) || !nop_pos.is_valid()) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid arguments, ", K(former), K(result), K(nop_pos.count()), K(ret));
|
||||
} else if (common::ObActionFlag::OP_DEL_ROW != result.flag_) {
|
||||
final_result = false;
|
||||
bool first_val = (0 == result.row_val_.count_ || common::ObActionFlag::OP_ROW_DOES_NOT_EXIST == result.flag_);
|
||||
int64_t cnt = 0;
|
||||
|
||||
if (first_val) {
|
||||
nop_pos.reset();
|
||||
result.flag_ = former.flag_;
|
||||
result.from_base_ = former.from_base_;
|
||||
cnt = (NULL == col_idxs) ? former.row_val_.count_ : col_idxs->count();
|
||||
} else {
|
||||
cnt = nop_pos.count_;
|
||||
}
|
||||
|
||||
if (cnt > column_count && NULL != column_changed) {
|
||||
ret = common::OB_ERR_SYS;
|
||||
STORAGE_LOG(ERROR, "column count not match", K(ret), K(cnt), K(column_count));
|
||||
} else if (common::ObActionFlag::OP_ROW_DOES_NOT_EXIST == former.flag_) {
|
||||
// skip, do nothing
|
||||
} else if (common::ObActionFlag::OP_DEL_ROW == former.flag_) {
|
||||
final_result = true;
|
||||
} else if (common::ObActionFlag::OP_ROW_EXIST == former.flag_) {
|
||||
if (OB_UNLIKELY(common::ObActionFlag::OP_ROW_EXIST == result.flag_ && result.row_val_.is_valid() &&
|
||||
nop_pos.count() > result.row_val_.count_ &&
|
||||
(NULL == col_idxs && result.row_val_.count_ != former.row_val_.count_)) &&
|
||||
(NULL != col_idxs && result.row_val_.count_ != col_idxs->count())) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid arguments", K(ret), K(former), K(result), K(nop_pos.count()), K(*col_idxs));
|
||||
} else {
|
||||
int64_t column_cnt = (NULL == col_idxs) ? former.row_val_.count_ : col_idxs->count();
|
||||
int64_t idx = -1;
|
||||
int64_t left_cnt = 0;
|
||||
int64_t former_idx = -1;
|
||||
bool is_former_nop = true;
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < cnt; i++) {
|
||||
idx = first_val ? i : nop_pos.nops_[i];
|
||||
former_idx = (NULL == col_idxs) ? idx : col_idxs->at(idx);
|
||||
if (former_idx == -1) {
|
||||
// skip the not exist column
|
||||
continue;
|
||||
}
|
||||
is_former_nop = former.row_val_.cells_[former_idx].is_nop_value();
|
||||
|
||||
if (first_val) {
|
||||
if (OB_FAIL(obj_copy(former.row_val_.cells_[former_idx], result.row_val_.cells_[idx]))) {
|
||||
STORAGE_LOG(WARN, "failed to copy obj", K(ret), K(former_idx), K(idx));
|
||||
} else {
|
||||
if (is_former_nop) {
|
||||
nop_pos.nops_[left_cnt++] = static_cast<int16_t>(idx);
|
||||
} else if (NULL != column_changed && !former.from_base_) {
|
||||
column_changed[idx] = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_former_nop) {
|
||||
nop_pos.nops_[left_cnt++] = static_cast<int16_t>(idx);
|
||||
} else {
|
||||
if (OB_FAIL(obj_copy(former.row_val_.cells_[former_idx], result.row_val_.cells_[idx]))) {
|
||||
STORAGE_LOG(WARN, "failed to copy obj", K(ret), K(former_idx), K(idx));
|
||||
} else {
|
||||
if (NULL != column_changed && !former.from_base_) {
|
||||
column_changed[idx] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final_result = (0 == left_cnt);
|
||||
result.row_val_.count_ = column_cnt;
|
||||
nop_pos.count_ = left_cnt;
|
||||
}
|
||||
} else {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "wrong row flag", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
OB_INLINE static int simple_fuse_row(
|
||||
const ObStoreRow& former, ObStoreRow& result, ObNopPos& nop_pos, bool& final_result, T& obj_copy)
|
||||
const ObStoreRow &former,
|
||||
ObStoreRow &result,
|
||||
ObNopPos &nop_pos,
|
||||
bool &final_result,
|
||||
T &obj_copy)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!former.is_valid()) || OB_ISNULL(result.row_val_.cells_) || !nop_pos.is_valid()) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN,
|
||||
"Invalid arguments, ",
|
||||
K(former),
|
||||
K(former.is_valid()),
|
||||
KP(result.row_val_.cells_),
|
||||
K(nop_pos.count()),
|
||||
K(nop_pos.capacity()),
|
||||
K(ret));
|
||||
} else if (common::ObActionFlag::OP_DEL_ROW == result.flag_ ||
|
||||
common::ObActionFlag::OP_ROW_DOES_NOT_EXIST == former.flag_) {
|
||||
STORAGE_LOG(WARN, "Invalid arguments, ", K(former), K(former.is_valid()), KP(result.row_val_.cells_), K(nop_pos.count()), K(nop_pos.capacity()), K(ret));
|
||||
} else if (result.flag_.is_delete() || former.flag_.is_not_exist()) {
|
||||
// do nothing
|
||||
} else {
|
||||
final_result = false;
|
||||
bool first_val = (0 == result.row_val_.count_ || common::ObActionFlag::OP_ROW_DOES_NOT_EXIST == result.flag_);
|
||||
bool first_val = (0 == result.row_val_.count_ || result.flag_.is_not_exist());
|
||||
int64_t column_cnt = 0;
|
||||
|
||||
if (first_val) {
|
||||
nop_pos.reset();
|
||||
result.flag_ = former.flag_;
|
||||
result.from_base_ = former.from_base_;
|
||||
result.dml_ = former.dml_;
|
||||
column_cnt = former.row_val_.count_;
|
||||
} else {
|
||||
column_cnt = nop_pos.count_;
|
||||
}
|
||||
|
||||
if (common::ObActionFlag::OP_DEL_ROW == former.flag_) {
|
||||
if (former.flag_.is_delete()) {
|
||||
final_result = true;
|
||||
if (first_val) { // copy rowkey
|
||||
if (first_val) { // copy rowkey
|
||||
result.row_val_.count_ = former.row_val_.count_;
|
||||
for (int i = 0; OB_SUCC(ret) && i < former.row_val_.count_; ++i) {
|
||||
if (OB_FAIL(obj_copy(former.row_val_.cells_[i], result.row_val_.cells_[i]))) {
|
||||
@ -223,9 +133,11 @@ OB_INLINE static int simple_fuse_row(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (common::ObActionFlag::OP_ROW_EXIST == former.flag_) {
|
||||
if (OB_UNLIKELY(common::ObActionFlag::OP_ROW_EXIST == result.flag_ && result.row_val_.is_valid() &&
|
||||
nop_pos.count() > result.row_val_.count_ && result.row_val_.count_ != former.row_val_.count_)) {
|
||||
} else if (former.flag_.is_exist_without_delete()) {
|
||||
if (OB_UNLIKELY(result.flag_.is_exist_without_delete()
|
||||
&& result.row_val_.is_valid()
|
||||
&& nop_pos.count() > result.row_val_.count_
|
||||
&& result.row_val_.count_ != former.row_val_.count_)) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid arguments", K(ret), K(former), K(result), K(nop_pos.count()));
|
||||
} else {
|
||||
@ -252,47 +164,17 @@ OB_INLINE static int simple_fuse_row(
|
||||
}
|
||||
} else {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "wrong row flag", K(ret));
|
||||
STORAGE_LOG(WARN, "wrong row flag", K(ret), K(former));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRowFuse::fuse_row(const ObStoreRow& former, ObStoreRow& result, ObNopPos& nop_pos, bool& final_result,
|
||||
const common::ObIArray<int32_t>* col_idxs, bool* column_changed, const int64_t column_count,
|
||||
ObObjDeepCopy* obj_copy)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (nullptr == obj_copy) {
|
||||
if (OB_FAIL(complex_fuse_row(
|
||||
former, result, nop_pos, final_result, col_idxs, column_changed, column_count, shallow_copy_))) {
|
||||
STORAGE_LOG(WARN,
|
||||
"fail to fuse complex row with shallow copy",
|
||||
K(ret),
|
||||
K(former),
|
||||
K(result),
|
||||
KP(col_idxs),
|
||||
KP(column_changed),
|
||||
K(column_count));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(complex_fuse_row(
|
||||
former, result, nop_pos, final_result, col_idxs, column_changed, column_count, *obj_copy))) {
|
||||
STORAGE_LOG(WARN,
|
||||
"fail to fuse complex row with deep copy",
|
||||
K(ret),
|
||||
K(former),
|
||||
K(result),
|
||||
KP(col_idxs),
|
||||
KP(column_changed),
|
||||
K(column_count));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRowFuse::fuse_row(
|
||||
const ObStoreRow& former, ObStoreRow& result, ObNopPos& nop_pos, bool& final_result, ObObjDeepCopy* obj_copy)
|
||||
int ObRowFuse::fuse_row(const ObStoreRow &former,
|
||||
ObStoreRow &result,
|
||||
ObNopPos &nop_pos,
|
||||
bool &final_result,
|
||||
ObObjDeepCopy *obj_copy)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (nullptr == obj_copy) {
|
||||
@ -307,95 +189,82 @@ int ObRowFuse::fuse_row(
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
OB_INLINE static int simple_fuse_sparse_row(const ObStoreRow& former, ObStoreRow& result,
|
||||
ObFixedBitSet<OB_ALL_MAX_COLUMN_ID>& bit_set, bool& final_result, T& obj_copy)
|
||||
int ObRowFuse::fuse_row(const blocksstable::ObDatumRow &former,
|
||||
blocksstable::ObDatumRow &result,
|
||||
ObNopPos &nop_pos,
|
||||
bool &final_result,
|
||||
ObIAllocator *allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!former.is_valid()) || OB_ISNULL(result.row_val_.cells_) || OB_ISNULL(result.column_ids_)) {
|
||||
if (OB_UNLIKELY(!former.is_valid() || !result.is_valid() || !nop_pos.is_valid())) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid arguments, ", K(former), K(former.is_valid()), K(result), K(ret));
|
||||
} else if (common::ObActionFlag::OP_DEL_ROW == result.flag_ ||
|
||||
common::ObActionFlag::OP_ROW_DOES_NOT_EXIST == former.flag_) {
|
||||
STORAGE_LOG(WARN, "Invalid arguments, ", K(former), K(result), K(nop_pos.count()), K(nop_pos.capacity()), K(ret));
|
||||
} else if (result.row_flag_.is_delete() || former.row_flag_.is_not_exist()) {
|
||||
// do nothing
|
||||
} else {
|
||||
result.is_sparse_row_ = true; // set sparse row flag
|
||||
if (0 == result.row_val_.count_ || common::ObActionFlag::OP_ROW_DOES_NOT_EXIST == result.flag_) {
|
||||
result.flag_ = former.flag_;
|
||||
result.from_base_ = former.from_base_;
|
||||
bit_set.reset();
|
||||
final_result = false;
|
||||
bool first_val = (0 == result.count_ || result.row_flag_.is_not_exist());
|
||||
int64_t column_cnt = 0;
|
||||
|
||||
if (first_val) {
|
||||
nop_pos.reset();
|
||||
result.row_flag_ = former.row_flag_;
|
||||
column_cnt = former.count_;
|
||||
} else {
|
||||
column_cnt = nop_pos.count_;
|
||||
}
|
||||
|
||||
if (common::ObActionFlag::OP_DEL_ROW == former.flag_) {
|
||||
if (former.row_flag_.is_delete()) {
|
||||
final_result = true;
|
||||
if (0 == result.row_val_.count_) { // copy rowkey
|
||||
for (int i = 0; OB_SUCC(ret) && i < former.row_val_.count_; ++i) {
|
||||
if (OB_FAIL(obj_copy(former.row_val_.cells_[i], result.row_val_.cells_[i]))) {
|
||||
STORAGE_LOG(WARN, "failed to copy obj", K(ret), K(i), K(former.row_val_.cells_[i]));
|
||||
} else {
|
||||
result.column_ids_[i] = former.column_ids_[i];
|
||||
if (first_val) { // copy rowkey
|
||||
result.count_ = former.count_;
|
||||
for (int i = 0; OB_SUCC(ret) && i < former.count_; ++i) {
|
||||
if (OB_ISNULL(allocator)) {
|
||||
result.storage_datums_[i] = former.storage_datums_[i];
|
||||
} else if (OB_FAIL(result.storage_datums_[i].deep_copy(former.storage_datums_[i], *allocator))) {
|
||||
STORAGE_LOG(WARN, "Failed to deep copy storage datum", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
result.row_val_.count_ = former.row_val_.count_;
|
||||
}
|
||||
} else if (former.row_flag_.is_exist_without_delete()) {
|
||||
if (OB_UNLIKELY(result.row_flag_.is_exist_without_delete()
|
||||
&& result.is_valid()
|
||||
&& nop_pos.count() > result.count_
|
||||
&& result.count_ != former.count_)) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "Invalid arguments", K(ret), K(former), K(result), K(nop_pos.count()));
|
||||
} else {
|
||||
STORAGE_LOG(DEBUG, "start to fuse", K(former), K(result), K(nop_pos.count()));
|
||||
int64_t idx = -1;
|
||||
int64_t left_cnt = 0;
|
||||
bool is_former_nop = true;
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < column_cnt; i++) {
|
||||
idx = first_val ? i : nop_pos.nops_[i];
|
||||
is_former_nop = former.storage_datums_[idx].is_nop();
|
||||
if (is_former_nop) {
|
||||
nop_pos.nops_[left_cnt++] = static_cast<int16_t>(idx);
|
||||
}
|
||||
if (is_former_nop && !first_val) {
|
||||
// do nothing
|
||||
} else if (OB_ISNULL(allocator)) {
|
||||
result.storage_datums_[idx] = former.storage_datums_[idx];
|
||||
} else if (OB_FAIL(result.storage_datums_[idx].deep_copy(former.storage_datums_[idx], *allocator))) {
|
||||
STORAGE_LOG(WARN, "Failed to deep copy storage datum", K(ret), K(idx));
|
||||
}
|
||||
}
|
||||
final_result = (0 == left_cnt);
|
||||
result.count_ = former.count_;
|
||||
nop_pos.count_ = left_cnt;
|
||||
}
|
||||
} else {
|
||||
int index_cnt = result.row_val_.count_; // next write index in result row
|
||||
bool found = true;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < former.row_val_.count_; i++) { // loop former row
|
||||
found = bit_set.has_member(former.column_ids_[i]);
|
||||
if (!found) { // not found in result row
|
||||
if (index_cnt > result.capacity_) {
|
||||
ret = OB_BUF_NOT_ENOUGH;
|
||||
STORAGE_LOG(WARN,
|
||||
"input row count is not enough",
|
||||
K(ret),
|
||||
K(index_cnt),
|
||||
K(result.row_val_.count_),
|
||||
K(result.capacity_));
|
||||
} else if (OB_FAIL(obj_copy(former.row_val_.cells_[i], result.row_val_.cells_[index_cnt]))) {
|
||||
STORAGE_LOG(WARN, "failed to copy obj", K(ret), K(i), K(index_cnt));
|
||||
} else if (OB_FAIL(bit_set.add_member(former.column_ids_[i]))) { // add column id into set
|
||||
STORAGE_LOG(WARN, "add column id into set failed", K(ret), K(i), K(former.column_ids_[i]));
|
||||
} else {
|
||||
result.column_ids_[index_cnt] = former.column_ids_[i];
|
||||
STORAGE_LOG(DEBUG,
|
||||
"add col",
|
||||
K(index_cnt),
|
||||
K(result.column_ids_[index_cnt]),
|
||||
K(result.column_ids_[index_cnt]),
|
||||
K(former.row_val_.cells_[i]),
|
||||
K(result.row_val_.cells_[index_cnt]));
|
||||
index_cnt++; // move forward
|
||||
}
|
||||
} else { // found in result row
|
||||
STORAGE_LOG(DEBUG, "already had col", K(former.column_ids_[i]), K(i));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) { // set result row count
|
||||
result.row_val_.count_ = index_cnt;
|
||||
}
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
STORAGE_LOG(WARN, "wrong row flag", K(ret), K(former));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRowFuse::fuse_sparse_row(const ObStoreRow& former, ObStoreRow& result,
|
||||
ObFixedBitSet<OB_ALL_MAX_COLUMN_ID>& bit_set, bool& final_result, ObObjDeepCopy* obj_copy)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (nullptr == obj_copy) {
|
||||
if (OB_FAIL(simple_fuse_sparse_row(former, result, bit_set, final_result, shallow_copy_))) {
|
||||
STORAGE_LOG(WARN, "fail to fuse simple row with shallow copy", K(ret), K(former), K(result));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(simple_fuse_sparse_row(former, result, bit_set, final_result, *obj_copy))) {
|
||||
STORAGE_LOG(WARN, "fail to fuse simple row with deep copy", K(ret), K(former), K(result));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace storage
|
||||
} // namespace oceanbase
|
||||
} // namespace storage
|
||||
} // namespace oceanbase
|
||||
|
||||
Reference in New Issue
Block a user