440 lines
14 KiB
C++
440 lines
14 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.
|
|
*/
|
|
|
|
#include "storage/memtable/ob_rowkey_codec.h"
|
|
|
|
#include "lib/allocator/page_arena.h"
|
|
#include "common/object/ob_object.h"
|
|
#include "common/rowkey/ob_rowkey.h"
|
|
|
|
#include "utils_rowkey_builder.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
namespace oceanbase
|
|
{
|
|
namespace unittest
|
|
{
|
|
using namespace oceanbase::common;
|
|
using namespace oceanbase::memtable;
|
|
|
|
class ObBuffer
|
|
{
|
|
public:
|
|
ObBuffer() : buf_(NULL), cap_(0), pos_(0) {}
|
|
~ObBuffer()
|
|
{
|
|
if (NULL != buf_)
|
|
{
|
|
delete[] buf_;
|
|
buf_ = NULL;
|
|
}
|
|
}
|
|
public:
|
|
void set_buf(const int64_t cap)
|
|
{
|
|
buf_ = new(std::nothrow) char[cap];
|
|
assert(NULL != buf_);
|
|
cap_ = cap;
|
|
pos_ = 0;
|
|
}
|
|
void reset()
|
|
{
|
|
if (NULL != buf_)
|
|
{
|
|
delete[] buf_;
|
|
buf_ = NULL;
|
|
}
|
|
cap_ = 0;
|
|
pos_ = 0;
|
|
}
|
|
public:
|
|
char *get_data() const { return buf_; }
|
|
int64_t get_capacity() const { return cap_; }
|
|
int64_t &get_capacity() { return cap_; }
|
|
int64_t &get_position() { return pos_; }
|
|
private:
|
|
char *buf_;
|
|
int64_t cap_;
|
|
int64_t pos_;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void test_decode_encode(const ObRowkeyWrapper &rkw)
|
|
{
|
|
static const int64_t VALID_BUFFER_SIZE = 1<<21;
|
|
static const int64_t LOOP_TIMES = 100;
|
|
|
|
ObBuffer src_buffer;
|
|
ObBuffer dst_buffer;
|
|
int ret = OB_SUCCESS;
|
|
|
|
src_buffer.set_buf(VALID_BUFFER_SIZE);
|
|
for (int64_t i = 0; i < LOOP_TIMES; ++i)
|
|
{
|
|
int64_t encode_orig_pos = src_buffer.get_position();
|
|
|
|
ret = encode_table_id(i, src_buffer);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
ret = encode_rowkey_len(static_cast<uint8_t>(rkw.get_obj_cnt()), src_buffer);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
ret = encode_compact_rowkey(rkw.get_rowkey(), src_buffer);
|
|
if (OB_FAIL(ret)) abort();
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
dst_buffer.set_buf(VALID_BUFFER_SIZE);
|
|
for (int64_t j = 0; j < LOOP_TIMES; ++j)
|
|
{
|
|
int64_t decode_orig_pos = src_buffer.get_position();
|
|
src_buffer.get_position() = encode_orig_pos;
|
|
|
|
uint64_t table_id = 0;
|
|
ret = decode_table_id(table_id, src_buffer);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_EQ(static_cast<int64_t>(table_id), i);
|
|
|
|
uint8_t rk_len = 0;
|
|
ret = decode_rowkey_len(rk_len, src_buffer);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObRowkeyWrapper decode_rkw(rk_len);
|
|
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_EQ(rkw.get_rowkey(), decode_rkw.get_rowkey());
|
|
ASSERT_EQ(decode_orig_pos, src_buffer.get_position());
|
|
if (rkw.get_rowkey() != decode_rkw.get_rowkey())
|
|
{
|
|
TRANS_LOG(WARN, "NE::", "\nrk1", rkw.get_rowkey(), "\nrk2", decode_rkw.get_rowkey());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST(TestObRowkeyCodec, test_encode_decode_normal)
|
|
{
|
|
test_decode_encode(
|
|
RK(
|
|
V("hello", 5),
|
|
V(NULL, 0),
|
|
I(1024),
|
|
N("3.14"),
|
|
//B(true),
|
|
//T(::oceanbase::common::ObTimeUtility::current_time()),
|
|
U(),
|
|
OBMIN(),
|
|
OBMAX(),
|
|
V("world", 5),
|
|
V(NULL, 0),
|
|
I(-1024),
|
|
N("-3.14"),
|
|
//B(false),
|
|
//T(-::oceanbase::common::ObTimeUtility::current_time()),
|
|
U(),
|
|
OBMIN(),
|
|
OBMAX()
|
|
));
|
|
|
|
int64_t v = 0x0100abcd01001234;
|
|
test_decode_encode(
|
|
RK(
|
|
V(NULL, 0),
|
|
V(reinterpret_cast<char *>(&v), 1),
|
|
V(reinterpret_cast<char *>(&v), 2),
|
|
V(reinterpret_cast<char *>(&v), 3),
|
|
V(reinterpret_cast<char *>(&v), 4),
|
|
V(reinterpret_cast<char *>(&v), 5),
|
|
V(reinterpret_cast<char *>(&v), 6),
|
|
V(reinterpret_cast<char *>(&v), 7),
|
|
V(reinterpret_cast<char *>(&v), 8)
|
|
));
|
|
|
|
test_decode_encode(
|
|
RK(
|
|
N("3.14"),
|
|
N("-3.14"),
|
|
N("0"),
|
|
N("999999999999999999999999999999999999999999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
|
|
N("-999999999999999999999999999999999999999999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
|
|
N("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"),
|
|
N("-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"),
|
|
N("1.23456789123456789123456789123456789123456789123456789"),
|
|
N("-1.23456789123456789123456789123456789123456789123456789"),
|
|
N("12345678912345678912345678912345678912345678.9123456789"),
|
|
N("-12345678912345678912345678912345678912345678.9123456789")
|
|
));
|
|
}
|
|
|
|
TEST(TestObRowkeyCodec, test_encode_decode_abnormal)
|
|
{
|
|
ObBuffer src_buffer;
|
|
ObBuffer dst_buffer;
|
|
int ret = OB_SUCCESS;
|
|
|
|
RK rkw_e(E(RF_DELETE));
|
|
uint8_t rk_len = 1;
|
|
uint64_t table_id = 1000;
|
|
|
|
RK rkw_v(V("hello", 5));
|
|
RK rkw_n(N("3.141593"));
|
|
RK rkw_i(I(1024));
|
|
//RK rkw_t(T(::oceanbase::common::ObTimeUtility::current_time()));
|
|
//RK rkw_b(B(true));
|
|
|
|
// null pointer, invalid param
|
|
src_buffer.reset();
|
|
ret = encode_compact_rowkey(rkw_v.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
// buffer not enough
|
|
src_buffer.set_buf(3);
|
|
src_buffer.get_position() = 0;
|
|
ret = encode_compact_rowkey(rkw_v.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
src_buffer.get_position() = 3;
|
|
ret = encode_compact_rowkey(rkw_v.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
|
|
// null pointer, invalid param
|
|
src_buffer.reset();
|
|
ret = encode_compact_rowkey(rkw_n.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
// buffer not enough
|
|
src_buffer.set_buf(3);
|
|
src_buffer.get_position() = 0;
|
|
ret = encode_compact_rowkey(rkw_n.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
src_buffer.get_position() = 3;
|
|
ret = encode_compact_rowkey(rkw_n.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
|
|
// null pointer, invalid param
|
|
src_buffer.reset();
|
|
ret = encode_compact_rowkey(rkw_i.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
// buffer not enough
|
|
src_buffer.set_buf(3);
|
|
src_buffer.get_position() = 0;
|
|
ret = encode_compact_rowkey(rkw_i.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
src_buffer.get_position() = 3;
|
|
ret = encode_compact_rowkey(rkw_i.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
|
|
//// null pointer, invalid param
|
|
//src_buffer.reset();
|
|
//ret = encode_compact_rowkey(rkw_i.get_rowkey(), src_buffer);
|
|
//EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
//// buffer not enough
|
|
//src_buffer.set_buf(3);
|
|
//src_buffer.get_position() = 0;
|
|
//ret = encode_compact_rowkey(rkw_t.get_rowkey(), src_buffer);
|
|
//EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
//EXPECT_EQ(0, src_buffer.get_position());
|
|
//src_buffer.get_position() = 3;
|
|
//ret = encode_compact_rowkey(rkw_t.get_rowkey(), src_buffer);
|
|
//EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
|
|
//// null pointer, invalid param
|
|
//src_buffer.reset();
|
|
//ret = encode_compact_rowkey(rkw_b.get_rowkey(), src_buffer);
|
|
//EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
//// buffer not enough
|
|
//src_buffer.set_buf(1);
|
|
//src_buffer.get_position() = 0;
|
|
//ret = encode_compact_rowkey(rkw_b.get_rowkey(), src_buffer);
|
|
//EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
//EXPECT_EQ(0, src_buffer.get_position());
|
|
//src_buffer.get_position() = 1;
|
|
//ret = encode_compact_rowkey(rkw_b.get_rowkey(), src_buffer);
|
|
//EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
|
|
// not supported
|
|
ret = encode_compact_rowkey(rkw_e.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_NOT_SUPPORTED, ret);
|
|
|
|
//////////////////////////////
|
|
|
|
// null pointer, invalid param
|
|
src_buffer.reset();
|
|
ret = encode_rowkey_len(rk_len, src_buffer);
|
|
EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
|
|
// buffer not enough
|
|
src_buffer.set_buf(1);
|
|
src_buffer.get_position() = 1;
|
|
ret = encode_rowkey_len(rk_len, src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
|
|
// null pointer, invalid param
|
|
src_buffer.reset();
|
|
ret = encode_table_id(table_id, src_buffer);
|
|
EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
|
|
// buffer not enough
|
|
src_buffer.set_buf(3);
|
|
src_buffer.get_position() = 1;
|
|
ret = encode_table_id(table_id, src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(1, src_buffer.get_position());
|
|
|
|
// decode rowkey len
|
|
src_buffer.set_buf(2);
|
|
ret = encode_rowkey_len(rk_len, src_buffer);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(1, src_buffer.get_position());
|
|
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 0;
|
|
ret = decode_rowkey_len(rk_len, src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
|
|
// decode table id
|
|
src_buffer.set_buf(3);
|
|
ret = encode_table_id(table_id, src_buffer);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(3, src_buffer.get_position());
|
|
|
|
// src buffer not integrity
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 1;
|
|
ret = decode_table_id(table_id, src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
|
|
// src buffer not integrity
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 2;
|
|
ret = decode_table_id(table_id, src_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
|
|
//////////////////////////////
|
|
|
|
ObRowkeyWrapper decode_rkw(1);
|
|
int64_t v = 0x0100abcddcba0001;
|
|
RK rkw_v4decode(V(reinterpret_cast<char *>(&v), 3));
|
|
|
|
src_buffer.set_buf(7);
|
|
ret = encode_compact_rowkey(rkw_v4decode.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(7, src_buffer.get_position());
|
|
|
|
// check position after decode
|
|
dst_buffer.set_buf(7);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 7;
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(7, src_buffer.get_position());
|
|
EXPECT_EQ(3, dst_buffer.get_position());
|
|
|
|
// dst buffer not enough
|
|
dst_buffer.set_buf(2);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 7;
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
|
|
// src buffer not integrity
|
|
dst_buffer.set_buf(7);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 1;
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
|
|
// src buffer not integrity
|
|
dst_buffer.set_buf(7);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 2;
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
|
|
// src buffer break
|
|
dst_buffer.set_buf(7);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 7;
|
|
src_buffer.get_data()[6] = '\2';
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
|
|
// invalid type
|
|
dst_buffer.set_buf(7);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 7;
|
|
src_buffer.get_data()[0] = static_cast<char>(0xff - 1);
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_NOT_SUPPORTED, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
|
|
//////////////////////////////
|
|
|
|
RK rkw_i4decode(I(0x0100abcd));
|
|
|
|
src_buffer.set_buf(6);
|
|
ret = encode_compact_rowkey(rkw_i4decode.get_rowkey(), src_buffer);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(6, src_buffer.get_position());
|
|
|
|
// check position after decode
|
|
dst_buffer.set_buf(6);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 6;
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_SUCCESS, ret);
|
|
EXPECT_EQ(6, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
|
|
// src buffer not integrity
|
|
dst_buffer.set_buf(6);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 1;
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
|
|
// src buffer not integrity
|
|
dst_buffer.set_buf(6);
|
|
src_buffer.get_position() = 0;
|
|
src_buffer.get_capacity() = 2;
|
|
ret = decode_compact_rowkey(decode_rkw.get_rowkey(), src_buffer, dst_buffer);
|
|
EXPECT_EQ(OB_BUF_NOT_ENOUGH, ret);
|
|
EXPECT_EQ(0, src_buffer.get_position());
|
|
EXPECT_EQ(0, dst_buffer.get_position());
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
oceanbase::common::ObLogger::get_logger().set_file_name("test_rowkey_codec.log", true);
|
|
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|