| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| #include "meta-store/keys.h" | |
| #include <bthread/bthread.h> | |
| #include <bthread/countdown_event.h> | |
| #include <gtest/gtest.h> | |
| #include <cstdint> | |
| #include <cstring> | |
| #include <iostream> | |
| #include <limits> | |
| #include <type_traits> | |
| #include <utility> | |
| #include <vector> | |
| #include "common/util.h" | |
| #include "meta-store/codec.h" | |
| #include "meta-store/versionstamp.h" | |
| int main(int argc, char** argv) { | |
| ::testing::InitGoogleTest(&argc, argv); | |
| return RUN_ALL_TESTS(); | |
| } | |
| static void remove_user_space_prefix(std::string_view* key_sv) { | |
| ASSERT_EQ(key_sv->front(), 0x01); | |
| key_sv->remove_prefix(1); | |
| } | |
| static void remove_system_space_prefix(std::string_view* key_sv) { | |
| ASSERT_EQ(key_sv->front(), 0x02); | |
| key_sv->remove_prefix(1); | |
| } | |
| static void remove_versioned_space_prefix(std::string_view* key_sv) { | |
| ASSERT_EQ(key_sv->front(), 0x03); | |
| key_sv->remove_prefix(1); | |
| } | |
| // extern | |
| namespace doris::cloud { | |
| void encode_int64(int64_t val, std::string* b); | |
| int decode_int64(std::string_view* in, int64_t* val); | |
| void encode_bytes(std::string_view bytes, std::string* b); | |
| int decode_bytes(std::string_view* in, std::string* out); | |
| } // namespace doris::cloud | |
| TEST(KeysTest, InstanceKeyTest) { | |
| using namespace doris::cloud; | |
| // instance key | |
| // 0x01 "instance" ${instance_id} | |
| std::string instance_id = "instance_id_deadbeef"; | |
| InstanceKeyInfo inst_key {instance_id}; | |
| std::string encoded_instance_key; | |
| instance_key(inst_key, &encoded_instance_key); | |
| std::string dec_instance_id; | |
| std::string_view key_sv(encoded_instance_key); | |
| std::string dec_instance_prefix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("instance", dec_instance_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| TEST(KeysTest, FixedEncodingGoldenTest) { | |
| using namespace doris::cloud; | |
| static_assert(!std::is_convertible_v<MetaRowsetKeyInfo, MetaRowsetTmpKeyInfo>); | |
| static_assert(std::is_constructible_v<MetaRowsetTmpKeyInfo, MetaRowsetKeyInfo>); | |
| EXPECT_EQ(hex(txn_tso_fence_key({"gavin-instance"})), | |
| "011074786e000110676176696e2d696e7374616e636500011074736f5f66656e63650001"); | |
| EXPECT_EQ(hex(mow_tablet_job_key({"gavin-instance", 10086, 10010})), | |
| "01106d657461000110676176696e2d696e7374616e63650001106d6f775f7461626c65745f" | |
| "6a6f62000112000000000000276612000000000000271a"); | |
| EXPECT_EQ(hex(storage_vault_key({"gavin-instance", "vault-id"})), | |
| "011073746f726167655f7661756c74000110676176696e2d696e7374616e6365000110766175" | |
| "6c740001107661756c742d69640001"); | |
| EXPECT_EQ(hex(meta_schema_pb_dictionary_key({"gavin-instance", 10086})), | |
| "01106d657461000110676176696e2d696e7374616e63650001107461626c65745f736368656d" | |
| "615f70625f646963740001120000000000002766"); | |
| const std::string table_stream_key = | |
| table_stream_offset_key({"gavin-instance", 10000, 20000, 30000, 40000, 50000}); | |
| const std::string table_stream_prefix = | |
| table_stream_offset_key_prefix("gavin-instance", 10000, 20000, 30000, 40000); | |
| EXPECT_EQ(hex(table_stream_key), | |
| "01106d657461000110676176696e2d696e7374616e63650001107461626c655f73747265616d" | |
| "5f6f66667365740001120000000000002710120000000000004e201200000000000075301200" | |
| "00000000009c4012000000000000c350"); | |
| EXPECT_EQ(hex(table_stream_prefix), | |
| "01106d657461000110676176696e2d696e7374616e63650001107461626c655f73747265616d" | |
| "5f6f66667365740001120000000000002710120000000000004e201200000000000075301200" | |
| "00000000009c40"); | |
| EXPECT_TRUE(table_stream_key.starts_with(table_stream_prefix)); | |
| const std::string versioned_table_stream_key = versioned::table_stream_offset_key( | |
| {"gavin-instance", 10000, 20000, 30000, 40000, 50000}); | |
| const std::string versioned_table_stream_prefix = | |
| versioned::table_stream_offset_key_prefix("gavin-instance", 10000, 20000, 30000, 40000); | |
| EXPECT_EQ(hex(versioned_table_stream_key), | |
| "03106d657461000110676176696e2d696e7374616e63650001107461626c655f73747265616d" | |
| "5f6f66667365740001120000000000002710120000000000004e201200000000000075301200" | |
| "00000000009c4012000000000000c350"); | |
| EXPECT_EQ(hex(versioned_table_stream_prefix), | |
| "03106d657461000110676176696e2d696e7374616e63650001107461626c655f73747265616d" | |
| "5f6f66667365740001120000000000002710120000000000004e201200000000000075301200" | |
| "00000000009c40"); | |
| EXPECT_TRUE(versioned_table_stream_key.starts_with(versioned_table_stream_prefix)); | |
| const std::string all_partitions_lock = | |
| meta_delete_bitmap_update_lock_key({"gavin-instance", 10086, -1}); | |
| EXPECT_EQ(hex(all_partitions_lock), | |
| "01106d657461000110676176696e2d696e7374616e636500011064656c6574655f6269746d61" | |
| "705f6c6f636b0001120000000000002766110000000000000001"); | |
| EXPECT_LT(all_partitions_lock, | |
| meta_delete_bitmap_update_lock_key({"gavin-instance", 10086, 0})); | |
| EXPECT_LT(meta_delete_bitmap_update_lock_key({"gavin-instance", 10086, 0}), | |
| meta_delete_bitmap_update_lock_key( | |
| {"gavin-instance", 10086, std::numeric_limits<int64_t>::max()})); | |
| } | |
| TEST(KeysTest, MetaKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // rowset meta key | |
| // 0x01 "meta" ${instance_id} "rowset" ${tablet_id} ${version} | |
| { | |
| int64_t tablet_id = 10086; | |
| int64_t version = 100; | |
| MetaRowsetKeyInfo rowset_key {instance_id, tablet_id, version}; | |
| std::string encoded_rowset_key0; | |
| meta_rowset_key(rowset_key, &encoded_rowset_key0); | |
| std::cout << hex(encoded_rowset_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_tablet_id = 0; | |
| int64_t dec_version = 0; | |
| std::string_view key_sv(encoded_rowset_key0); | |
| std::string dec_meta_prefix; | |
| std::string dec_rowset_prefix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_rowset_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0) << hex(key_sv); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_version), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", dec_meta_prefix); | |
| EXPECT_EQ("rowset", dec_rowset_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| EXPECT_EQ(version, dec_version); | |
| std::get<2>(rowset_key) = version + 1; | |
| std::string encoded_rowset_key1; | |
| meta_rowset_key(rowset_key, &encoded_rowset_key1); | |
| std::cout << hex(encoded_rowset_key1) << std::endl; | |
| ASSERT_GT(encoded_rowset_key1, encoded_rowset_key0); | |
| } | |
| // tmp rowset meta key | |
| // 0x01 "meta" ${instance_id} "rowset_tmp" ${txn_id} ${tablet_id} | |
| { | |
| int64_t txn_id = 10086; | |
| int64_t tablet_id = 100; | |
| MetaRowsetTmpKeyInfo rowset_key {instance_id, txn_id, tablet_id}; | |
| std::string encoded_rowset_key0; | |
| meta_rowset_tmp_key(rowset_key, &encoded_rowset_key0); | |
| std::cout << hex(encoded_rowset_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_txn_id = 0; | |
| int64_t dec_tablet_id = 0; | |
| std::string_view key_sv(encoded_rowset_key0); | |
| std::string dec_meta_prefix; | |
| std::string dec_rowset_prefix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_rowset_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_txn_id), 0) << hex(key_sv); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", dec_meta_prefix); | |
| EXPECT_EQ("rowset_tmp", dec_rowset_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(txn_id, dec_txn_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| std::get<2>(rowset_key) = tablet_id + 1; | |
| std::string encoded_rowset_key1; | |
| meta_rowset_tmp_key(rowset_key, &encoded_rowset_key1); | |
| std::cout << hex(encoded_rowset_key1) << std::endl; | |
| ASSERT_GT(encoded_rowset_key1, encoded_rowset_key0); | |
| } | |
| // tablet meta key | |
| // 0x01 "meta" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} -> TabletMetaCloudPB | |
| { | |
| int64_t table_id = 10010; | |
| int64_t index_id = 10011; | |
| int64_t partition_id = 10012; | |
| int64_t tablet_id = 10086; | |
| MetaTabletKeyInfo tablet_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_rowset_key0; | |
| meta_tablet_key(tablet_key, &encoded_rowset_key0); | |
| std::cout << hex(encoded_rowset_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_table_id = 0; | |
| int64_t dec_tablet_id = 0; | |
| int64_t dec_index_id = 0; | |
| int64_t dec_partition_id = 0; | |
| std::string_view key_sv(encoded_rowset_key0); | |
| std::string dec_meta_prefix; | |
| std::string dec_tablet_prefix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_tablet_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_table_id), 0) << hex(key_sv); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_index_id), 0) << hex(key_sv); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_partition_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", dec_meta_prefix); | |
| EXPECT_EQ("tablet", dec_tablet_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| std::get<4>(tablet_key) = tablet_id + 1; | |
| std::string encoded_rowset_key1; | |
| meta_tablet_key(tablet_key, &encoded_rowset_key1); | |
| std::cout << hex(encoded_rowset_key1) << std::endl; | |
| ASSERT_GT(encoded_rowset_key1, encoded_rowset_key0); | |
| } | |
| // tablet index key | |
| // 0x01 "meta" ${instance_id} "tablet_index" ${tablet_id} -> ${table_id} | |
| { | |
| int64_t tablet_id = 10086; | |
| MetaTabletIdxKeyInfo tablet_tbl_key {instance_id, tablet_id}; | |
| std::string encoded_rowset_key0; | |
| meta_tablet_idx_key(tablet_tbl_key, &encoded_rowset_key0); | |
| std::cout << hex(encoded_rowset_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_tablet_id = 0; | |
| std::string_view key_sv(encoded_rowset_key0); | |
| std::string dec_meta_prefix; | |
| std::string dec_tablet_prefix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_tablet_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", dec_meta_prefix); | |
| EXPECT_EQ("tablet_index", dec_tablet_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| std::get<1>(tablet_tbl_key) = tablet_id + 1; | |
| std::string encoded_rowset_key1; | |
| meta_tablet_idx_key(tablet_tbl_key, &encoded_rowset_key1); | |
| std::cout << hex(encoded_rowset_key1) << std::endl; | |
| ASSERT_GT(encoded_rowset_key1, encoded_rowset_key0); | |
| } | |
| // tablet schema key | |
| // 0x01 "meta" ${instance_id} "schema" ${index_id} ${schema_version} -> TabletSchemaCloudPB | |
| { | |
| int64_t index_id = 10000; | |
| int32_t schema_version = 5; | |
| auto key = meta_schema_key({instance_id, index_id, schema_version}); | |
| std::string dec_instance_id; | |
| int64_t dec_index_id = 0; | |
| int64_t dec_schema_version = 0; | |
| std::string_view key_sv(key); | |
| std::string dec_schema_prefix; | |
| std::string dec_schema_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_schema_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_schema_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_index_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_schema_version), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| EXPECT_EQ(schema_version, dec_schema_version); | |
| EXPECT_EQ(dec_schema_prefix, "meta"); | |
| EXPECT_EQ(dec_schema_infix, "schema"); | |
| // TODO: the order of schema version? | |
| } | |
| } | |
| TEST(KeysTest, VersionKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x01 "version" ${instance_id} "partition" ${db_id} ${tbl_id} ${partition_id} -> ${version} | |
| { | |
| int64_t db_id = 11111; | |
| int64_t table_id = 10086; | |
| int64_t partition_id = 9998; | |
| PartitionVersionKeyInfo v_key {instance_id, db_id, table_id, partition_id}; | |
| std::string encoded_version_key0; | |
| partition_version_key(v_key, &encoded_version_key0); | |
| std::cout << "version key after encode: " << hex(encoded_version_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_db_id = 0; | |
| int64_t dec_table_id = 0; | |
| int64_t dec_partition_id = 0; | |
| std::string_view key_sv(encoded_version_key0); | |
| std::string dec_version_prefix; | |
| std::string dec_version_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_version_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_version_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_db_id), 0) << hex(key_sv); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_partition_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("version", dec_version_prefix); | |
| EXPECT_EQ("partition", dec_version_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| std::get<3>(v_key) = partition_id + 1; | |
| std::string encoded_version_key1; | |
| partition_version_key(v_key, &encoded_version_key1); | |
| std::cout << "version key after encode: " << hex(encoded_version_key1) << std::endl; | |
| ASSERT_GT(encoded_version_key1, encoded_version_key0); | |
| } | |
| // 0x01 "version" ${instance_id} "table" ${db_id} ${tbl_id} -> ${version} | |
| { | |
| int64_t db_id = 11111; | |
| int64_t table_id = 10010; | |
| TableVersionKeyInfo v_key {instance_id, db_id, table_id}; | |
| std::string encoded_version_key0; | |
| table_version_key(v_key, &encoded_version_key0); | |
| std::cout << "version key after encode: " << hex(encoded_version_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_db_id = 0; | |
| int64_t dec_table_id = 0; | |
| std::string_view key_sv(encoded_version_key0); | |
| std::string dec_version_prefix; | |
| std::string dec_version_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_version_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_version_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_db_id), 0) << hex(key_sv); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_table_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("version", dec_version_prefix); | |
| EXPECT_EQ("table", dec_version_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| std::get<2>(v_key) = table_id + 1; | |
| std::string encoded_version_key1; | |
| table_version_key(v_key, &encoded_version_key1); | |
| std::cout << "version key after encode: " << hex(encoded_version_key1) << std::endl; | |
| ASSERT_GT(encoded_version_key1, encoded_version_key0); | |
| } | |
| } | |
| TEST(KeysTest, TxnKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x01 "txn" ${instance_id} "txn_label" ${db_id} ${label} -> set<${version_timestamp}> | |
| { | |
| int64_t db_id = 12345678; | |
| std::string label = "label1xxx"; | |
| TxnLabelKeyInfo index_key {instance_id, db_id, label}; | |
| std::string encoded_txn_index_key0; | |
| txn_label_key(index_key, &encoded_txn_index_key0); | |
| std::cout << hex(encoded_txn_index_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_db_id = 0; | |
| std::string dec_label; | |
| std::string_view key_sv(encoded_txn_index_key0); | |
| std::string dec_txn_prefix; | |
| std::string dec_txn_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_db_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_label), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("txn", dec_txn_prefix); | |
| EXPECT_EQ("txn_label", dec_txn_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(label, dec_label); | |
| std::get<1>(index_key) = db_id + 1; | |
| std::string encoded_txn_index_key1; | |
| txn_label_key(index_key, &encoded_txn_index_key1); | |
| std::cout << hex(encoded_txn_index_key1) << std::endl; | |
| ASSERT_GT(encoded_txn_index_key1, encoded_txn_index_key0); | |
| } | |
| // 0x01 "txn" ${instance_id} "txn_info" ${db_id} ${txn_id} -> TxnInfoPB | |
| { | |
| int64_t db_id = 12345678; | |
| int64_t txn_id = 10086; | |
| TxnInfoKeyInfo info_key {instance_id, db_id, txn_id}; | |
| std::string encoded_txn_info_key0; | |
| txn_info_key(info_key, &encoded_txn_info_key0); | |
| std::cout << hex(encoded_txn_info_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_db_id = 0; | |
| int64_t dec_txn_id = 0; | |
| std::string_view key_sv(encoded_txn_info_key0); | |
| std::string dec_txn_prefix; | |
| std::string dec_txn_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_txn_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("txn", dec_txn_prefix); | |
| EXPECT_EQ("txn_info", dec_txn_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(txn_id, dec_txn_id); | |
| std::get<2>(info_key) = txn_id + 1; | |
| std::string encoded_txn_info_key1; | |
| txn_info_key(info_key, &encoded_txn_info_key1); | |
| std::cout << hex(encoded_txn_info_key1) << std::endl; | |
| ASSERT_GT(encoded_txn_info_key1, encoded_txn_info_key0); | |
| std::get<1>(info_key) = db_id + 1; | |
| std::string encoded_txn_info_key2; | |
| txn_info_key(info_key, &encoded_txn_info_key2); | |
| std::cout << hex(encoded_txn_info_key2) << std::endl; | |
| ASSERT_GT(encoded_txn_info_key2, encoded_txn_info_key0); | |
| } | |
| // 0x01 "txn" ${instance_id} "txn_index" ${txn_id} -> TxnIndexPB | |
| { | |
| int64_t txn_id = 12343212453; | |
| TxnIndexKeyInfo txn_index_key_ {instance_id, txn_id}; | |
| std::string encoded_txn_index_key0; | |
| txn_index_key(txn_index_key_, &encoded_txn_index_key0); | |
| std::cout << hex(encoded_txn_index_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_txn_id = 0; | |
| std::string_view key_sv(encoded_txn_index_key0); | |
| std::string dec_txn_prefix; | |
| std::string dec_txn_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_txn_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("txn", dec_txn_prefix); | |
| EXPECT_EQ("txn_index", dec_txn_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(txn_id, dec_txn_id); | |
| std::get<1>(txn_index_key_) = txn_id + 1; | |
| std::string encoded_txn_index_key1; | |
| txn_index_key(txn_index_key_, &encoded_txn_index_key1); | |
| std::cout << hex(encoded_txn_index_key1) << std::endl; | |
| ASSERT_GT(encoded_txn_index_key1, encoded_txn_index_key0); | |
| } | |
| // 0x01 "txn" ${instance_id} "txn_running" ${db_id} ${txn_id} -> ${table_id_list} | |
| { | |
| int64_t db_id = 98712345; | |
| int64_t txn_id = 12343212453; | |
| TxnRunningKeyInfo running_key {instance_id, db_id, txn_id}; | |
| std::string encoded_txn_running_key0; | |
| txn_running_key(running_key, &encoded_txn_running_key0); | |
| std::cout << hex(encoded_txn_running_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_db_id = 0; | |
| int64_t dec_txn_id = 0; | |
| std::string_view key_sv(encoded_txn_running_key0); | |
| std::string dec_txn_prefix; | |
| std::string dec_txn_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_txn_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("txn", dec_txn_prefix); | |
| EXPECT_EQ("txn_running", dec_txn_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(txn_id, dec_txn_id); | |
| std::get<2>(running_key) = txn_id + 1; | |
| std::string encoded_txn_running_key1; | |
| txn_running_key(running_key, &encoded_txn_running_key1); | |
| std::cout << hex(encoded_txn_running_key1) << std::endl; | |
| ASSERT_GT(encoded_txn_running_key1, encoded_txn_running_key0); | |
| } | |
| // 0x01 "txn" ${instance_id} "tso_fence" -> TxnTsoFencePB | |
| { | |
| std::string encoded_key = txn_tso_fence_key({instance_id}); | |
| std::string_view key_sv(encoded_key); | |
| std::string decoded_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_infix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("txn", decoded_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("tso_fence", decoded_infix); | |
| } | |
| } | |
| TEST(KeysTest, RecycleKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x01 "recycle" ${instance_id} "index" ${index_id} -> RecycleIndexPB | |
| { | |
| int64_t index_id = 1234545; | |
| RecycleIndexKeyInfo recycle_key {instance_id, index_id}; | |
| std::string encoded_recycle_key0; | |
| recycle_index_key(recycle_key, &encoded_recycle_key0); | |
| std::cout << hex(encoded_recycle_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_index_id = 0; | |
| std::string_view key_sv(encoded_recycle_key0); | |
| std::string dec_recycle_prefix; | |
| std::string dec_recycle_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_index_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("recycle", dec_recycle_prefix); | |
| EXPECT_EQ("index", dec_recycle_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| } | |
| // 0x01 "recycle" ${instance_id} "partition" ${partition_id} -> RecyclePartitionPB | |
| { | |
| int64_t partition_id = 12345450; | |
| RecyclePartKeyInfo recycle_key {instance_id, partition_id}; | |
| std::string encoded_recycle_key0; | |
| recycle_partition_key(recycle_key, &encoded_recycle_key0); | |
| std::cout << hex(encoded_recycle_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_partition_id = 0; | |
| std::string_view key_sv(encoded_recycle_key0); | |
| std::string dec_recycle_prefix; | |
| std::string dec_recycle_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_partition_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("recycle", dec_recycle_prefix); | |
| EXPECT_EQ("partition", dec_recycle_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| } | |
| // 0x01 "recycle" ${instance_id} "rowset" ${tablet_id} ${rowset_id} -> RecycleRowsetPB | |
| { | |
| int64_t tablet_id = 100201; | |
| std::string rowset_id = "202201"; | |
| RecycleRowsetKeyInfo recycle_key {instance_id, tablet_id, rowset_id}; | |
| std::string encoded_recycle_key0; | |
| recycle_rowset_key(recycle_key, &encoded_recycle_key0); | |
| std::cout << hex(encoded_recycle_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_tablet_id = 0; | |
| std::string dec_rowset_id; | |
| std::string_view key_sv(encoded_recycle_key0); | |
| std::string dec_recycle_prefix; | |
| std::string dec_recycle_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_rowset_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("recycle", dec_recycle_prefix); | |
| EXPECT_EQ("rowset", dec_recycle_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| EXPECT_EQ(rowset_id, dec_rowset_id); | |
| } | |
| // 0x01 "recycle" ${instance_id} "txn" ${db_id} ${txn_id} -> RecycleTxnKeyInfo | |
| { | |
| int64_t db_id = 98712345; | |
| int64_t txn_id = 12343212453; | |
| RecycleTxnKeyInfo recycle_key {instance_id, db_id, txn_id}; | |
| std::string encoded_recycle_txn_key0; | |
| recycle_txn_key(recycle_key, &encoded_recycle_txn_key0); | |
| std::cout << hex(encoded_recycle_txn_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_db_id = 0; | |
| int64_t dec_txn_id = 0; | |
| std::string_view key_sv(encoded_recycle_txn_key0); | |
| std::string dec_txn_prefix; | |
| std::string dec_txn_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_txn_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_txn_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("recycle", dec_txn_prefix); | |
| EXPECT_EQ("txn", dec_txn_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(txn_id, dec_txn_id); | |
| } | |
| // 0x01 "recycle" ${instance_id} "stage" ${stage_id} -> RecycleStagePB | |
| { | |
| std::string stage_id = "100201"; | |
| RecycleStageKeyInfo recycle_key {instance_id, stage_id}; | |
| std::string encoded_recycle_key0; | |
| recycle_stage_key(recycle_key, &encoded_recycle_key0); | |
| std::cout << hex(encoded_recycle_key0) << std::endl; | |
| std::string dec_instance_id; | |
| std::string dec_stage_id; | |
| std::string_view key_sv(encoded_recycle_key0); | |
| std::string dec_recycle_prefix; | |
| std::string dec_recycle_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_recycle_infix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stage_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("recycle", dec_recycle_prefix); | |
| EXPECT_EQ("stage", dec_recycle_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(stage_id, dec_stage_id); | |
| } | |
| } | |
| TEST(KeysTest, StatsKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| int64_t table_id = 123; | |
| int64_t index_id = 345; | |
| int64_t partition_id = 1231231231; | |
| int64_t tablet_id = 543671234523; | |
| auto expect_stats_prefix = [&](std::string_view& key_sv) { | |
| std::string dec_instance_id; | |
| int64_t dec_table_id = 0; | |
| int64_t dec_index_id = 0; | |
| int64_t dec_partition_id = 0; | |
| int64_t dec_tablet_id = 0; | |
| std::string dec_stats_prefix; | |
| std::string dec_stats_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_index_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_partition_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| EXPECT_EQ("stats", dec_stats_prefix); | |
| EXPECT_EQ("tablet", dec_stats_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| }; | |
| // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} -> TabletStatsPB | |
| { | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key0; | |
| stats_tablet_key(stats_key, &encoded_stats_key0); | |
| std::cout << hex(encoded_stats_key0) << std::endl; | |
| std::string_view key_sv(encoded_stats_key0); | |
| expect_stats_prefix(key_sv); | |
| ASSERT_TRUE(key_sv.empty()); | |
| } | |
| // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} "data_size" -> int64 | |
| { | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key0; | |
| stats_tablet_data_size_key(stats_key, &encoded_stats_key0); | |
| std::cout << hex(encoded_stats_key0) << std::endl; | |
| std::string dec_stats_suffix; | |
| std::string_view key_sv(encoded_stats_key0); | |
| expect_stats_prefix(key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("data_size", dec_stats_suffix); | |
| } | |
| // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} "num_rows" -> int64 | |
| { | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key0; | |
| stats_tablet_num_rows_key(stats_key, &encoded_stats_key0); | |
| std::cout << hex(encoded_stats_key0) << std::endl; | |
| std::string dec_stats_suffix; | |
| std::string_view key_sv(encoded_stats_key0); | |
| expect_stats_prefix(key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("num_rows", dec_stats_suffix); | |
| } | |
| // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} "num_rowsets" -> int64 | |
| { | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key0; | |
| stats_tablet_num_rowsets_key(stats_key, &encoded_stats_key0); | |
| std::cout << hex(encoded_stats_key0) << std::endl; | |
| std::string dec_stats_suffix; | |
| std::string_view key_sv(encoded_stats_key0); | |
| expect_stats_prefix(key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("num_rowsets", dec_stats_suffix); | |
| } | |
| // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} "num_segs" -> int64 | |
| { | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key0; | |
| stats_tablet_num_segs_key(stats_key, &encoded_stats_key0); | |
| std::cout << hex(encoded_stats_key0) << std::endl; | |
| std::string dec_stats_suffix; | |
| std::string_view key_sv(encoded_stats_key0); | |
| expect_stats_prefix(key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("num_segs", dec_stats_suffix); | |
| } | |
| // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} "index_size" -> int64 | |
| { | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key0; | |
| stats_tablet_index_size_key(stats_key, &encoded_stats_key0); | |
| std::cout << hex(encoded_stats_key0) << std::endl; | |
| std::string dec_stats_suffix; | |
| std::string_view key_sv(encoded_stats_key0); | |
| expect_stats_prefix(key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index_size", dec_stats_suffix); | |
| } | |
| // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} "segment_size" -> int64 | |
| { | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key0; | |
| stats_tablet_segment_size_key(stats_key, &encoded_stats_key0); | |
| std::cout << hex(encoded_stats_key0) << std::endl; | |
| std::string dec_stats_suffix; | |
| std::string_view key_sv(encoded_stats_key0); | |
| expect_stats_prefix(key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("segment_size", dec_stats_suffix); | |
| } | |
| } | |
| TEST(KeysTest, JobKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x01 "job" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} -> TabletJobInfoPB | |
| { | |
| int64_t table_id = 123; | |
| int64_t index_id = 345; | |
| int64_t partition_id = 1231231231; | |
| int64_t tablet_id = 543671234523; | |
| JobTabletKeyInfo job_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_job_key0; | |
| job_tablet_key(job_key, &encoded_job_key0); | |
| std::cout << hex(encoded_job_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_table_id = 0; | |
| int64_t dec_index_id = 0; | |
| int64_t dec_partition_id = 0; | |
| int64_t dec_tablet_id = 0; | |
| std::string_view key_sv(encoded_job_key0); | |
| std::string dec_job_prefix; | |
| std::string dec_job_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_index_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_partition_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("tablet", dec_job_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| } | |
| // 0x01 "job" ${instance_id} "recycle" -> JobRecyclePB | |
| { | |
| JobRecycleKeyInfo job_key {instance_id}; | |
| std::string encoded_job_key0; | |
| job_recycle_key(job_key, &encoded_job_key0); | |
| std::cout << hex(encoded_job_key0) << std::endl; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(encoded_job_key0); | |
| std::string dec_job_prefix; | |
| std::string dec_job_suffix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("recycle", dec_job_suffix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| // 0x01 "job" ${instance_id} "check" -> JobRecyclePB | |
| { | |
| JobRecycleKeyInfo job_key {instance_id}; | |
| std::string encoded_job_key0; | |
| job_check_key(job_key, &encoded_job_key0); | |
| std::cout << hex(encoded_job_key0) << std::endl; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(encoded_job_key0); | |
| std::string dec_job_prefix; | |
| std::string dec_job_suffix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("check", dec_job_suffix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| // 0x01 "job" ${instance_id} "snapshot_data_migrator" -> JobSnapshotDataMigratorPB | |
| { | |
| JobSnapshotDataMigratorKeyInfo job_key {instance_id}; | |
| std::string encoded_job_key0; | |
| job_snapshot_data_migrator_key(job_key, &encoded_job_key0); | |
| std::cout << hex(encoded_job_key0) << std::endl; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(encoded_job_key0); | |
| std::string dec_job_prefix; | |
| std::string dec_job_suffix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("snapshot_data_migrator", dec_job_suffix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| // 0x01 "job" ${instance_id} "snapshot_chain_compactor" -> JobSnapshotChainCompactorPB | |
| { | |
| JobSnapshotChainCompactorKeyInfo job_key {instance_id}; | |
| std::string encoded_job_key0; | |
| job_snapshot_chain_compactor_key(job_key, &encoded_job_key0); | |
| std::cout << hex(encoded_job_key0) << std::endl; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(encoded_job_key0); | |
| std::string dec_job_prefix; | |
| std::string dec_job_suffix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("snapshot_chain_compactor", dec_job_suffix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| } | |
| TEST(KeysTest, SystemKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x02 "system" "meta-service" "registry" -> MetaServiceRegistryPB | |
| // 0x02 "system" "meta-service" "arn_info" -> RamUserPB | |
| // 0x02 "system" "meta-service" "encryption_key_info" -> EncryptionKeyInfoPB | |
| // 0x02 "system" "meta-service" "instance_update" -> int64 | |
| std::vector<std::string> suffixes {"registry", "arn_info", "encryption_key_info", | |
| "instance_update"}; | |
| std::vector<std::function<std::string()>> fns { | |
| system_meta_service_registry_key, | |
| system_meta_service_arn_info_key, | |
| system_meta_service_encryption_key_info_key, | |
| system_meta_service_instance_update_key, | |
| }; | |
| size_t num = suffixes.size(); | |
| for (size_t i = 0; i < num; ++i) { | |
| std::string key = fns[i](); | |
| std::cout << hex(key) << std::endl; | |
| std::string_view key_sv(key); | |
| std::string prefix, infix, suffix; | |
| remove_system_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &infix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &suffix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("system", prefix); | |
| EXPECT_EQ("meta-service", infix); | |
| EXPECT_EQ(suffixes[i], suffix) << i; | |
| } | |
| } | |
| TEST(KeysTest, CopyKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x01 "copy" ${instance_id} "job" ${stage_id} ${table_id} ${copy_id} ${group_id} -> CopyJobPB | |
| { | |
| int64_t table_id = 3745823784; | |
| int64_t group_id = 1238547388; | |
| std::string stage_id = "9482049283"; | |
| std::string copy_id = "1284758385"; | |
| CopyJobKeyInfo copy_key {instance_id, stage_id, table_id, copy_id, group_id}; | |
| std::string encoded_copy_job_key0; | |
| copy_job_key(copy_key, &encoded_copy_job_key0); | |
| std::cout << hex(encoded_copy_job_key0) << std::endl; | |
| std::string dec_instance_id; | |
| std::string dec_stage_id; | |
| std::string dec_copy_id; | |
| int64_t dec_table_id = 0; | |
| int64_t dec_group_id = 0; | |
| std::string_view key_sv(encoded_copy_job_key0); | |
| std::string dec_copy_job_prefix, dec_copy_job_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_copy_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_copy_job_infix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stage_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_table_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_copy_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_group_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("copy", dec_copy_job_prefix); | |
| EXPECT_EQ("job", dec_copy_job_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(stage_id, dec_stage_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(copy_id, dec_copy_id); | |
| EXPECT_EQ(group_id, dec_group_id); | |
| } | |
| // 0x01 "copy" ${instance_id} "loading_file" ${stage_id} ${table_id} ${obj_name} ${etag} -> CopyFilePB | |
| { | |
| std::string stage_id = "9482049283"; | |
| int64_t table_id = 3745823784; | |
| std::string obj_name = "test-obj-name"; | |
| std::string etag = "test-etag"; | |
| CopyFileKeyInfo copy_key {instance_id, stage_id, table_id, obj_name, etag}; | |
| std::string encoded_copy_job_key0; | |
| copy_file_key(copy_key, &encoded_copy_job_key0); | |
| std::cout << hex(encoded_copy_job_key0) << std::endl; | |
| std::string dec_instance_id; | |
| std::string dec_stage_id; | |
| int64_t dec_table_id = 0; | |
| std::string dec_obj_name; | |
| std::string dec_etag; | |
| std::string_view key_sv(encoded_copy_job_key0); | |
| std::string dec_copy_prefix, dec_copy_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_copy_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_copy_infix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stage_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_table_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_obj_name), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_etag), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("copy", dec_copy_prefix); | |
| EXPECT_EQ("loading_file", dec_copy_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(stage_id, dec_stage_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(obj_name, dec_obj_name); | |
| EXPECT_EQ(etag, dec_etag); | |
| } | |
| } | |
| TEST(KeysTest, MetaSchemaPBDictionaryTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_meta_dict"; | |
| int64_t index_id = 123456; | |
| // 0:instance_id 1:index_id | |
| MetaSchemaPBDictionaryInfo dict_key {instance_id, index_id}; | |
| std::string encoded_dict_key; | |
| meta_schema_pb_dictionary_key(dict_key, &encoded_dict_key); | |
| std::cout << hex(encoded_dict_key) << std::endl; | |
| std::string decoded_instance_id; | |
| std::string decoded_prefix; | |
| std::string decoded_meta_prefix; | |
| int64_t decoded_index_id; | |
| std::string_view key_sv(encoded_dict_key); | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_meta_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_index_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", decoded_prefix); | |
| EXPECT_EQ("tablet_schema_pb_dict", decoded_meta_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ(index_id, decoded_index_id); | |
| } | |
| TEST(KeysTest, VersionedPartitionVersionKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t partition_id = 123456; | |
| { | |
| // test partition_version_key | |
| // 0x03 "version" ${instance_id} "partition" ${partition_id} ${timestamp} -> VersionPB | |
| PartitionVersionKeyInfo partition_key {instance_id, partition_id}; | |
| std::string encoded_partition_key; | |
| partition_version_key(partition_key, &encoded_partition_key); | |
| std::string decoded_version_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_partition_prefix; | |
| int64_t decoded_partition_id; | |
| std::string_view key_sv(encoded_partition_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_version_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_partition_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_partition_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("version", decoded_version_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("partition", decoded_partition_prefix); | |
| EXPECT_EQ(partition_id, decoded_partition_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedTableVersionKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t table_id = 456; | |
| { | |
| // test table_version_key | |
| // 0x03 "version" ${instance_id} "table" ${table_id} ${timestamp} -> ${empty_value} | |
| TableVersionKeyInfo table_key {instance_id, table_id}; | |
| std::string encoded_table_key; | |
| table_version_key(table_key, &encoded_table_key); | |
| std::string decoded_version_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_table_prefix; | |
| int64_t decoded_table_id; | |
| std::string_view key_sv(encoded_table_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_version_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_table_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_table_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("version", decoded_version_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("table", decoded_table_prefix); | |
| EXPECT_EQ(table_id, decoded_table_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedPartitionIndexKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t partition_id = 789; | |
| { | |
| // test partition_index_key | |
| // 0x03 "index" ${instance_id} "partition" ${partition_id} -> PartitionIndexPB | |
| PartitionIndexKeyInfo partition_index_info {instance_id, partition_id}; | |
| std::string encoded_partition_index_key; | |
| partition_index_key(partition_index_info, &encoded_partition_index_key); | |
| std::string decoded_index_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_partition_prefix; | |
| int64_t decoded_partition_id; | |
| std::string_view key_sv(encoded_partition_index_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_partition_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_partition_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index", decoded_index_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("partition", decoded_partition_prefix); | |
| EXPECT_EQ(partition_id, decoded_partition_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedPartitionInvertedIndexKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t db_id = 123; | |
| int64_t table_id = 456; | |
| int64_t partition_id = 999; | |
| { | |
| // test partition_inverted_index_key | |
| // 0x03 "index" ${instance_id} "partition_inverted" ${db_id} ${table_id} ${partition} -> ${empty_value} | |
| PartitionInvertedIndexKeyInfo partition_inverted_index_info {instance_id, db_id, table_id, | |
| partition_id}; | |
| std::string encoded_partition_inverted_index_key; | |
| partition_inverted_index_key(partition_inverted_index_info, | |
| &encoded_partition_inverted_index_key); | |
| std::string decoded_index_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_partition_inverted_prefix; | |
| int64_t decoded_db_id; | |
| int64_t decoded_table_id; | |
| int64_t decoded_partition_id; | |
| std::string_view key_sv(encoded_partition_inverted_index_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_partition_inverted_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_partition_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index", decoded_index_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("partition_inverted", decoded_partition_inverted_prefix); | |
| EXPECT_EQ(db_id, decoded_db_id); | |
| EXPECT_EQ(table_id, decoded_table_id); | |
| EXPECT_EQ(partition_id, decoded_partition_id); | |
| key_sv = encoded_partition_inverted_index_key; | |
| EXPECT_TRUE(decode_partition_inverted_index_key(&key_sv, &decoded_db_id, &decoded_table_id, | |
| &decoded_partition_id)); | |
| EXPECT_EQ(db_id, decoded_db_id); | |
| EXPECT_EQ(table_id, decoded_table_id); | |
| EXPECT_EQ(partition_id, decoded_partition_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedTabletIndexKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t tablet_id = 789; | |
| { | |
| // test tablet_index_key | |
| // 0x03 "index" ${instance_id} "tablet" ${tablet_id} -> TabletIndexPB | |
| TabletIndexKeyInfo tablet_index_info {instance_id, tablet_id}; | |
| std::string encoded_tablet_index_key; | |
| tablet_index_key(tablet_index_info, &encoded_tablet_index_key); | |
| std::string decoded_index_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_tablet_prefix; | |
| int64_t decoded_tablet_id; | |
| std::string_view key_sv(encoded_tablet_index_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_tablet_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index", decoded_index_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("tablet", decoded_tablet_prefix); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedTabletInvertedIndexKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t db_id = 123; | |
| int64_t table_id = 456; | |
| int64_t index_id = 789; | |
| int64_t partition_id = 999; | |
| int64_t tablet_id = 888; | |
| { | |
| // test tablet_inverted_index_key | |
| // 0x03 "index" ${instance_id} "tablet_inverted" ${db_id} ${table_id} ${index_id} ${partition} ${tablet} -> ${empty_value} | |
| TabletInvertedIndexKeyInfo tablet_inverted_index_info { | |
| instance_id, db_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_tablet_inverted_index_key; | |
| tablet_inverted_index_key(tablet_inverted_index_info, &encoded_tablet_inverted_index_key); | |
| std::string decoded_index_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_tablet_inverted_prefix; | |
| int64_t decoded_db_id; | |
| int64_t decoded_table_id; | |
| int64_t decoded_index_id; | |
| int64_t decoded_partition_id; | |
| int64_t decoded_tablet_id; | |
| std::string_view key_sv(encoded_tablet_inverted_index_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_tablet_inverted_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_index_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_partition_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index", decoded_index_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("tablet_inverted", decoded_tablet_inverted_prefix); | |
| EXPECT_EQ(db_id, decoded_db_id); | |
| EXPECT_EQ(table_id, decoded_table_id); | |
| EXPECT_EQ(index_id, decoded_index_id); | |
| EXPECT_EQ(partition_id, decoded_partition_id); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedIndexIndexKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t index_id = 789; | |
| { | |
| // test index_index_key | |
| // 0x03 "index" ${instance_id} "index" ${index_id} -> IndexIndexPB | |
| IndexIndexKeyInfo index_index_info {instance_id, index_id}; | |
| std::string encoded_index_index_key; | |
| index_index_key(index_index_info, &encoded_index_index_key); | |
| std::string decoded_index_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_index_infix; | |
| int64_t decoded_index_id; | |
| std::string_view key_sv(encoded_index_index_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_index_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index", decoded_index_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("index", decoded_index_infix); | |
| EXPECT_EQ(index_id, decoded_index_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedIndexInvertedKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t db_id = 123; | |
| int64_t table_id = 456; | |
| int64_t index_id = 789; | |
| { | |
| // test index_inverted_key | |
| // 0x03 "index" ${instance_id} "index_inverted" ${db_id} ${table_id} ${index_id} -> ${empty_value} | |
| IndexInvertedKeyInfo index_inverted_info {instance_id, db_id, table_id, index_id}; | |
| std::string encoded_index_inverted_key; | |
| index_inverted_key(index_inverted_info, &encoded_index_inverted_key); | |
| std::string decoded_index_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_index_inverted_prefix; | |
| int64_t decoded_db_id; | |
| int64_t decoded_table_id; | |
| int64_t decoded_index_id; | |
| std::string_view key_sv(encoded_index_inverted_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_inverted_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_index_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index", decoded_index_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("index_inverted", decoded_index_inverted_prefix); | |
| EXPECT_EQ(db_id, decoded_db_id); | |
| EXPECT_EQ(table_id, decoded_table_id); | |
| EXPECT_EQ(index_id, decoded_index_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedTabletLoadStatsKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t tablet_id = 789; | |
| { | |
| // test tablet_load_stats_key | |
| // 0x03 "stats" ${instance_id} "tablet_load" ${tablet_id} ${timestamp} -> TabletStatsPB | |
| TabletLoadStatsKeyInfo tablet_load_stats_info {instance_id, tablet_id}; | |
| std::string encoded_tablet_load_stats_key; | |
| tablet_load_stats_key(tablet_load_stats_info, &encoded_tablet_load_stats_key); | |
| std::string decoded_stats_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_tablet_load_prefix; | |
| int64_t decoded_tablet_id; | |
| std::string_view key_sv(encoded_tablet_load_stats_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_stats_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_tablet_load_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("stats", decoded_stats_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("tablet_load", decoded_tablet_load_prefix); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedTabletCompactStatsKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t tablet_id = 789; | |
| { | |
| // test tablet_compact_stats_key | |
| // 0x03 "stats" ${instance_id} "tablet_compact" ${tablet_id} ${timestamp} -> TabletStatsPB | |
| TabletCompactStatsKeyInfo tablet_compact_stats_info {instance_id, tablet_id}; | |
| std::string encoded_tablet_compact_stats_key; | |
| tablet_compact_stats_key(tablet_compact_stats_info, &encoded_tablet_compact_stats_key); | |
| std::string decoded_stats_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_tablet_compact_prefix; | |
| int64_t decoded_tablet_id; | |
| std::string_view key_sv(encoded_tablet_compact_stats_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_stats_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_tablet_compact_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("stats", decoded_stats_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("tablet_compact", decoded_tablet_compact_prefix); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedMetaPartitionKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t partition_id = 789; | |
| { | |
| // test meta_partition_key | |
| // 0x03 "meta" ${instance_id} "partition" ${partition_id} ${timestamp} -> ${empty_value} | |
| MetaPartitionKeyInfo meta_partition_info {instance_id, partition_id}; | |
| std::string encoded_meta_partition_key; | |
| meta_partition_key(meta_partition_info, &encoded_meta_partition_key); | |
| std::string decoded_meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_partition_prefix; | |
| int64_t decoded_partition_id; | |
| std::string_view key_sv(encoded_meta_partition_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_partition_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_partition_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", decoded_meta_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("partition", decoded_partition_prefix); | |
| EXPECT_EQ(partition_id, decoded_partition_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedMetaIndexKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t index_id = 789; | |
| { | |
| // test meta_index_key | |
| // 0x03 "meta" ${instance_id} "index" ${index_id} ${timestamp} -> ${empty_value} | |
| MetaIndexKeyInfo meta_index_info {instance_id, index_id}; | |
| std::string encoded_meta_index_key; | |
| meta_index_key(meta_index_info, &encoded_meta_index_key); | |
| std::string decoded_meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_index_prefix; | |
| int64_t decoded_index_id; | |
| std::string_view key_sv(encoded_meta_index_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_index_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_index_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", decoded_meta_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("index", decoded_index_prefix); | |
| EXPECT_EQ(index_id, decoded_index_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedMetaTabletKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t tablet_id = 789; | |
| { | |
| // test meta_tablet_key | |
| // 0x03 "meta" ${instance_id} "tablet" ${tablet_id} ${timestamp} -> TabletMetaPB | |
| doris::cloud::versioned::MetaTabletKeyInfo meta_tablet_info {instance_id, tablet_id}; | |
| std::string encoded_meta_tablet_key; | |
| meta_tablet_key(meta_tablet_info, &encoded_meta_tablet_key); | |
| std::string decoded_meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_tablet_prefix; | |
| int64_t decoded_tablet_id; | |
| std::string_view key_sv(encoded_meta_tablet_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_tablet_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", decoded_meta_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("tablet", decoded_tablet_prefix); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedMetaSchemaKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t index_id = 789; | |
| int64_t schema_version = 5; | |
| { | |
| // test meta_schema_key | |
| // 0x03 "meta" ${instance_id} "schema" ${index_id} ${schema_version} -> TabletSchemaPB | |
| doris::cloud::versioned::MetaSchemaKeyInfo meta_schema_info {instance_id, index_id, | |
| schema_version}; | |
| std::string encoded_meta_schema_key; | |
| meta_schema_key(meta_schema_info, &encoded_meta_schema_key); | |
| std::string decoded_meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_schema_prefix; | |
| int64_t decoded_index_id; | |
| int64_t decoded_schema_version; | |
| std::string_view key_sv(encoded_meta_schema_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_schema_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_index_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_schema_version), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", decoded_meta_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("schema", decoded_schema_prefix); | |
| EXPECT_EQ(index_id, decoded_index_id); | |
| EXPECT_EQ(schema_version, decoded_schema_version); | |
| } | |
| } | |
| TEST(KeysTest, VersionedMetaRowsetLoadKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t tablet_id = 789; | |
| int64_t version = 123; | |
| { | |
| // test meta_rowset_load_key | |
| // 0x03 "meta" ${instance_id} "rowset_load" ${tablet_id} ${version} ${timestamp} -> RowsetMetaPB | |
| MetaRowsetLoadKeyInfo meta_rowset_load_info {instance_id, tablet_id, version}; | |
| std::string encoded_meta_rowset_load_key; | |
| meta_rowset_load_key(meta_rowset_load_info, &encoded_meta_rowset_load_key); | |
| std::string decoded_meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_rowset_load_prefix; | |
| int64_t decoded_tablet_id; | |
| int64_t decoded_version; | |
| std::string_view key_sv(encoded_meta_rowset_load_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_rowset_load_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_version), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", decoded_meta_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("rowset_load", decoded_rowset_load_prefix); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| EXPECT_EQ(version, decoded_version); | |
| } | |
| } | |
| TEST(KeysTest, VersionedMetaRowsetCompactKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t tablet_id = 789; | |
| int64_t version = 123; | |
| { | |
| // test meta_rowset_compact_key | |
| // 0x03 "meta" ${instance_id} "rowset_compact" ${tablet_id} ${version} ${timestamp} -> RowsetMetaPB | |
| MetaRowsetCompactKeyInfo meta_rowset_compact_info {instance_id, tablet_id, version}; | |
| std::string encoded_meta_rowset_compact_key; | |
| meta_rowset_compact_key(meta_rowset_compact_info, &encoded_meta_rowset_compact_key); | |
| std::string decoded_meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_rowset_compact_prefix; | |
| int64_t decoded_tablet_id; | |
| int64_t decoded_version; | |
| std::string_view key_sv(encoded_meta_rowset_compact_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_rowset_compact_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_version), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", decoded_meta_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("rowset_compact", decoded_rowset_compact_prefix); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| EXPECT_EQ(version, decoded_version); | |
| } | |
| } | |
| TEST(KeysTest, VersionedDataRowsetRefCountKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_int64; | |
| std::string instance_id = "instance_id"; | |
| int64_t tablet_id = 789; | |
| std::string rowset_id = "test_rowset_id"; | |
| { | |
| // test data_rowset_key | |
| // 0x03 "data" ${instance_id} "rowset" ${tablet_id} ${rowset_id} -> int64 | |
| DataRowsetRefCountKeyInfo data_rowset_info {instance_id, tablet_id, rowset_id}; | |
| std::string encoded_data_rowset_key; | |
| data_rowset_ref_count_key(data_rowset_info, &encoded_data_rowset_key); | |
| std::string decoded_data_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_rowset_prefix; | |
| int64_t decoded_tablet_id; | |
| std::string decoded_rowset_id; | |
| std::string_view key_sv(encoded_data_rowset_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_data_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_rowset_prefix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_tablet_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_rowset_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("data", decoded_data_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("rowset_ref_count", decoded_rowset_prefix); | |
| EXPECT_EQ(tablet_id, decoded_tablet_id); | |
| EXPECT_EQ(rowset_id, decoded_rowset_id); | |
| } | |
| } | |
| TEST(KeysTest, VersionedSnapshotFullKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| std::string instance_id = "instance_id"; | |
| { | |
| // test snapshot_full_key | |
| // 0x03 "snapshot" ${instance_id} "full" ${timestamp} -> SnapshotPB | |
| SnapshotFullKeyInfo snapshot_full_info {instance_id}; | |
| std::string encoded_snapshot_full_key; | |
| snapshot_full_key(snapshot_full_info, &encoded_snapshot_full_key); | |
| std::string decoded_snapshot_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_full_prefix; | |
| std::string_view key_sv(encoded_snapshot_full_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_snapshot_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_full_prefix), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("snapshot", decoded_snapshot_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("full", decoded_full_prefix); | |
| } | |
| } | |
| TEST(KeysTest, VersionedSnapshotReferenceKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| using doris::cloud::decode_versionstamp; | |
| using doris::cloud::Versionstamp; | |
| std::string instance_id = "instance_id"; | |
| Versionstamp timestamp(888, 99); | |
| std::string ref_instance_id = "ref_instance_id"; | |
| { | |
| // test snapshot_reference_key | |
| // 0x03 "snapshot" ${instance_id} "reference" ${timestamp} ${instance_id} -> ${empty_value} | |
| SnapshotReferenceKeyInfo snapshot_reference_info {instance_id, timestamp, ref_instance_id}; | |
| std::string encoded_snapshot_reference_key; | |
| snapshot_reference_key(snapshot_reference_info, &encoded_snapshot_reference_key); | |
| std::string decoded_snapshot_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_reference_prefix; | |
| Versionstamp decoded_timestamp; | |
| std::string decoded_ref_instance_id; | |
| std::string_view key_sv(encoded_snapshot_reference_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_snapshot_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_reference_prefix), 0); | |
| ASSERT_EQ(decode_versionstamp(&key_sv, &decoded_timestamp), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_ref_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("snapshot", decoded_snapshot_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("reference", decoded_reference_prefix); | |
| EXPECT_EQ(timestamp.version(), decoded_timestamp.version()); | |
| EXPECT_EQ(timestamp.order(), decoded_timestamp.order()); | |
| EXPECT_EQ(ref_instance_id, decoded_ref_instance_id); | |
| } | |
| { | |
| std::string encoded_snapshot_reference_key = | |
| snapshot_reference_key_prefix(instance_id, timestamp); | |
| std::string decoded_snapshot_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_reference_prefix; | |
| Versionstamp decoded_timestamp; | |
| std::string_view key_sv(encoded_snapshot_reference_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_snapshot_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_reference_prefix), 0); | |
| ASSERT_EQ(decode_versionstamp(&key_sv, &decoded_timestamp), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("snapshot", decoded_snapshot_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| EXPECT_EQ("reference", decoded_reference_prefix); | |
| EXPECT_EQ(timestamp.version(), decoded_timestamp.version()); | |
| EXPECT_EQ(timestamp.order(), decoded_timestamp.order()); | |
| } | |
| } | |
| TEST(KeysTest, VersionedLogKeyTest) { | |
| using namespace doris::cloud::versioned; | |
| using doris::cloud::decode_bytes; | |
| std::string instance_id = "instance_id"; | |
| { | |
| // test log_key | |
| // 0x03 "log" ${instance_id} ${timestamp} -> OperationLogPB | |
| LogKeyInfo log_info {instance_id}; | |
| std::string encoded_log_key; | |
| log_key(log_info, &encoded_log_key); | |
| std::string decoded_log_prefix; | |
| std::string decoded_instance_id; | |
| std::string_view key_sv(encoded_log_key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_log_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("log", decoded_log_prefix); | |
| EXPECT_EQ(instance_id, decoded_instance_id); | |
| } | |
| } | |
| TEST(KeysTest, TableStreamOffsetKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id"; | |
| int64_t base_db_id = 101; | |
| int64_t base_table_id = 102; | |
| int64_t stream_db_id = 103; | |
| int64_t stream_id = 104; | |
| int64_t partition_id = 105; | |
| TableStreamOffsetKeyInfo info {instance_id, base_db_id, base_table_id, | |
| stream_db_id, stream_id, partition_id}; | |
| std::string key = table_stream_offset_key(info); | |
| std::string prefix = table_stream_offset_key_prefix(instance_id, base_db_id, base_table_id, | |
| stream_db_id, stream_id); | |
| ASSERT_TRUE(key.starts_with(prefix)); | |
| std::string meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string offset_infix; | |
| int64_t decoded_base_db_id = 0; | |
| int64_t decoded_base_table_id = 0; | |
| int64_t decoded_stream_db_id = 0; | |
| int64_t decoded_stream_id = 0; | |
| int64_t decoded_partition_id = 0; | |
| std::string_view key_sv(key); | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &offset_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_base_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_base_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_stream_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_stream_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_partition_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(meta_prefix, "meta"); | |
| EXPECT_EQ(decoded_instance_id, instance_id); | |
| EXPECT_EQ(offset_infix, "table_stream_offset"); | |
| EXPECT_EQ(decoded_base_db_id, base_db_id); | |
| EXPECT_EQ(decoded_base_table_id, base_table_id); | |
| EXPECT_EQ(decoded_stream_db_id, stream_db_id); | |
| EXPECT_EQ(decoded_stream_id, stream_id); | |
| EXPECT_EQ(decoded_partition_id, partition_id); | |
| } | |
| TEST(KeysTest, VersionedTableStreamOffsetKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id"; | |
| int64_t base_db_id = 101; | |
| int64_t base_table_id = 102; | |
| int64_t stream_db_id = 103; | |
| int64_t stream_id = 104; | |
| int64_t partition_id = 105; | |
| Versionstamp timestamp(888, 99); | |
| versioned::TableStreamOffsetKeyInfo info {instance_id, base_db_id, base_table_id, | |
| stream_db_id, stream_id, partition_id}; | |
| std::string key = versioned::table_stream_offset_key(info); | |
| std::string prefix = versioned::table_stream_offset_key_prefix( | |
| instance_id, base_db_id, base_table_id, stream_db_id, stream_id); | |
| ASSERT_TRUE(key.starts_with(prefix)); | |
| encode_versionstamp(timestamp, &key); | |
| encode_versionstamp_end(&key); | |
| std::string meta_prefix; | |
| std::string decoded_instance_id; | |
| std::string offset_infix; | |
| int64_t decoded_base_db_id = 0; | |
| int64_t decoded_base_table_id = 0; | |
| int64_t decoded_stream_db_id = 0; | |
| int64_t decoded_stream_id = 0; | |
| int64_t decoded_partition_id = 0; | |
| Versionstamp decoded_timestamp; | |
| std::string_view key_sv(key); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &offset_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_base_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_base_table_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_stream_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_stream_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &decoded_partition_id), 0); | |
| ASSERT_EQ(decode_versionstamp(&key_sv, &decoded_timestamp), 0); | |
| ASSERT_EQ(decode_versionstamp_end(&key_sv), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(meta_prefix, "meta"); | |
| EXPECT_EQ(decoded_instance_id, instance_id); | |
| EXPECT_EQ(offset_infix, "table_stream_offset"); | |
| EXPECT_EQ(decoded_base_db_id, base_db_id); | |
| EXPECT_EQ(decoded_base_table_id, base_table_id); | |
| EXPECT_EQ(decoded_stream_db_id, stream_db_id); | |
| EXPECT_EQ(decoded_stream_id, stream_id); | |
| EXPECT_EQ(decoded_partition_id, partition_id); | |
| EXPECT_EQ(decoded_timestamp.version(), timestamp.version()); | |
| EXPECT_EQ(decoded_timestamp.order(), timestamp.order()); | |
| } | |
| TEST(KeysTest, RestoreJobKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x01 "job" ${instance_id} "restore_tablet" ${tablet_id} | |
| { | |
| int64_t tablet_id = 10086; | |
| JobRestoreTabletKeyInfo tablet_key {instance_id, tablet_id}; | |
| std::string encoded_key; | |
| job_restore_tablet_key(tablet_key, &encoded_key); | |
| std::cout << hex(encoded_key) << std::endl; | |
| std::string dec_job_prefix; | |
| std::string dec_instance_id; | |
| int64_t dec_tablet_id = 0; | |
| std::string dec_restore_tablet_infix; | |
| std::string_view key_sv(encoded_key); | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_restore_tablet_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("restore_tablet", dec_restore_tablet_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| } | |
| // 0x01 "job" ${instance_id} "restore_rowset" ${tablet_id} ${version} | |
| { | |
| int64_t tablet_id = 10086; | |
| int64_t version = 100; | |
| JobRestoreRowsetKeyInfo rowset_key {instance_id, tablet_id, version}; | |
| std::string encoded_key; | |
| job_restore_rowset_key(rowset_key, &encoded_key); | |
| std::cout << hex(encoded_key) << std::endl; | |
| std::string dec_job_prefix; | |
| std::string dec_instance_id; | |
| std::string dec_restore_rowset_infix; | |
| int64_t dec_tablet_id = 0; | |
| int64_t dec_version = 0; | |
| std::string_view key_sv(encoded_key); | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_restore_rowset_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_tablet_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_version), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("restore_rowset", dec_restore_rowset_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| EXPECT_EQ(version, dec_version); | |
| std::get<2>(rowset_key) = version + 1; | |
| std::string encoded_key1; | |
| job_restore_rowset_key(rowset_key, &encoded_key1); | |
| std::cout << hex(encoded_key1) << std::endl; | |
| ASSERT_GT(encoded_key1, encoded_key); | |
| } | |
| } | |
| TEST(KeysTest, StreamingJobKeysTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| // 0x01 "job" ${instance_id} "streaming_job" ${db_id} ${job_id} -> StreamingJobPB | |
| { | |
| int64_t db_id = 123; | |
| int64_t job_id = 456; | |
| StreamingJobKeyInfo streaming_key {instance_id, db_id, job_id}; | |
| std::string encoded_streaming_key0; | |
| streaming_job_key(streaming_key, &encoded_streaming_key0); | |
| std::cout << hex(encoded_streaming_key0) << std::endl; | |
| std::string dec_instance_id; | |
| int64_t dec_db_id = 0; | |
| int64_t dec_job_id = 0; | |
| std::string_view key_sv(encoded_streaming_key0); | |
| std::string dec_job_prefix; | |
| std::string dec_streaming_infix; | |
| remove_user_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_job_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_streaming_infix), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_db_id), 0); | |
| ASSERT_EQ(decode_int64(&key_sv, &dec_job_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("job", dec_job_prefix); | |
| EXPECT_EQ("streaming_job", dec_streaming_infix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(job_id, dec_job_id); | |
| std::get<2>(streaming_key) = job_id + 1; | |
| std::string encoded_streaming_key1; | |
| streaming_job_key(streaming_key, &encoded_streaming_key1); | |
| std::cout << hex(encoded_streaming_key1) << std::endl; | |
| ASSERT_GT(encoded_streaming_key1, encoded_streaming_key0); | |
| std::get<1>(streaming_key) = db_id + 1; | |
| std::string encoded_streaming_key2; | |
| streaming_job_key(streaming_key, &encoded_streaming_key2); | |
| std::cout << hex(encoded_streaming_key2) << std::endl; | |
| ASSERT_GT(encoded_streaming_key2, encoded_streaming_key0); | |
| } | |
| } | |
| TEST(KeysTest, VersionedKeyPrefixTest) { | |
| using namespace doris::cloud; | |
| using namespace doris::cloud::versioned; | |
| std::string instance_id = "test_instance_id"; | |
| // Test versioned key prefixes - these use key space 0x03 | |
| { | |
| // versioned::version_key_prefix - 0x03 "version" ${instance_id} | |
| std::string version_prefix = versioned::version_key_prefix(instance_id); | |
| std::cout << "versioned::version_key_prefix: " << hex(version_prefix) << std::endl; | |
| std::string dec_version_prefix; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(version_prefix); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_version_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("version", dec_version_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| { | |
| // versioned::index_key_prefix - 0x03 "index" ${instance_id} | |
| std::string index_prefix = versioned::index_key_prefix(instance_id); | |
| std::cout << "versioned::index_key_prefix: " << hex(index_prefix) << std::endl; | |
| std::string dec_index_prefix; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(index_prefix); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_index_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("index", dec_index_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| { | |
| // versioned::stats_key_prefix - 0x03 "stats" ${instance_id} | |
| std::string stats_prefix = versioned::stats_key_prefix(instance_id); | |
| std::cout << "versioned::stats_key_prefix: " << hex(stats_prefix) << std::endl; | |
| std::string dec_stats_prefix; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(stats_prefix); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_stats_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("stats", dec_stats_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| { | |
| // versioned::meta_key_prefix - 0x03 "meta" ${instance_id} | |
| std::string meta_prefix = versioned::meta_key_prefix(instance_id); | |
| std::cout << "versioned::meta_key_prefix: " << hex(meta_prefix) << std::endl; | |
| std::string dec_meta_prefix; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(meta_prefix); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_meta_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("meta", dec_meta_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| { | |
| // versioned::data_key_prefix - 0x03 "data" ${instance_id} | |
| std::string data_prefix = versioned::data_key_prefix(instance_id); | |
| std::cout << "versioned::data_key_prefix: " << hex(data_prefix) << std::endl; | |
| std::string dec_data_prefix; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(data_prefix); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_data_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("data", dec_data_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| { | |
| // versioned::snapshot_key_prefix - 0x03 "snapshot" ${instance_id} | |
| std::string snapshot_prefix = versioned::snapshot_key_prefix(instance_id); | |
| std::cout << "versioned::snapshot_key_prefix: " << hex(snapshot_prefix) << std::endl; | |
| std::string dec_snapshot_prefix; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(snapshot_prefix); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_snapshot_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("snapshot", dec_snapshot_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| { | |
| // versioned::log_key_prefix - 0x03 "log" ${instance_id} | |
| std::string log_prefix = versioned::log_key_prefix(instance_id); | |
| std::cout << "versioned::log_key_prefix: " << hex(log_prefix) << std::endl; | |
| std::string dec_log_prefix; | |
| std::string dec_instance_id; | |
| std::string_view key_sv(log_prefix); | |
| remove_versioned_space_prefix(&key_sv); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_log_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&key_sv, &dec_instance_id), 0); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ("log", dec_log_prefix); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| } | |
| } | |
| TEST(KeysTest, DecodeStatsTabletKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| int64_t table_id = 123; | |
| int64_t index_id = 345; | |
| int64_t partition_id = 1231231231; | |
| int64_t tablet_id = 543671234523; | |
| StatsTabletKeyInfo stats_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_stats_key; | |
| stats_tablet_key(stats_key, &encoded_stats_key); | |
| // Test decode_stats_tablet_key | |
| int64_t dec_table_id = 0; | |
| int64_t dec_index_id = 0; | |
| int64_t dec_partition_id = 0; | |
| int64_t dec_tablet_id = 0; | |
| std::string_view key_sv(encoded_stats_key); | |
| ASSERT_TRUE(decode_stats_tablet_key(&key_sv, &dec_table_id, &dec_index_id, &dec_partition_id, | |
| &dec_tablet_id)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| // Test with invalid key | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_stats_tablet_key(&invalid_sv, &dec_table_id, &dec_index_id, | |
| &dec_partition_id, &dec_tablet_id)); | |
| } | |
| TEST(KeysTest, DecodeTableVersionKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| int64_t db_id = 11111; | |
| int64_t table_id = 10010; | |
| TableVersionKeyInfo v_key {instance_id, db_id, table_id}; | |
| std::string encoded_version_key; | |
| table_version_key(v_key, &encoded_version_key); | |
| // Test decode_table_version_key | |
| int64_t dec_db_id = 0; | |
| int64_t dec_table_id = 0; | |
| std::string_view key_sv(encoded_version_key); | |
| ASSERT_TRUE(decode_table_version_key(&key_sv, &dec_db_id, &dec_table_id)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| // Test with invalid key | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_table_version_key(&invalid_sv, &dec_db_id, &dec_table_id)); | |
| } | |
| TEST(KeysTest, DecodeTabletSchemaKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_meta_dict"; | |
| int64_t index_id = 10000; | |
| int32_t schema_version = 5; | |
| auto key = meta_schema_key({instance_id, index_id, schema_version}); | |
| // Test decode_tablet_schema_key | |
| int64_t dec_index_id = 0; | |
| int64_t dec_schema_version = 0; | |
| std::string_view key_sv(key); | |
| ASSERT_TRUE(decode_tablet_schema_key(&key_sv, &dec_index_id, &dec_schema_version)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| EXPECT_EQ(schema_version, dec_schema_version); | |
| // Test with invalid key | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_tablet_schema_key(&invalid_sv, &dec_index_id, &dec_schema_version)); | |
| } | |
| TEST(KeysTest, DecodePartitionVersionKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| int64_t db_id = 11111; | |
| int64_t table_id = 10086; | |
| int64_t partition_id = 9998; | |
| PartitionVersionKeyInfo v_key {instance_id, db_id, table_id, partition_id}; | |
| std::string encoded_version_key; | |
| partition_version_key(v_key, &encoded_version_key); | |
| // Test decode_partition_version_key | |
| int64_t dec_db_id = 0; | |
| int64_t dec_table_id = 0; | |
| int64_t dec_partition_id = 0; | |
| std::string_view key_sv(encoded_version_key); | |
| ASSERT_TRUE( | |
| decode_partition_version_key(&key_sv, &dec_db_id, &dec_table_id, &dec_partition_id)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(db_id, dec_db_id); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| // Test with invalid key | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_partition_version_key(&invalid_sv, &dec_db_id, &dec_table_id, | |
| &dec_partition_id)); | |
| } | |
| TEST(KeysTest, DecodeMetaTabletKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| int64_t table_id = 10010; | |
| int64_t index_id = 10011; | |
| int64_t partition_id = 10012; | |
| int64_t tablet_id = 10086; | |
| MetaTabletKeyInfo tablet_key {instance_id, table_id, index_id, partition_id, tablet_id}; | |
| std::string encoded_tablet_key; | |
| meta_tablet_key(tablet_key, &encoded_tablet_key); | |
| // Test decode_meta_tablet_key | |
| int64_t dec_table_id = 0; | |
| int64_t dec_index_id = 0; | |
| int64_t dec_partition_id = 0; | |
| int64_t dec_tablet_id = 0; | |
| std::string_view key_sv(encoded_tablet_key); | |
| ASSERT_TRUE(decode_meta_tablet_key(&key_sv, &dec_table_id, &dec_index_id, &dec_partition_id, | |
| &dec_tablet_id)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(table_id, dec_table_id); | |
| EXPECT_EQ(index_id, dec_index_id); | |
| EXPECT_EQ(partition_id, dec_partition_id); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| // Test with invalid key | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_meta_tablet_key(&invalid_sv, &dec_table_id, &dec_index_id, | |
| &dec_partition_id, &dec_tablet_id)); | |
| } | |
| TEST(KeysTest, DecodeMetaRowsetKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| int64_t tablet_id = 10086; | |
| int64_t version = 100; | |
| MetaRowsetKeyInfo rowset_key {instance_id, tablet_id, version}; | |
| std::string encoded_rowset_key; | |
| meta_rowset_key(rowset_key, &encoded_rowset_key); | |
| // Test decode_meta_rowset_key | |
| int64_t dec_tablet_id = 0; | |
| int64_t dec_version = 0; | |
| std::string_view key_sv(encoded_rowset_key); | |
| ASSERT_TRUE(decode_meta_rowset_key(&key_sv, &dec_tablet_id, &dec_version)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| EXPECT_EQ(version, dec_version); | |
| // Test with invalid key | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_meta_rowset_key(&invalid_sv, &dec_tablet_id, &dec_version)); | |
| } | |
| TEST(KeysTest, DecodeMetaTabletIdxKeyTest) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| int64_t tablet_id = 10086; | |
| MetaTabletIdxKeyInfo tablet_tbl_key {instance_id, tablet_id}; | |
| std::string encoded_tablet_idx_key; | |
| meta_tablet_idx_key(tablet_tbl_key, &encoded_tablet_idx_key); | |
| // Test decode_meta_tablet_idx_key | |
| int64_t dec_tablet_id = 0; | |
| std::string_view key_sv(encoded_tablet_idx_key); | |
| ASSERT_TRUE(decode_meta_tablet_idx_key(&key_sv, &dec_tablet_id)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(tablet_id, dec_tablet_id); | |
| // Test with invalid key | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_meta_tablet_idx_key(&invalid_sv, &dec_tablet_id)); | |
| } | |
| TEST(KeysTest, DecodeSnapshotRefKeyTest) { | |
| using namespace doris::cloud; | |
| using namespace doris::cloud::versioned; | |
| std::string instance_id = "test_instance_id"; | |
| Versionstamp timestamp(0x0102030405060708ULL, 0x090a); | |
| std::string ref_instance_id = "derived_instance_id"; | |
| // Encode a snapshot reference key | |
| SnapshotReferenceKeyInfo key_info {instance_id, timestamp, ref_instance_id}; | |
| std::string encoded_key = snapshot_reference_key(key_info); | |
| std::string prefix = snapshot_reference_key_prefix(instance_id); | |
| EXPECT_TRUE(encoded_key.starts_with(prefix)); | |
| { | |
| std::string_view prefix_view = prefix; | |
| remove_versioned_space_prefix(&prefix_view); | |
| std::string decoded_prefix; | |
| std::string decoded_instance_id; | |
| std::string decoded_infix; | |
| ASSERT_EQ(decode_bytes(&prefix_view, &decoded_prefix), 0); | |
| ASSERT_EQ(decode_bytes(&prefix_view, &decoded_instance_id), 0); | |
| ASSERT_EQ(decode_bytes(&prefix_view, &decoded_infix), 0); | |
| EXPECT_TRUE(prefix_view.empty()); | |
| EXPECT_EQ(decoded_prefix, "snapshot"); | |
| EXPECT_EQ(decoded_instance_id, instance_id); | |
| EXPECT_EQ(decoded_infix, "reference"); | |
| } | |
| // Test decode_snapshot_ref_key - decode all fields | |
| { | |
| std::string dec_instance_id; | |
| Versionstamp dec_timestamp; | |
| std::string dec_ref_instance_id; | |
| std::string_view key_view = encoded_key; | |
| bool ret = decode_snapshot_ref_key(&key_view, &dec_instance_id, &dec_timestamp, | |
| &dec_ref_instance_id); | |
| ASSERT_TRUE(ret); | |
| EXPECT_TRUE(key_view.empty()); | |
| EXPECT_EQ(dec_instance_id, instance_id); | |
| EXPECT_EQ(dec_timestamp, timestamp); | |
| EXPECT_EQ(dec_ref_instance_id, ref_instance_id); | |
| } | |
| // Test decode_snapshot_ref_key - decode only ref_instance_id (nullptr for others) | |
| { | |
| std::string dec_ref_instance_id; | |
| std::string_view key_view = encoded_key; | |
| bool ret = decode_snapshot_ref_key(&key_view, nullptr, nullptr, &dec_ref_instance_id); | |
| ASSERT_TRUE(ret); | |
| EXPECT_TRUE(key_view.empty()); | |
| EXPECT_EQ(dec_ref_instance_id, ref_instance_id); | |
| } | |
| // Test decode_snapshot_ref_key - decode only instance_id and timestamp | |
| { | |
| std::string dec_instance_id; | |
| Versionstamp dec_timestamp; | |
| std::string_view key_view = encoded_key; | |
| bool ret = decode_snapshot_ref_key(&key_view, &dec_instance_id, &dec_timestamp, nullptr); | |
| ASSERT_TRUE(ret); | |
| EXPECT_TRUE(key_view.empty()); | |
| EXPECT_EQ(dec_instance_id, instance_id); | |
| EXPECT_EQ(dec_timestamp, timestamp); | |
| } | |
| // Test with invalid key - empty | |
| { | |
| std::string dec_ref_instance_id; | |
| std::string_view key_view = ""; | |
| bool ret = decode_snapshot_ref_key(&key_view, nullptr, nullptr, &dec_ref_instance_id); | |
| ASSERT_FALSE(ret); | |
| } | |
| // Test with invalid key - wrong prefix | |
| { | |
| std::string invalid_key = "invalid_key"; | |
| std::string dec_ref_instance_id; | |
| std::string_view key_view = invalid_key; | |
| bool ret = decode_snapshot_ref_key(&key_view, nullptr, nullptr, &dec_ref_instance_id); | |
| ASSERT_FALSE(ret); | |
| } | |
| // Every strict prefix of a valid key must be rejected without throwing. | |
| for (size_t size = 0; size < encoded_key.size(); ++size) { | |
| SCOPED_TRACE(size); | |
| std::string_view key_view(encoded_key.data(), size); | |
| EXPECT_FALSE(decode_snapshot_ref_key(&key_view, nullptr, nullptr, nullptr)); | |
| } | |
| // A successfully decoded key may retain a caller-owned suffix. | |
| { | |
| std::string key_with_suffix = encoded_key; | |
| key_with_suffix.push_back('\0'); | |
| std::string_view key_view = key_with_suffix; | |
| EXPECT_TRUE(decode_snapshot_ref_key(&key_view, nullptr, nullptr, nullptr)); | |
| EXPECT_EQ(key_view, std::string_view("\0", 1)); | |
| } | |
| // The timestamp field must carry a versionstamp tag, not merely another decodable field. | |
| { | |
| std::string invalid_key = prefix; | |
| encode_int64(1, &invalid_key); | |
| encode_bytes(ref_instance_id, &invalid_key); | |
| std::string_view key_view = invalid_key; | |
| EXPECT_FALSE(decode_snapshot_ref_key(&key_view, nullptr, nullptr, nullptr)); | |
| } | |
| // Test with multiple ref_instance_ids to ensure uniqueness | |
| { | |
| std::string ref_id1 = "ref_instance_1"; | |
| std::string ref_id2 = "ref_instance_2"; | |
| std::string ref_id3 = "ref_instance_3"; | |
| SnapshotReferenceKeyInfo key1 {instance_id, timestamp, ref_id1}; | |
| SnapshotReferenceKeyInfo key2 {instance_id, timestamp, ref_id2}; | |
| SnapshotReferenceKeyInfo key3 {instance_id, timestamp, ref_id3}; | |
| std::string encoded1 = snapshot_reference_key(key1); | |
| std::string encoded2 = snapshot_reference_key(key2); | |
| std::string encoded3 = snapshot_reference_key(key3); | |
| std::string dec_ref1, dec_ref2, dec_ref3; | |
| std::string_view key_view1 = encoded1; | |
| std::string_view key_view2 = encoded2; | |
| std::string_view key_view3 = encoded3; | |
| ASSERT_TRUE(decode_snapshot_ref_key(&key_view1, nullptr, nullptr, &dec_ref1)); | |
| ASSERT_TRUE(decode_snapshot_ref_key(&key_view2, nullptr, nullptr, &dec_ref2)); | |
| ASSERT_TRUE(decode_snapshot_ref_key(&key_view3, nullptr, nullptr, &dec_ref3)); | |
| EXPECT_TRUE(key_view1.empty()); | |
| EXPECT_TRUE(key_view2.empty()); | |
| EXPECT_TRUE(key_view3.empty()); | |
| EXPECT_EQ(dec_ref1, ref_id1); | |
| EXPECT_EQ(dec_ref2, ref_id2); | |
| EXPECT_EQ(dec_ref3, ref_id3); | |
| } | |
| } | |
| TEST(KeysTest, VersionedDecodersRequireExactSchema) { | |
| using namespace doris::cloud; | |
| const Versionstamp timestamp(123, 4); | |
| auto append_timestamp = [&](std::string key) { | |
| encode_versionstamp(timestamp, &key); | |
| encode_versionstamp_end(&key); | |
| return key; | |
| }; | |
| auto append_int = [](std::string key) { | |
| encode_int64(123, &key); | |
| return key; | |
| }; | |
| { | |
| std::string valid_key = | |
| append_timestamp(versioned::table_version_key({"instance-id", 100})); | |
| std::string_view key_view = valid_key; | |
| int64_t table_id = 0; | |
| Versionstamp decoded_timestamp; | |
| ASSERT_TRUE(versioned::decode_table_version_key(&key_view, &table_id, &decoded_timestamp)); | |
| EXPECT_TRUE(key_view.empty()); | |
| EXPECT_EQ(table_id, 100); | |
| EXPECT_EQ(decoded_timestamp, timestamp); | |
| std::string invalid_key = append_int(versioned::table_version_key({"instance-id", 100})); | |
| key_view = invalid_key; | |
| EXPECT_FALSE(versioned::decode_table_version_key(&key_view, &table_id, &decoded_timestamp)); | |
| invalid_key.assign(1, static_cast<char>(CLOUD_VERSIONED_KEY_SPACE03)); | |
| encode_bytes("version", &invalid_key); | |
| encode_int64(1, &invalid_key); // instance_id must be encoded as bytes. | |
| encode_bytes("table", &invalid_key); | |
| encode_int64(100, &invalid_key); | |
| invalid_key = append_timestamp(std::move(invalid_key)); | |
| key_view = invalid_key; | |
| EXPECT_FALSE(versioned::decode_table_version_key(&key_view, &table_id, &decoded_timestamp)); | |
| } | |
| { | |
| std::string invalid_key = append_int(versioned::meta_partition_key({"instance-id", 101})); | |
| std::string_view key_view = invalid_key; | |
| int64_t partition_id = 0; | |
| Versionstamp decoded_timestamp; | |
| EXPECT_FALSE( | |
| versioned::decode_meta_partition_key(&key_view, &partition_id, &decoded_timestamp)); | |
| } | |
| { | |
| std::string invalid_key = append_int(versioned::meta_index_key({"instance-id", 102})); | |
| std::string_view key_view = invalid_key; | |
| int64_t index_id = 0; | |
| Versionstamp decoded_timestamp; | |
| EXPECT_FALSE(versioned::decode_meta_index_key(&key_view, &index_id, &decoded_timestamp)); | |
| } | |
| { | |
| std::string invalid_key = append_int(versioned::meta_tablet_key({"instance-id", 103})); | |
| std::string_view key_view = invalid_key; | |
| int64_t tablet_id = 0; | |
| Versionstamp decoded_timestamp; | |
| EXPECT_FALSE(versioned::decode_meta_tablet_key(&key_view, &tablet_id, &decoded_timestamp)); | |
| invalid_key = versioned::meta_tablet_key({"instance-id", 103}); | |
| encode_int64(104, &invalid_key); | |
| invalid_key = append_timestamp(std::move(invalid_key)); | |
| key_view = invalid_key; | |
| EXPECT_FALSE(versioned::decode_meta_tablet_key(&key_view, &tablet_id, &decoded_timestamp)); | |
| } | |
| { | |
| std::string invalid_key = | |
| versioned::partition_inverted_index_key({"instance-id", 100, 101, 102}); | |
| ASSERT_GT(invalid_key.size(), 2); | |
| invalid_key[2] = 'x'; // Corrupt the encoded "index" family prefix. | |
| std::string_view key_view = invalid_key; | |
| int64_t db_id = 0; | |
| int64_t table_id = 0; | |
| int64_t partition_id = 0; | |
| EXPECT_FALSE(versioned::decode_partition_inverted_index_key(&key_view, &db_id, &table_id, | |
| &partition_id)); | |
| } | |
| } | |
| TEST(KeysTest, DecodeInstanceKey) { | |
| using namespace doris::cloud; | |
| std::string instance_id = "instance_id_deadbeef"; | |
| std::string encoded_instance_key = instance_key({instance_id}); | |
| std::string dec_instance_id; | |
| std::string_view key_sv(encoded_instance_key); | |
| ASSERT_TRUE(decode_instance_key(&key_sv, &dec_instance_id)); | |
| ASSERT_TRUE(key_sv.empty()); | |
| EXPECT_EQ(instance_id, dec_instance_id); | |
| std::string invalid_key = "invalid"; | |
| std::string_view invalid_sv(invalid_key); | |
| ASSERT_FALSE(decode_instance_key(&invalid_sv, &dec_instance_id)); | |
| } |