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#include "index/version_manager.h"
18#include <gtest/gtest.h>
19
20using namespace proxima::be;
21using namespace proxima::be::index;
22
23
24class VersionManagerTest : public testing::Test {
25 protected:
26 void SetUp() {
27 char cmd_buf[100];
28 snprintf(cmd_buf, 100, "rm -rf ./data.manifest");
29 system(cmd_buf);
30 }
31
32 void TearDown() {}
33};
34
35TEST_F(VersionManagerTest, TestGeneral) {
36 auto version_manager = VersionManager::Create("collection_test", "./");
37 ASSERT_NE(version_manager, nullptr);
38
39 ReadOptions read_options;
40 read_options.use_mmap = true;
41 read_options.create_new = true;
42 int ret = version_manager->open(read_options);
43 ASSERT_EQ(ret, 0);
44
45 ASSERT_EQ(version_manager->total_segment_count(), 1);
46
47 for (size_t i = 1; i < 100; i++) {
48 SegmentMeta segment_meta;
49 int ret = version_manager->alloc_segment_meta(&segment_meta);
50 ASSERT_EQ(ret, 0);
51 segment_meta.state = SegmentState::WRITING;
52 ret = version_manager->update_segment_meta(segment_meta);
53 ASSERT_EQ(ret, 0);
54 ASSERT_EQ(segment_meta.segment_id, i);
55 ASSERT_EQ(version_manager->total_segment_count(), i + 1);
56 }
57
58 for (size_t i = 0; i < 100; i++) {
59 VersionEdit edit;
60 edit.add_segments.emplace_back(i);
61 ret = version_manager->apply(edit);
62 ASSERT_EQ(ret, 0);
63 ASSERT_EQ(version_manager->current_version().size(), i + 1);
64 }
65
66 for (size_t i = 0; i < 100; i++) {
67 SegmentMeta segment_meta;
68 segment_meta.segment_id = i;
69 segment_meta.state = SegmentState::WRITING;
70 segment_meta.doc_count = i;
71 segment_meta.min_primary_key = i;
72 segment_meta.max_primary_key = i;
73 segment_meta.min_doc_id = i;
74 segment_meta.max_doc_id = i;
75 segment_meta.min_timestamp = i;
76 segment_meta.max_timestamp = i;
77
78 ret = version_manager->update_segment_meta(segment_meta);
79 ASSERT_EQ(ret, 0);
80 }
81
82 for (size_t i = 0; i < 100; i++) {
83 SegmentMeta segment_meta;
84 int ret = version_manager->get_segment_meta(i, &segment_meta);
85 ASSERT_EQ(ret, 0);
86 ASSERT_EQ(segment_meta.segment_id, i);
87 ASSERT_EQ(segment_meta.state, SegmentState::WRITING);
88 ASSERT_EQ(segment_meta.doc_count, i);
89 ASSERT_EQ(segment_meta.min_primary_key, i);
90 ASSERT_EQ(segment_meta.max_primary_key, i);
91 ASSERT_EQ(segment_meta.min_doc_id, i);
92 ASSERT_EQ(segment_meta.max_doc_id, i);
93 ASSERT_EQ(segment_meta.min_timestamp, i);
94 ASSERT_EQ(segment_meta.max_timestamp, i);
95 }
96 version_manager->close();
97
98 read_options.create_new = false;
99 ret = version_manager->open(read_options);
100 ASSERT_EQ(ret, 0);
101 for (size_t i = 0; i < 100; i++) {
102 SegmentMeta segment_meta;
103 int ret = version_manager->get_segment_meta(i, &segment_meta);
104 ASSERT_EQ(ret, 0);
105 ASSERT_EQ(segment_meta.segment_id, i);
106 ASSERT_EQ(segment_meta.state, SegmentState::WRITING);
107 ASSERT_EQ(segment_meta.doc_count, i);
108 ASSERT_EQ(segment_meta.min_doc_id, i);
109 ASSERT_EQ(segment_meta.max_doc_id, i);
110 ASSERT_EQ(segment_meta.min_primary_key, i);
111 ASSERT_EQ(segment_meta.max_primary_key, i);
112 ASSERT_EQ(segment_meta.min_timestamp, i);
113 ASSERT_EQ(segment_meta.max_timestamp, i);
114 }
115
116 ASSERT_EQ(version_manager->current_version().size(), 100);
117 for (size_t i = 0; i < 100; i++) {
118 const SegmentMeta &segment_meta = version_manager->current_version()[i];
119 ASSERT_EQ(segment_meta.segment_id, i);
120 ASSERT_EQ(segment_meta.doc_count, i);
121 ASSERT_EQ(segment_meta.min_primary_key, i);
122 ASSERT_EQ(segment_meta.max_primary_key, i);
123 ASSERT_EQ(segment_meta.min_doc_id, i);
124 ASSERT_EQ(segment_meta.max_doc_id, i);
125 ASSERT_EQ(segment_meta.min_timestamp, i);
126 ASSERT_EQ(segment_meta.max_timestamp, i);
127 }
128
129 // test alloc unused segment meta
130 // check if it will be reused
131 for (size_t i = 0; i < 100; i++) {
132 SegmentMeta segment_meta;
133 int ret = version_manager->alloc_segment_meta(&segment_meta);
134 ASSERT_EQ(ret, 0);
135 ASSERT_EQ(segment_meta.segment_id, 100);
136 }
137}
138
139TEST_F(VersionManagerTest, TestVersionEdit) {
140 auto version_manager = VersionManager::Create("collection_test", "./");
141 ASSERT_NE(version_manager, nullptr);
142
143 ReadOptions read_options;
144 read_options.use_mmap = true;
145 read_options.create_new = true;
146 int ret = version_manager->open(read_options);
147 ASSERT_EQ(ret, 0);
148
149 for (size_t i = 0; i < 100; i++) {
150 SegmentMeta segment_meta;
151 ret = version_manager->alloc_segment_meta(&segment_meta);
152 ASSERT_EQ(ret, 0);
153 segment_meta.state = SegmentState::WRITING;
154 ret = version_manager->update_segment_meta(segment_meta);
155 ASSERT_EQ(ret, 0);
156 ASSERT_EQ(segment_meta.segment_id, i + 1);
157 }
158
159 VersionEdit edit1;
160 edit1.add_segments.emplace_back(10);
161 edit1.add_segments.emplace_back(11);
162
163 ret = version_manager->apply(edit1);
164 ASSERT_EQ(ret, 0);
165 ASSERT_EQ(version_manager->current_version().size(), 2);
166 ASSERT_EQ(version_manager->current_version()[0].segment_id, 10);
167 ASSERT_EQ(version_manager->current_version()[1].segment_id, 11);
168
169 VersionEdit edit2;
170 edit2.add_segments.emplace_back(12);
171 edit2.add_segments.emplace_back(13);
172 edit2.delete_segments.emplace_back(10);
173 ret = version_manager->apply(edit2);
174 ASSERT_EQ(ret, 0);
175 ASSERT_EQ(version_manager->current_version().size(), 3);
176 ASSERT_EQ(version_manager->current_version()[0].segment_id, 11);
177 ASSERT_EQ(version_manager->current_version()[1].segment_id, 12);
178 ASSERT_EQ(version_manager->current_version()[2].segment_id, 13);
179}
180