1327 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1327 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2021 OceanBase
 | |
|  * OceanBase CE is licensed under Mulan PubL v2.
 | |
|  * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | |
|  * You may obtain a copy of Mulan PubL v2 at:
 | |
|  *          http://license.coscl.org.cn/MulanPubL-2.0
 | |
|  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | |
|  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | |
|  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | |
|  * See the Mulan PubL v2 for more details.
 | |
|  */
 | |
| 
 | |
| #include <gtest/gtest.h>
 | |
| #include "ob_sstable_test.h"
 | |
| #include "lib/container/ob_array_iterator.h"
 | |
| 
 | |
| namespace oceanbase {
 | |
| using namespace blocksstable;
 | |
| using namespace common;
 | |
| using namespace storage;
 | |
| using namespace share::schema;
 | |
| 
 | |
| namespace unittest {
 | |
| class TestSSTableMultiScanner : public ObSSTableTest {
 | |
| public:
 | |
|   TestSSTableMultiScanner();
 | |
|   virtual ~TestSSTableMultiScanner();
 | |
|   void test_one_case(const ObIArray<int64_t>& start_seeds, const int64_t count_perf_range, const int64_t hit_mode,
 | |
|       const bool is_reverse_scan);
 | |
|   void test_skip_range(const ObIArray<int64_t>& start_seeds, const int64_t count_per_range, const bool is_reverse_scan,
 | |
|       const ObIArray<SkipInfo>& skip_infos);
 | |
|   void test_single_get_normal(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_single_get_border(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_multi_get_normal(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_multi_get_border(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_single_scan_normal(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_single_scan_border(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_multi_scan_multi_scan_range(const bool is_reverse_scan, const int64_t limit, const int64_t count_per_range);
 | |
|   void test_multi_scan_multi_get_with_scan(
 | |
|       const bool is_reverse_scan, const int64_t limit, const int64_t count_per_range);
 | |
|   void test_multi_block_read_small_io(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_multi_block_read_big_continue_io(const bool is_reverse_scan, const int64_t limit);
 | |
|   void test_multi_block_read_big_discrete_io(const bool is_reverse_scan, const int64_t limit);
 | |
| };
 | |
| 
 | |
| TestSSTableMultiScanner::TestSSTableMultiScanner() : ObSSTableTest("multi_scan_sstable")
 | |
| {}
 | |
| 
 | |
| TestSSTableMultiScanner::~TestSSTableMultiScanner()
 | |
| {}
 | |
| 
 | |
| void TestSSTableMultiScanner::test_skip_range(const ObIArray<int64_t>& start_seeds, const int64_t count_per_range,
 | |
|     const bool is_reverse_scan, const ObIArray<SkipInfo>& skip_infos)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObStoreRowkey mscan_rowkeys[TEST_MULTI_GET_CNT];
 | |
|   ObStoreRange mscan_ranges[TEST_MULTI_GET_CNT];
 | |
|   ObObj mscan_start_cells[TEST_MULTI_GET_CNT][TEST_COLUMN_CNT];
 | |
|   ObObj mscan_end_cells[TEST_MULTI_GET_CNT][TEST_COLUMN_CNT];
 | |
|   ObStoreRow mscan_start_rows[TEST_MULTI_GET_CNT];
 | |
|   ObStoreRow mscan_end_rows[TEST_MULTI_GET_CNT];
 | |
|   ObArray<ObStoreRange> ranges;
 | |
|   ObArray<ObExtStoreRange> ext_ranges;
 | |
|   ObObj check_cells[TEST_COLUMN_CNT];
 | |
|   ObStoreRow check_row;
 | |
|   check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|   ObStoreRowIterator* scanner;
 | |
|   const ObStoreRow* prow = NULL;
 | |
|   const int64_t step = is_reverse_scan ? -1 : 1;
 | |
|   ObStoreRow gap_row;
 | |
|   ObStoreRowkey gap_rowkey;
 | |
|   ObObj gap_key_cells[TEST_COLUMN_CNT];
 | |
|   gap_row.row_val_.assign(gap_key_cells, TEST_COLUMN_CNT);
 | |
| 
 | |
|   const int64_t limit = -1;
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   for (int64_t i = 0; i < start_seeds.count(); ++i) {
 | |
|     mscan_start_rows[i].row_val_.assign(mscan_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mscan_end_rows[i].row_val_.assign(mscan_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mscan_ranges[i].get_start_key().assign(mscan_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mscan_ranges[i].get_end_key().assign(mscan_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mscan_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mscan_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(start_seeds.at(i), mscan_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(start_seeds.at(i) + count_per_range - 1, mscan_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = 0; i < start_seeds.count(); ++i) {
 | |
|     ret = ranges.push_back(mscan_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   STORAGE_LOG(INFO, "multi scan ranges", K(ext_ranges));
 | |
|   for (int64_t i = 0; i < start_seeds.count(); ++i) {
 | |
|     const int64_t start = is_reverse_scan ? start_seeds.at(i) + count_per_range - 1 : start_seeds.at(i);
 | |
|     const int64_t end = is_reverse_scan ? start_seeds.at(i) : start_seeds.at(i) + count_per_range - 1;
 | |
|     for (int64_t j = start; compare(is_reverse_scan, j, end); j += step) {
 | |
|       int64_t k = 0;
 | |
|       ret = row_generate_.get_next_row(j, check_row);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       STORAGE_LOG(INFO, "get_next_row_generate", K(check_row), K(*prow), K(j), K(i), K(end), K(start));
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       STORAGE_LOG(INFO, "get_next_row", K(check_row), K(*prow));
 | |
|       ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|       for (k = 0; OB_SUCC(ret) && k < skip_infos.count(); ++k) {
 | |
|         if (skip_infos.at(k).start_key_ == j) {
 | |
|           j = skip_infos.at(k).gap_key_ - step;
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|       if (k != skip_infos.count()) {
 | |
|         ret = row_generate_.get_next_row(skip_infos.at(k).gap_key_, gap_row);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         gap_rowkey.assign(gap_key_cells, TEST_ROWKEY_COLUMN_CNT);
 | |
|         STORAGE_LOG(INFO, "skip range to", K(gap_rowkey), K(skip_infos.at(k)), K(i), K(start_seeds));
 | |
|         ret = scanner->skip_range(i, &gap_rowkey, true);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
|   if (nullptr != scanner) {
 | |
|     scanner->~ObStoreRowIterator();
 | |
|     scanner = nullptr;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_one_case(const ObIArray<int64_t>& start_seeds, const int64_t count_per_range,
 | |
|     const int64_t hit_mode, const bool is_reverse_scan)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObStoreRowkey mscan_rowkeys[TEST_MULTI_GET_CNT];
 | |
|   ObStoreRange mscan_ranges[TEST_MULTI_GET_CNT];
 | |
|   ObObj mscan_start_cells[TEST_MULTI_GET_CNT][TEST_COLUMN_CNT];
 | |
|   ObObj mscan_end_cells[TEST_MULTI_GET_CNT][TEST_COLUMN_CNT];
 | |
|   ObStoreRow mscan_start_rows[TEST_MULTI_GET_CNT];
 | |
|   ObStoreRow mscan_end_rows[TEST_MULTI_GET_CNT];
 | |
|   ObArray<ObStoreRange> ranges;
 | |
|   ObArray<ObExtStoreRange> ext_ranges;
 | |
|   ObObj check_cells[TEST_COLUMN_CNT];
 | |
|   ObStoreRow check_row;
 | |
|   ObStoreRowIterator* scanner = nullptr;
 | |
|   const ObStoreRow* prow = NULL;
 | |
|   if (HIT_PART == hit_mode) {
 | |
|     ObArray<ObStoreRange> part_ranges;
 | |
|     ObArray<ObStoreRange> tmp_ranges;
 | |
|     ObArray<ObExtStoreRange> part_ext_ranges;
 | |
|     ret = tmp_ranges.assign(ranges);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     std::random_shuffle(tmp_ranges.begin(), tmp_ranges.end());
 | |
|     for (int64_t i = 0; tmp_ranges.count() / 3; ++i) {
 | |
|       ret = part_ranges.push_back(tmp_ranges.at(i));
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     }
 | |
|     if (part_ranges.count() > 0) {
 | |
|       convert_range(part_ranges, part_ext_ranges, allocator_);
 | |
|       ret = sstable_.multi_scan(param_, context_, part_ext_ranges, scanner);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       for (int64_t i = 0; OB_SUCC(ret); ++i) {
 | |
|         ret = scanner->get_next_row(prow);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       }
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_ITER_END, ret);
 | |
|     }
 | |
|   }
 | |
|   if (nullptr != scanner) {
 | |
|     scanner->~ObStoreRowIterator();
 | |
|     scanner = nullptr;
 | |
|   }
 | |
|   for (int64_t i = 0; i < start_seeds.count(); ++i) {
 | |
|     mscan_start_rows[i].row_val_.assign(mscan_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mscan_end_rows[i].row_val_.assign(mscan_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mscan_ranges[i].get_start_key().assign(mscan_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mscan_ranges[i].get_end_key().assign(mscan_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mscan_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mscan_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(start_seeds.at(i), mscan_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(start_seeds.at(i) + count_per_range - 1, mscan_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = 0; i < start_seeds.count(); ++i) {
 | |
|     ret = ranges.push_back(mscan_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = 0; i < start_seeds.count(); ++i) {
 | |
|     for (int64_t j = 0; j < count_per_range; ++j) {
 | |
|       const int64_t k = is_reverse_scan ? start_seeds.at(i) + count_per_range - j - 1 : start_seeds.at(i) + j;
 | |
|       if (k < row_cnt_ || ext_ranges.at(i).get_range().is_single_rowkey()) {
 | |
|         check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|         ret = row_generate_.get_next_row(k, check_row);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ret = scanner->get_next_row(prow);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         if (k < row_cnt_) {
 | |
|           ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|         } else {
 | |
|           ASSERT_TRUE(prow->flag_ == ObActionFlag::OP_ROW_DOES_NOT_EXIST);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
|   if (nullptr != scanner) {
 | |
|     scanner->~ObStoreRowIterator();
 | |
|     scanner = nullptr;
 | |
|   }
 | |
| 
 | |
|   if (HIT_ALL == hit_mode) {
 | |
|     ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     for (int64_t i = 0; i < start_seeds.count(); ++i) {
 | |
|       for (int64_t j = 0; j < count_per_range; ++j) {
 | |
|         const int64_t k = is_reverse_scan ? start_seeds.at(i) + count_per_range - j - 1 : start_seeds.at(i) + j;
 | |
|         if (k < row_cnt_ || ext_ranges.at(i).get_range().is_single_rowkey()) {
 | |
|           check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|           ret = scanner->get_next_row(prow);
 | |
|           ASSERT_EQ(OB_SUCCESS, ret);
 | |
|           ret = row_generate_.get_next_row(k, check_row);
 | |
|           if (k < row_cnt_) {
 | |
|             ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|           } else {
 | |
|             ASSERT_TRUE(prow->flag_ == ObActionFlag::OP_ROW_DOES_NOT_EXIST);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     ret = scanner->get_next_row(prow);
 | |
|     ASSERT_EQ(OB_ITER_END, ret);
 | |
|     if (nullptr != scanner) {
 | |
|       scanner->~ObStoreRowIterator();
 | |
|       scanner = nullptr;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_single_get_normal(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   // prepare query param and context
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // row in first macro
 | |
|   ret = seeds.push_back(3);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // row in middle macro
 | |
|   seeds.reset();
 | |
|   seeds.push_back(row_cnt_ / 2);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // row in last macro, in cache
 | |
|   seeds.reset();
 | |
|   seeds.push_back(row_cnt_ - 3);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_single_get_border(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   // prepare query param and context
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // left border rowkey
 | |
|   ret = seeds.push_back(0);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // right border rowkey
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_ - 1);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // not exist
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_multi_get_normal(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
| 
 | |
|   // prepare query param
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // 2 rows exist test
 | |
|   seeds.reuse();
 | |
|   for (int64_t i = 0; i < 2; ++i) {
 | |
|     ret = seeds.push_back(i * 11 + 2);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // 10 rows exist test
 | |
|   seeds.reuse();
 | |
|   for (int64_t i = 0; i < 10; ++i) {
 | |
|     ret = seeds.push_back(i * 11 + 2);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // TEST_MULTI_GET_CNT rows test
 | |
|   seeds.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
| 
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // single row exist test
 | |
|   seeds.reuse();
 | |
|   ret = seeds.push_back(3);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // some row exist, while other rows not exist
 | |
|   seeds.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(i + (i % 2 ? row_cnt_ : 0));
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // 2 row2 not exist
 | |
|   seeds.reuse();
 | |
|   for (int64_t i = 0; i < 2; ++i) {
 | |
|     ret = seeds.push_back(i * 11 + 2 + row_cnt_);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // 10 rows not exist
 | |
|   seeds.reuse();
 | |
|   for (int64_t i = 0; i < 10; ++i) {
 | |
|     ret = seeds.push_back(i * 11 + 2 + row_cnt_);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // TEST_MULTI_GET_CNT rows not exist
 | |
|   seeds.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(i * 11 + 2 + row_cnt_);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_multi_get_border(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   // prepare query param
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // first row of sstable
 | |
|   ret = seeds.push_back(0);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, false);
 | |
|   }
 | |
| 
 | |
|   // last row of sstable
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_ - 1);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, false);
 | |
|   }
 | |
| 
 | |
|   // single row not exist
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, false);
 | |
|   }
 | |
| 
 | |
|   // TEST_MULTI_GET_CNT rows with same rowkey
 | |
|   seeds.reset();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(row_cnt_ / 2);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_single_scan_normal(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   ObRandom random;
 | |
|   const int64_t random_start = random.get(0, 10000000) % row_cnt_;
 | |
|   const int64_t random_end = random.get(0, 100000000) % row_cnt_;
 | |
|   const int64_t start = std::min(random_start, random_end);
 | |
|   const int64_t end = std::max(random_start, random_end);
 | |
| 
 | |
|   // prepare query param
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // multiple rows exist
 | |
|   ret = seeds.push_back(start);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, end - start, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // multiple rows, partial exist
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(start);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, row_cnt_ + 10 - start, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // single row exist
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_ / 2);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // not exist
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_ + 10);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 10, i, is_reverse_scan);
 | |
|   }
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_single_scan_border(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   // prepare query param
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // full table scan
 | |
|   ret = seeds.push_back(0);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, row_cnt_, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // first row of sstable
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(0);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // last row of sstable
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_ - 1);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // not exist
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_multi_block_read_small_io(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   GCONF.multiblock_read_size = 10 * 1024;
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   seeds.reuse();
 | |
|   destroy_all_cache();
 | |
|   for (int64_t i = 0; i < 10; ++i) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
| 
 | |
|   destroy_all_cache();
 | |
|   std::random_shuffle(seeds.begin(), seeds.end());
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_multi_block_read_big_continue_io(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   GCONF.multiblock_read_size = 10 * 1024;
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   seeds.reuse();
 | |
|   destroy_all_cache();
 | |
|   for (int64_t i = 0; i < 100; ++i) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
| 
 | |
|   // gap_size < multiblock_gap_size
 | |
|   GCONF.multiblock_read_gap_size = 5 * 1024;
 | |
|   seeds.reuse();
 | |
|   destroy_all_cache();
 | |
|   for (int64_t i = 0; i < 100; i += 15) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
| 
 | |
|   // gap_size > multiblock_read_gap_size
 | |
|   GCONF.multiblock_read_gap_size = 0;
 | |
|   seeds.reuse();
 | |
|   destroy_all_cache();
 | |
|   for (int64_t i = 0; i < 100; i += 15) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_multi_block_read_big_discrete_io(const bool is_reverse_scan, const int64_t limit)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObArray<int64_t> seeds;
 | |
|   GCONF.multiblock_read_size = 10 * 1024;
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   seeds.reuse();
 | |
|   destroy_all_cache();
 | |
|   for (int64_t i = 0; i < 100; ++i) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   std::random_shuffle(seeds.begin(), seeds.end());
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
| 
 | |
|   // gap_size < multiblock_gap_size
 | |
|   GCONF.multiblock_read_gap_size = 5 * 1024;
 | |
|   seeds.reuse();
 | |
|   destroy_all_cache();
 | |
|   for (int64_t i = 0; i < 100; i += 15) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   std::random_shuffle(seeds.begin(), seeds.end());
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
| 
 | |
|   // gap_size > multiblock_read_gap_size
 | |
|   GCONF.multiblock_read_gap_size = 0;
 | |
|   seeds.reuse();
 | |
|   destroy_all_cache();
 | |
|   for (int64_t i = 0; i < 100; i += 15) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   std::random_shuffle(seeds.begin(), seeds.end());
 | |
|   test_one_case(seeds, 2, HIT_NONE, is_reverse_scan);
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_get_normal)
 | |
| {
 | |
|   const bool is_reverse_scan = false;
 | |
|   test_single_get_normal(is_reverse_scan, -1);
 | |
|   test_single_get_normal(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_get_normal_reverse_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = true;
 | |
|   test_single_get_normal(is_reverse_scan, -1);
 | |
|   test_single_get_normal(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_get_border)
 | |
| {
 | |
|   const bool is_reverse_scan = false;
 | |
|   test_single_get_border(is_reverse_scan, -1);
 | |
|   test_single_get_border(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_get_border_reverse_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = true;
 | |
|   test_single_get_border(is_reverse_scan, -1);
 | |
|   test_single_get_border(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_get_normal)
 | |
| {
 | |
|   const bool is_reverse_scan = false;
 | |
|   test_multi_get_normal(is_reverse_scan, -1);
 | |
|   test_multi_get_normal(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_get_normal_reverse_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = true;
 | |
|   test_multi_get_normal(is_reverse_scan, -1);
 | |
|   test_multi_get_normal(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_scan_normal)
 | |
| {
 | |
|   const bool is_reverse_scan = false;
 | |
|   test_single_scan_normal(is_reverse_scan, -1);
 | |
|   test_single_scan_normal(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_scan_normal_reverse_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = true;
 | |
|   test_single_scan_normal(is_reverse_scan, -1);
 | |
|   test_single_scan_normal(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_scan_border)
 | |
| {
 | |
|   const bool is_reverse_scan = false;
 | |
|   test_single_scan_border(is_reverse_scan, -1);
 | |
|   test_single_scan_border(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_single_scan_border_reverse_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = true;
 | |
|   test_single_scan_border(is_reverse_scan, -1);
 | |
|   test_single_scan_border(is_reverse_scan, 1);
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_multi_scan_multi_scan_range(
 | |
|     const bool is_reverse_scan, const int64_t limit, const int64_t count_per_range)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObStoreRowIterator* scanner;
 | |
|   ObStoreRange range;
 | |
|   ObArray<ObStoreRange> ranges;
 | |
|   ObArray<ObExtStoreRange> ext_ranges;
 | |
|   ObStoreRow row;
 | |
|   ObStoreRowkey rowkey;
 | |
|   ObArray<int64_t> seeds;
 | |
| 
 | |
|   // prepare query param
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // invalid argument with 0 ranges
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_NE(OB_SUCCESS, ret);
 | |
| 
 | |
|   // invalid argument with empty rowkey
 | |
|   // range.start_key_ = rowkey;
 | |
|   // range.end_key_ = rowkey;
 | |
|   // range.border_flag_.set_inclusive_start();
 | |
|   // range.border_flag_.set_inclusive_end();
 | |
|   // ret = ext_ranges.push_back(ObExtStoreRange(range));
 | |
|   // ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   // ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   // ASSERT_NE(OB_SUCCESS, ret);
 | |
| 
 | |
|   // invalid invoke when not inited
 | |
|   ranges.reuse();
 | |
|   ret = ext_ranges.push_back(ObExtStoreRange(range));
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   ObSSTable sstable;
 | |
|   ret = sstable.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_NE(OB_SUCCESS, ret);
 | |
| 
 | |
|   // left border rowkey
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(0);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // right border rowkey
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_ - 2);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // not exist rowkey
 | |
|   seeds.reset();
 | |
|   ret = seeds.push_back(row_cnt_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, 1, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   seeds.reset();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, count_per_range, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   seeds.reset();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(0);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, count_per_range, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // not exist : all
 | |
|   seeds.reset();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(row_cnt_ + i);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, count_per_range, i, is_reverse_scan);
 | |
|   }
 | |
| 
 | |
|   // not exist : partial
 | |
|   seeds.reset();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = seeds.push_back(i % 2 ? i : i + row_cnt_);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = HIT_ALL; i < HIT_MAX; ++i) {
 | |
|     test_one_case(seeds, count_per_range, i, is_reverse_scan);
 | |
|   }
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = false;
 | |
|   int64_t limit = -1;
 | |
|   for (int64_t i = 2; i < 20; i += 10) {
 | |
|     test_multi_scan_multi_scan_range(is_reverse_scan, limit, i);
 | |
|     limit += 2;
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_reverse_multi_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = true;
 | |
|   int64_t limit = -1;
 | |
|   for (int64_t i = 2; i < 20; i += 10) {
 | |
|     test_multi_scan_multi_scan_range(is_reverse_scan, limit, i);
 | |
|     limit += 2;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TestSSTableMultiScanner::test_multi_scan_multi_get_with_scan(
 | |
|     const bool is_reverse_scan, const int64_t limit, const int64_t count_per_range)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   ObStoreRowIterator* scanner = NULL;
 | |
|   ObStoreRange range;
 | |
|   ObArray<ObStoreRange> ranges;
 | |
|   ObArray<ObExtStoreRange> ext_ranges;
 | |
|   ObStoreRow row;
 | |
|   ObStoreRowkey rowkey;
 | |
|   const ObStoreRow* prow = NULL;
 | |
|   ObObj check_cells[TEST_COLUMN_CNT];
 | |
|   ObStoreRow check_row;
 | |
|   int64_t row_cnt = 0;
 | |
|   STORAGE_LOG(INFO, "limit info", K(is_reverse_scan), K(limit));
 | |
| 
 | |
|   // prepare query param
 | |
|   ret = prepare_query_param(is_reverse_scan, limit);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // multi scan interact with multi get
 | |
|   ObStoreRowkey mget_rowkeys[TEST_MULTI_GET_CNT];
 | |
|   ObStoreRange mget_ranges[TEST_MULTI_GET_CNT];
 | |
|   ObObj mget_start_cells[TEST_MULTI_GET_CNT][TEST_COLUMN_CNT];
 | |
|   ObObj mget_end_cells[TEST_MULTI_GET_CNT][TEST_COLUMN_CNT];
 | |
|   ObStoreRow mget_start_rows[TEST_MULTI_GET_CNT];
 | |
|   ObStoreRow mget_end_rows[TEST_MULTI_GET_CNT];
 | |
|   ranges.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     mget_start_rows[i].row_val_.assign(mget_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_end_rows[i].row_val_.assign(mget_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_ranges[i].get_start_key().assign(mget_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_end_key().assign(mget_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(i, mget_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(i + (i % 2 ? count_per_range - 1 : 0), mget_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     ret = ranges.push_back(mget_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   destroy_cache();
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   STORAGE_LOG(INFO, "multi scan begin");
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   row_cnt = 0;
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     const int64_t p = i;
 | |
|     if (p % 2) {
 | |
|       for (int64_t j = 0; j < count_per_range; ++j) {
 | |
|         const int64_t k = is_reverse_scan ? i + count_per_range - j - 1 : i + j;
 | |
|         check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|         ret = scanner->get_next_row(prow);
 | |
|         if (OB_SUCCESS != ret) {
 | |
|           STORAGE_LOG(INFO, "limit info", K(limit));
 | |
|         }
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ret = row_generate_.get_next_row(k, check_row);
 | |
|         ++row_cnt;
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|       }
 | |
|     } else {
 | |
|       check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ret = row_generate_.get_next_row(p, check_row);
 | |
|       ++row_cnt;
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
| 
 | |
|   // TODO: fix here
 | |
|   // ObCostMetrics cost_metrics;
 | |
|   // ret = sstable_.estimate_multi_scan_cost(context_.query_flag_, table_key_.table_id_, ext_ranges, cost_metrics);
 | |
|   // ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   // ASSERT_EQ(row_cnt, cost_metrics.result_row_count_);
 | |
| 
 | |
|   // first half multi scan, second half multi get
 | |
|   ranges.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     mget_start_rows[i].row_val_.assign(mget_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_end_rows[i].row_val_.assign(mget_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_ranges[i].get_start_key().assign(mget_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_end_key().assign(mget_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(i, mget_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(i + (i < TEST_MULTI_GET_CNT / 2 ? count_per_range - 1 : 0), mget_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = ranges.push_back(mget_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   destroy_cache();
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     const int64_t p = i;
 | |
|     if (p < TEST_MULTI_GET_CNT / 2) {
 | |
|       for (int64_t j = 0; j < count_per_range; ++j) {
 | |
|         const int64_t k = is_reverse_scan ? i + count_per_range - j - 1 : i + j;
 | |
|         check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|         ret = scanner->get_next_row(prow);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ret = row_generate_.get_next_row(k, check_row);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|       }
 | |
|     } else {
 | |
|       check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ret = row_generate_.get_next_row(p, check_row);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
| 
 | |
|   // first half multi get, second half multi scan
 | |
|   ranges.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     mget_start_rows[i].row_val_.assign(mget_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_end_rows[i].row_val_.assign(mget_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_ranges[i].get_start_key().assign(mget_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_end_key().assign(mget_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(i, mget_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(i + (i > TEST_MULTI_GET_CNT / 2 ? count_per_range - 1 : 0), mget_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = ranges.push_back(mget_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   destroy_cache();
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     const int64_t p = i;
 | |
|     if (p > TEST_MULTI_GET_CNT / 2) {
 | |
|       for (int64_t j = 0; j < count_per_range; ++j) {
 | |
|         const int64_t k = is_reverse_scan ? i + count_per_range - j - 1 : i + j;
 | |
|         check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|         ret = scanner->get_next_row(prow);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ret = row_generate_.get_next_row(k, check_row);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|       }
 | |
|     } else {
 | |
|       check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ret = row_generate_.get_next_row(p, check_row);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
| 
 | |
|   // first one multi get, others multi scan
 | |
|   ranges.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     mget_start_rows[i].row_val_.assign(mget_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_end_rows[i].row_val_.assign(mget_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_ranges[i].get_start_key().assign(mget_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_end_key().assign(mget_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(i, mget_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(i + (i != 0 ? count_per_range - 1 : 0), mget_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = ranges.push_back(mget_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   destroy_cache();
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     const int64_t p = i;
 | |
|     if (p != 0) {
 | |
|       for (int64_t j = 0; j < count_per_range; ++j) {
 | |
|         const int64_t k = is_reverse_scan ? i + count_per_range - j - 1 : i + j;
 | |
|         check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|         ret = scanner->get_next_row(prow);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ret = row_generate_.get_next_row(k, check_row);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|       }
 | |
|     } else {
 | |
|       check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ret = row_generate_.get_next_row(p, check_row);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
| 
 | |
|   // first one multi scan, others multi get
 | |
|   ranges.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     mget_start_rows[i].row_val_.assign(mget_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_end_rows[i].row_val_.assign(mget_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_ranges[i].get_start_key().assign(mget_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_end_key().assign(mget_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(i, mget_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(i + (i == 0 ? count_per_range - 1 : 0), mget_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = ranges.push_back(mget_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   destroy_cache();
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     const int64_t p = i;
 | |
|     if (p == 0) {
 | |
|       for (int64_t j = 0; j < count_per_range; ++j) {
 | |
|         const int64_t k = is_reverse_scan ? i + count_per_range - j - 1 : i + j;
 | |
|         check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|         ret = scanner->get_next_row(prow);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ret = row_generate_.get_next_row(k, check_row);
 | |
|         ASSERT_EQ(OB_SUCCESS, ret);
 | |
|         ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|       }
 | |
|     } else {
 | |
|       check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ret = row_generate_.get_next_row(p, check_row);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
| 
 | |
|   // multi scan not exist row
 | |
|   STORAGE_LOG(DEBUG, "multi_scan_not_exist_row");
 | |
|   ranges.reuse();
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     mget_start_rows[i].row_val_.assign(mget_start_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_end_rows[i].row_val_.assign(mget_end_cells[i], TEST_COLUMN_CNT);
 | |
|     mget_ranges[i].get_start_key().assign(mget_start_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_end_key().assign(mget_end_cells[i], TEST_ROWKEY_COLUMN_CNT);
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_start();
 | |
|     mget_ranges[i].get_border_flag().set_inclusive_end();
 | |
|     ret = row_generate_.get_next_row(i + (i % 2 ? row_cnt_ : 0), mget_start_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = row_generate_.get_next_row(i + (i % 2 ? row_cnt_ + count_per_range - 1 : 0), mget_end_rows[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     ret = ranges.push_back(mget_ranges[i]);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   }
 | |
|   destroy_cache();
 | |
|   convert_range(ranges, ext_ranges, allocator_);
 | |
|   ret = sstable_.multi_scan(param_, context_, ext_ranges, scanner);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   for (int64_t i = 0; i < TEST_MULTI_GET_CNT; ++i) {
 | |
|     const int64_t p = i;
 | |
|     if (p % 2) {
 | |
|       continue;
 | |
|     } else {
 | |
|       check_row.row_val_.assign(check_cells, TEST_COLUMN_CNT);
 | |
|       ret = scanner->get_next_row(prow);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ret = row_generate_.get_next_row(p, check_row);
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|       ASSERT_TRUE(check_row.row_val_ == prow->row_val_);
 | |
|     }
 | |
|   }
 | |
|   ret = scanner->get_next_row(prow);
 | |
|   ASSERT_EQ(OB_ITER_END, ret);
 | |
|   destroy_query_param();
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_get_with_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = false;
 | |
|   int64_t limit = -1;
 | |
|   for (int64_t i = 2; i < 20; i += 10) {
 | |
|     test_multi_scan_multi_get_with_scan(is_reverse_scan, limit, i);
 | |
|     limit += 2;
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_reverse_multi_get_with_scan)
 | |
| {
 | |
|   const bool is_reverse_scan = true;
 | |
|   int64_t limit = -1;
 | |
|   for (int64_t i = 2; i < 20; i += 10) {
 | |
|     test_multi_scan_multi_get_with_scan(is_reverse_scan, limit, i);
 | |
|     limit += 2;
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_small_io)
 | |
| {
 | |
|   test_multi_block_read_small_io(false, -1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_small_io_reverse_scan)
 | |
| {
 | |
|   test_multi_block_read_small_io(true, -1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_small_io_limit)
 | |
| {
 | |
|   test_multi_block_read_small_io(false, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_small_io_limit_reverse_scan)
 | |
| {
 | |
|   test_multi_block_read_small_io(true, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_continue_io)
 | |
| {
 | |
|   test_multi_block_read_big_continue_io(false, -1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_continue_io_reverse_scan)
 | |
| {
 | |
|   test_multi_block_read_big_continue_io(true, -1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_continue_io_limit)
 | |
| {
 | |
|   test_multi_block_read_big_continue_io(false, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_continue_io_limit_reverse_scan)
 | |
| {
 | |
|   test_multi_block_read_big_continue_io(true, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_discrete_io)
 | |
| {
 | |
|   test_multi_block_read_big_discrete_io(false, -1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_discrete_io_reverse_scan)
 | |
| {
 | |
|   test_multi_block_read_big_discrete_io(true, -1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_discrete_io_limit)
 | |
| {
 | |
|   test_multi_block_read_big_discrete_io(false, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_multi_block_read_big_discrete_io_limit_reverse_scan)
 | |
| {
 | |
|   test_multi_block_read_big_discrete_io(true, 1);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_skip_single_range)
 | |
| {
 | |
|   ObArray<int64_t> start_seeds;
 | |
|   ObArray<SkipInfo> skip_infos;
 | |
|   const int64_t count_per_range = 1000;
 | |
|   int64_t start_seed = 20;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   SkipInfo info;
 | |
|   info.start_key_ = 205;
 | |
|   info.gap_key_ = 400;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   test_skip_range(start_seeds, count_per_range, false, skip_infos);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_skip_single_range_reverse_scan)
 | |
| {
 | |
|   ObArray<int64_t> start_seeds;
 | |
|   ObArray<SkipInfo> skip_infos;
 | |
|   const int64_t count_per_range = 1000;
 | |
|   int64_t start_seed = 20;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   SkipInfo info;
 | |
|   info.gap_key_ = 205;
 | |
|   info.start_key_ = 400;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   test_skip_range(start_seeds, count_per_range, true, skip_infos);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_skip_multiple_range)
 | |
| {
 | |
|   ObArray<int64_t> start_seeds;
 | |
|   ObArray<SkipInfo> skip_infos;
 | |
|   const int64_t count_per_range = 50;
 | |
|   int64_t start_seed = 20;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   start_seed = 40;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   start_seed = 120;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   start_seed = 300;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   SkipInfo info;
 | |
|   info.start_key_ = 25;
 | |
|   info.gap_key_ = 40;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.start_key_ = 53;
 | |
|   info.gap_key_ = 55;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.start_key_ = 57;
 | |
|   info.gap_key_ = 68;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.start_key_ = 72;
 | |
|   info.gap_key_ = 75;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.start_key_ = 140;
 | |
|   info.gap_key_ = 155;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.start_key_ = 159;
 | |
|   info.gap_key_ = 162;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.start_key_ = 301;
 | |
|   info.gap_key_ = 310;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.start_key_ = 319;
 | |
|   info.gap_key_ = 323;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   test_skip_range(start_seeds, count_per_range, false, skip_infos);
 | |
| }
 | |
| 
 | |
| TEST_F(TestSSTableMultiScanner, test_skip_multiple_range_reverse_scan)
 | |
| {
 | |
|   ObArray<int64_t> start_seeds;
 | |
|   ObArray<SkipInfo> skip_infos;
 | |
|   const int64_t count_per_range = 50;
 | |
|   int64_t start_seed = 20;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   start_seed = 40;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   start_seed = 120;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   start_seed = 300;
 | |
|   ASSERT_EQ(OB_SUCCESS, start_seeds.push_back(start_seed));
 | |
|   SkipInfo info;
 | |
|   info.gap_key_ = 25;
 | |
|   info.start_key_ = 40;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.gap_key_ = 53;
 | |
|   info.start_key_ = 55;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.gap_key_ = 57;
 | |
|   info.start_key_ = 68;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.gap_key_ = 72;
 | |
|   info.start_key_ = 75;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.gap_key_ = 140;
 | |
|   info.start_key_ = 155;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.gap_key_ = 159;
 | |
|   info.start_key_ = 162;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.gap_key_ = 301;
 | |
|   info.start_key_ = 310;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   info.gap_key_ = 319;
 | |
|   info.start_key_ = 323;
 | |
|   ASSERT_EQ(OB_SUCCESS, skip_infos.push_back(info));
 | |
|   test_skip_range(start_seeds, count_per_range, true, skip_infos);
 | |
| }
 | |
| 
 | |
| }  // end namespace unittest
 | |
| }  // end namespace oceanbase
 | |
| 
 | |
| int main(int argc, char** argv)
 | |
| {
 | |
|   system("rm -f test_sstable_multi_scan.log*");
 | |
|   OB_LOGGER.set_file_name("test_sstable_multi_scan.log");
 | |
|   OB_LOGGER.set_log_level("INFO");
 | |
|   CLOG_LOG(INFO, "begin unittest: test_sstable_multi_scan");
 | |
|   oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
 | |
|   testing::InitGoogleTest(&argc, argv);
 | |
|   return RUN_ALL_TESTS();
 | |
| }
 | 
