/** * 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 OCEANBASE_UNITTEST_MEMTABLE_ROWKEY_BUILDER_H_ #define OCEANBASE_UNITTEST_MEMTABLE_ROWKEY_BUILDER_H_ #include "lib/allocator/page_arena.h" #include "lib/container/ob_iarray.h" #include "lib/container/ob_se_array.h" #include "common/object/ob_object.h" #include "common/rowkey/ob_store_rowkey.h" #include "share/schema/ob_table_schema.h" namespace oceanbase { namespace unittest { using namespace oceanbase::common; class ObStoreRowkeyWrapper { public: template ObStoreRowkeyWrapper(const Args&... args) : obj_cnt_(0) { fill(args...); } ObStoreRowkeyWrapper(const uint8_t obj_cnt) : obj_cnt_(obj_cnt) {} ObStoreRowkeyWrapper(const int32_t obj_cnt) : obj_cnt_(obj_cnt) {} ~ObStoreRowkeyWrapper() {} public: CharArena& get_allocator() { return allocator_; } ObObj& get_cur_obj() { return objs_[obj_cnt_]; } ObObj& get_obj(int64_t idx) { return objs_[idx]; } int64_t get_obj_cnt() const { return obj_cnt_; } void add_obj() { obj_cnt_++; } ObStoreRowkey& get_rowkey() { return rowkey_ = ObStoreRowkey(objs_, obj_cnt_); } const ObStoreRowkey& get_rowkey() const { return rowkey_ = ObStoreRowkey(objs_, obj_cnt_); } private: template void fill(const T& head, const Args&... args) { head.build(*this); fill(args...); } void fill() { /*for recursion exit*/ } private: CharArena allocator_; mutable ObObj objs_[OB_MAX_ROWKEY_COLUMN_NUMBER]; int64_t obj_cnt_; mutable ObStoreRowkey rowkey_; }; class ObColumnDesc { public: template ObColumnDesc(const Args&... args) { fill(args...); } const ObIArray& get_columns() const { return columns_; } private: template void fill(const uint64_t col_id, const ObObjType col_type, const ObCollationType col_collation, const Args&... args) { share::schema::ObColDesc col_desc; col_desc.col_id_ = col_id; col_desc.col_type_.set_type(col_type); col_desc.col_type_.set_collation_type(col_collation); columns_.push_back(col_desc); fill(args...); } void fill() { /*for recursion exit*/ } private: ObSEArray columns_; }; //////////////////////////////////////////////////////////////////////////////////////////////////// #define DEFINE_TYPE_OBJ(classname, ctype, obtype) \ class classname { \ public: \ classname(const ctype v) : v_(v) \ {} \ ~classname() \ {} \ \ public: \ void build(ObStoreRowkeyWrapper& rowkey_wrapper) const \ { \ rowkey_wrapper.get_cur_obj().set_##obtype(v_); \ rowkey_wrapper.add_obj(); \ } \ \ private: \ const ctype v_; \ }; #define DEFINE_CHARTYPE_OBJ(classname, obtype, cltype) \ class classname { \ public: \ classname(const char* str, const int64_t len, const ObCollationType cltype = CS_TYPE_UTF8MB4_BIN) \ : str_(str), len_(len), cltype_(cltype) \ {} \ ~classname() \ {} \ \ public: \ void build(ObStoreRowkeyWrapper& rowkey_wrapper) const \ { \ ObString obstr; \ obstr.assign_ptr(const_cast(str_), static_cast(len_)); \ rowkey_wrapper.get_cur_obj().set_##obtype(obstr); \ rowkey_wrapper.get_cur_obj().set_collation_type(cltype_); \ rowkey_wrapper.add_obj(); \ } \ \ private: \ const char* str_; \ const int64_t len_; \ const ObCollationType cltype_; \ }; #define DEFINE_NMBTYPE_OBJ(classname, obtype) \ class classname { \ public: \ classname(const char* str) : str_(str) \ {} \ ~classname() \ {} \ \ public: \ void build(ObStoreRowkeyWrapper& rowkey_wrapper) const \ { \ number::ObNumber obnmb; \ obnmb.from(str_, rowkey_wrapper.get_allocator()); \ rowkey_wrapper.get_cur_obj().set_##obtype(obnmb); \ rowkey_wrapper.add_obj(); \ } \ \ private: \ const char* str_; \ }; class U { public: U() {} ~U() {} public: void build(ObStoreRowkeyWrapper& rowkey_wrapper) const { rowkey_wrapper.get_cur_obj().set_null(); rowkey_wrapper.add_obj(); } }; class OBMIN { public: OBMIN() {} ~OBMIN() {} public: void build(ObStoreRowkeyWrapper& rowkey_wrapper) const { rowkey_wrapper.get_cur_obj().set_ext(ObObj::MIN_OBJECT_VALUE); rowkey_wrapper.add_obj(); } }; class OBMAX { public: OBMAX() {} ~OBMAX() {} public: void build(ObStoreRowkeyWrapper& rowkey_wrapper) const { rowkey_wrapper.get_cur_obj().set_ext(ObObj::MAX_OBJECT_VALUE); rowkey_wrapper.add_obj(); } }; DEFINE_TYPE_OBJ(IT, int8_t, tinyint) DEFINE_TYPE_OBJ(IS, int16_t, smallint) DEFINE_TYPE_OBJ(IM, int32_t, mediumint) DEFINE_TYPE_OBJ(I32, int32_t, int32) DEFINE_TYPE_OBJ(I, int64_t, int) DEFINE_TYPE_OBJ(UIT, uint8_t, utinyint) DEFINE_TYPE_OBJ(UIS, uint16_t, usmallint) DEFINE_TYPE_OBJ(UIM, uint32_t, umediumint) DEFINE_TYPE_OBJ(UI32, uint32_t, uint32) DEFINE_TYPE_OBJ(UI, uint64_t, uint64) DEFINE_TYPE_OBJ(F, float, float) DEFINE_TYPE_OBJ(D, double, double) DEFINE_TYPE_OBJ(UF, float, ufloat) DEFINE_TYPE_OBJ(UD, double, udouble) DEFINE_NMBTYPE_OBJ(N, number) DEFINE_NMBTYPE_OBJ(UN, unumber) DEFINE_TYPE_OBJ(T, int64_t, datetime) DEFINE_TYPE_OBJ(TS, int64_t, timestamp) DEFINE_TYPE_OBJ(DD, int32_t, date) DEFINE_TYPE_OBJ(TT, int64_t, time) DEFINE_TYPE_OBJ(YY, uint8_t, year) DEFINE_CHARTYPE_OBJ(V, varchar, ObCollationType) DEFINE_CHARTYPE_OBJ(C, char, ObCollationType) DEFINE_CHARTYPE_OBJ(VB, varbinary, ObCollationType) DEFINE_CHARTYPE_OBJ(BB, binary, ObCollationType) typedef ObStoreRowkeyWrapper RK; typedef ObColumnDesc CD; #define INIT_MTK(allocator, mtk, table_id, ...) \ { \ RK _rkb_(__VA_ARGS__); \ ObMemtableKey tmp_mtk; \ int ret = tmp_mtk.encode(table_id, &(_rkb_.get_rowkey())); \ EXPECT_EQ(OB_SUCCESS, ret); \ ret = tmp_mtk.dup(mtk, allocator); \ EXPECT_EQ(OB_SUCCESS, ret); \ } } // namespace unittest } // namespace oceanbase #endif // OCEANBASE_UNITTEST_MEMTABLE_ROWKEY_BUILDER_H_