1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define private public
18#define protected public
19#include "index/lsn_store.h"
20#undef private
21#undef protected
22
23#include <ailego/parallel/thread_pool.h>
24#include <ailego/utility/time_helper.h>
25#include <gtest/gtest.h>
26
27using namespace proxima::be;
28using namespace proxima::be::index;
29
30
31class LsnStoreTest : public testing::Test {
32 protected:
33 void SetUp() {
34 char cmd_buf[100];
35 snprintf(cmd_buf, 100, "rm -rf ./data.lsn");
36 system(cmd_buf);
37 }
38
39 void TearDown() {}
40};
41
42TEST_F(LsnStoreTest, TestGeneral) {
43 LsnStorePtr lsn_store = LsnStore::Create("teachers", "./");
44 ASSERT_TRUE(lsn_store != nullptr);
45
46 ReadOptions read_options;
47 read_options.use_mmap = true;
48 read_options.create_new = true;
49 int ret = lsn_store->open(read_options);
50 ASSERT_EQ(ret, 0);
51
52 for (size_t i = 0; i < 40000; i++) {
53 std::string lsn_context = "JDBC://hello";
54 ret = lsn_store->append(i, lsn_context + std::to_string(i));
55 ASSERT_EQ(ret, 0);
56 }
57
58 ASSERT_EQ(lsn_store->header_.tail_block_index, 1);
59 ASSERT_GT(lsn_store->data_blocks_[0]->data_size(), 0);
60 LOG_INFO("data_size: %lu", lsn_store->data_blocks_[0]->data_size());
61 ASSERT_GT(lsn_store->data_blocks_[1]->data_size(), 0);
62 ASSERT_EQ(lsn_store->data_blocks_[2]->data_size(), 0);
63
64 for (size_t i = 30000; i < 70000; i++) {
65 std::string lsn_context = "JDBC://hello";
66 ret = lsn_store->append(i, lsn_context + std::to_string(i));
67 ASSERT_EQ(ret, 0);
68 }
69
70 ASSERT_EQ(lsn_store->header_.tail_block_index, 0);
71 ASSERT_GT(lsn_store->data_blocks_[1]->data_size(), 0);
72 LOG_INFO("data_size: %lu", lsn_store->data_blocks_[0]->data_size());
73 ASSERT_EQ(lsn_store->data_blocks_[2]->data_size(), 0);
74
75 ret = lsn_store->shift();
76 ASSERT_EQ(ret, 0);
77 ASSERT_EQ(lsn_store->data_blocks_[2]->data_size(),
78 lsn_store->data_blocks_[0]->data_size());
79
80 for (size_t i = 70000; i < 71000; i++) {
81 std::string lsn_context = "JDBC://hello";
82 ret = lsn_store->append(i, lsn_context + std::to_string(i));
83 ASSERT_EQ(ret, 0);
84
85 ailego::ElapsedTime timer;
86 uint64_t lsn;
87 std::string lsn_context_val;
88 ret = lsn_store->get_latest_lsn(&lsn, &lsn_context_val);
89 ASSERT_EQ(ret, 0);
90 ASSERT_EQ(lsn, i);
91 ASSERT_EQ(lsn_context_val, lsn_context + std::to_string(i));
92 }
93
94 ret = lsn_store->close();
95 ASSERT_EQ(ret, 0);
96
97 read_options.use_mmap = true;
98 read_options.create_new = false;
99 ret = lsn_store->open(read_options);
100 ASSERT_EQ(ret, 0);
101
102 uint64_t lsn;
103 std::string lsn_context_val;
104 lsn_store->get_latest_lsn(&lsn, &lsn_context_val);
105 ASSERT_EQ(lsn, 70999);
106 ASSERT_EQ(lsn_context_val,
107 std::string("JDBC://hello") + std::to_string(70999));
108}
109
110void do_insert(LsnStore *lsn_store, size_t number) {
111 std::string lsn_context = "JDBC://hello";
112 int ret = lsn_store->append(number, lsn_context + std::to_string(number));
113 ASSERT_EQ(ret, 0);
114}
115
116TEST_F(LsnStoreTest, TestMultiThread) {
117 LsnStorePtr lsn_store = LsnStore::Create("teachers", "./");
118 ASSERT_TRUE(lsn_store != nullptr);
119
120 ReadOptions read_options;
121 read_options.use_mmap = true;
122 read_options.create_new = true;
123 int ret = lsn_store->open(read_options);
124 ASSERT_EQ(ret, 0);
125
126 ailego::ThreadPool pool(10, false);
127 for (size_t i = 0; i < 10000; i++) {
128 pool.execute(do_insert, lsn_store.get(), i);
129 }
130 pool.wait_finish();
131
132 LOG_INFO("data_size0: %lu", lsn_store->data_blocks_[0]->data_size());
133 LOG_INFO("data_size1: %lu", lsn_store->data_blocks_[1]->data_size());
134 LOG_INFO("data_size2: %lu", lsn_store->data_blocks_[2]->data_size());
135
136 uint64_t lsn;
137 std::string lsn_context_val;
138 ret = lsn_store->get_latest_lsn(&lsn, &lsn_context_val);
139 ASSERT_EQ(ret, 0);
140 ASSERT_GE(lsn, 9999);
141 ASSERT_EQ(lsn_context_val,
142 std::string("JDBC://hello") + std::to_string(9999));
143}
144