inital commit
[c11concurrency-benchmarks.git] / mabain / src / unittest / resource_collection_test.cpp
1 /**
2  * Copyright (C) 2017 Cisco Inc.
3  *
4  * This program is free software: you can redistribute it and/or  modify
5  * it under the terms of the GNU General Public License, version 2,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 // @author Changxue Deng <chadeng@cisco.com>
18
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <iostream>
22 #include <openssl/sha.h>
23 #include <sys/time.h>
24
25 #include <gtest/gtest.h>
26
27 #define TEST_MBSHRINK_FRIENDS \
28     friend class MBShrinkTest;
29
30 #include "../db.h"
31 #include "../mabain_consts.h"
32 #include "../mb_rc.h"
33 #include "../error.h"
34 #include "./test_key.h"
35 #include "../resource_pool.h"
36
37 #define DB_DIR "/var/tmp/mabain_test/"
38 #define KEY_TYPE_INT    0
39 #define KEY_TYPE_SHA256 1
40
41 using namespace mabain;
42
43 namespace {
44
45 class ResourceCollectionTest : public ::testing::Test
46 {
47 public:
48     ResourceCollectionTest() : db(NULL) {
49         key_type = MABAIN_TEST_KEY_TYPE_INT;
50         srand(time(NULL));
51     }
52     virtual ~ResourceCollectionTest() {
53         if(db != NULL) delete db;
54     }
55     virtual void SetUp() {
56         std::string cmd = std::string("mkdir -p ") + DB_DIR;
57         if(system(cmd.c_str()) != 0) {
58         }
59         cmd = std::string("rm ") + DB_DIR + "_*";
60         if(system(cmd.c_str()) != 0) {
61         }
62         db = new DB(DB_DIR, CONSTS::ACCESS_MODE_WRITER, 128ULL*1024*1024, 128ULL*1024*1024);
63         if(!db->is_open()) {
64             std::cerr << "failed to open mabain db: " << db->StatusStr() << "\n";
65             abort();
66         }
67     }
68     virtual void TearDown() {
69         db->Close();
70         ResourcePool::getInstance().RemoveAll();
71     }
72
73     void Populate(long num, bool *exist) {
74         TestKey tkey = TestKey(key_type);
75         for(long i = 0; i < num; i++) {
76             std::string key = tkey.get_key(i);
77             std::string value = key;
78             int rval = db->Add(key.c_str(), key.length(), value.c_str(), value.length());
79             assert(rval == MBError::SUCCESS);
80             exist[i] = true;
81         }
82     }
83
84     void DeleteRandom(long num, bool *exist) {
85         long count = 0;
86         int64_t tot_count = db->Count();
87         TestKey tkey = TestKey(key_type);
88         while(true) {
89             long ikey = rand() % tot_count;
90             std::string key = tkey.get_key(ikey);
91             int rval = db->Remove(key.c_str(), key.length());
92             if(rval == MBError::SUCCESS) {
93                 exist[ikey] = false;
94                 count++;
95                 if(count >= num) break;
96             }
97         }
98     }
99
100     void DeleteOdd(long num,  bool *exist) {
101         TestKey tkey = TestKey(key_type);
102         for(long i = 0; i < num; i++) {
103             if(i % 2 == 0) continue;
104             std::string key = tkey.get_key(i);
105             std::string value = key;
106             db->Remove(key.c_str(), key.length());
107             exist[i] = false;
108         }
109     }
110
111     void DeleteRange(long start, long end, bool *exist) {
112         TestKey tkey = TestKey(key_type);
113         for(long i = start; i < end; i++) {
114             std::string key = tkey.get_key(i);
115             std::string value = key;
116             db->Remove(key.c_str(), key.length());
117             exist[i] = false;
118        }
119    }
120
121    void VerifyKeyValue(long ikey, bool found) {
122        TestKey tkey = TestKey(key_type);
123        std::string key = tkey.get_key(ikey);
124        std::string value = key;
125        MBData mbd;
126        int rval = db->Find(key.c_str(), key.length(), mbd);
127        if(found) {
128            EXPECT_EQ(rval, MBError::SUCCESS);
129            EXPECT_TRUE(value == std::string(reinterpret_cast<char*>(mbd.buff), mbd.data_len));
130        } else {
131            EXPECT_EQ(rval, MBError::NOT_EXIST);
132        }
133    }
134
135 protected:
136     DB *db;
137     int key_type;
138 };
139
140 TEST_F(ResourceCollectionTest, RC_reorder_index_test)
141 {
142     key_type = KEY_TYPE_INT;
143     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_INDEX);
144
145     long tot = 53245;
146     bool *exist = new bool[tot];
147     Populate(tot, exist);
148     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
149     for(long i = 0; i < tot; i++) {
150         VerifyKeyValue(i, exist[i]);
151     }
152
153     delete [] exist;
154 }
155
156 TEST_F(ResourceCollectionTest, RC_reorder_data_test)
157 {
158     key_type = MABAIN_TEST_KEY_TYPE_SHA_128;
159     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_DATA);
160
161     long tot = 35275;
162     bool *exist = new bool[tot];
163     Populate(tot, exist);
164     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
165     for(long i = 0; i < tot; i++) {
166         VerifyKeyValue(i, exist[i]);
167     }
168
169     delete [] exist;
170 }
171
172 TEST_F(ResourceCollectionTest, RC_reorder_index_data_test)
173 {
174     key_type = MABAIN_TEST_KEY_TYPE_SHA_256;
175     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_INDEX |
176                                RESOURCE_COLLECTION_TYPE_DATA);
177
178     long tot = 35275;
179     bool *exist = new bool[tot];
180     Populate(tot, exist);
181     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
182     for(long i = 0; i < tot; i++) {
183         VerifyKeyValue(i, exist[i]);
184     }
185
186     delete [] exist;
187 }
188
189 TEST_F(ResourceCollectionTest, RC_delete_odd_collect_index_test)
190 {
191     key_type = MABAIN_TEST_KEY_TYPE_INT;
192     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_INDEX);
193
194     long tot = 128471;
195     bool *exist = new bool[tot];
196     Populate(tot, exist);
197     DeleteOdd(tot, exist);
198     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
199     for(long i = 0; i < tot; i++) {
200         VerifyKeyValue(i, exist[i]);
201     }
202
203     delete [] exist;
204 }
205
206 TEST_F(ResourceCollectionTest, RC_delete_random_collect_data_test)
207 {
208     key_type = MABAIN_TEST_KEY_TYPE_SHA_128;
209     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_DATA);
210
211     long tot = 34521;
212     bool *exist = new bool[tot];
213     Populate(tot, exist);
214     DeleteRandom(tot, exist);
215     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
216     for(long i = 0; i < tot; i++) {
217         VerifyKeyValue(i, exist[i]);
218     }
219
220     delete [] exist;
221 }
222
223 TEST_F(ResourceCollectionTest, RC_delete_random_collect_index_data_test)
224 {
225     key_type = MABAIN_TEST_KEY_TYPE_SHA_256;
226     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_INDEX |
227                                RESOURCE_COLLECTION_TYPE_DATA);
228
229     long tot = 34521;
230     bool *exist = new bool[tot];
231     Populate(tot, exist);
232     DeleteRandom(tot, exist);
233     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
234     for(long i = 0; i < tot; i++) {
235         VerifyKeyValue(i, exist[i]);
236     }
237
238     delete [] exist;
239 }
240
241 TEST_F(ResourceCollectionTest, RC_delete_range_collect_index_data_test)
242 {
243     key_type = MABAIN_TEST_KEY_TYPE_SHA_256;
244     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_INDEX |
245                                RESOURCE_COLLECTION_TYPE_DATA);
246
247     long tot = 34521;
248     bool *exist = new bool[tot];
249     Populate(tot, exist);
250     DeleteRange(0, 23, exist);
251     DeleteRange(1110, 1118, exist);
252     DeleteRange(29110, 29301, exist);
253     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
254     for(long i = 0; i < tot; i++) {
255         VerifyKeyValue(i, exist[i]);
256     }
257
258     delete [] exist;
259 }
260
261 TEST_F(ResourceCollectionTest, RC_delete_random_collect_index_data_add_test)
262 {
263     key_type = MABAIN_TEST_KEY_TYPE_SHA_128;
264     ResourceCollection rc(*db, RESOURCE_COLLECTION_TYPE_INDEX |
265                                RESOURCE_COLLECTION_TYPE_DATA);
266
267     long tot = 55569;
268     bool *exist = new bool[tot];
269     Populate(tot, exist);
270     DeleteRandom(tot, exist);
271     rc.ReclaimResource(0, 0, 10000000000LL, 10000000000LL);
272     for(long i = 0; i < tot; i++) {
273         VerifyKeyValue(i, exist[i]);
274     }
275
276     db->Close();
277     delete db;
278
279     db = new DB(DB_DIR, CONSTS::ACCESS_MODE_WRITER, 128ULL*1024*1024, 128ULL*1024*1024);
280     if(!db->is_open()) {
281         std::cerr << "failed top open db\n";
282         exit(0);
283     }
284
285     for(long i = 0; i < tot; i++) {
286         VerifyKeyValue(i, exist[i]);
287     }
288
289     key_type = MABAIN_TEST_KEY_TYPE_INT;
290     tot = 12343;
291     Populate(tot, exist); 
292     for(long i = 0; i < tot; i++) {
293         VerifyKeyValue(i, exist[i]);
294     }
295
296     delete [] exist;
297 }
298
299 }