10 #include "./test_key.h"
12 using namespace mabain;
14 static std::atomic<int64_t> key_low;
15 static std::atomic<int64_t> key_high;
16 static int64_t memcap_i = 256*1024*1024;
17 static int64_t memcap_d = 256*1024*1024;
18 static pthread_t wid = 0;
20 static std::string mbdir = "/var/tmp/mabain_test";
21 static bool stop_processing = false;
22 static uint32_t run_time = 3600;
24 static void* run_mb_test(void *arg);
26 static void* Reader(void *arg)
28 DB db(mbdir.c_str(), CONSTS::ReaderOptions(), memcap_i, memcap_d);
30 std::cerr << "failed tp open db\n";
36 TestKey tkey_int(MABAIN_TEST_KEY_TYPE_INT);
37 TestKey tkey_sha1(MABAIN_TEST_KEY_TYPE_SHA_128);
38 TestKey tkey_sha2(MABAIN_TEST_KEY_TYPE_SHA_256);
43 while(!stop_processing) {
46 if(key_high.load(std::memory_order_consume) == key_low.load(std::memory_order_consume))
48 ikey = key_low.load(std::memory_order_consume);
49 ikey += rand() % (key_high.load(std::memory_order_consume) - key_low.load(std::memory_order_consume));
54 keystr = tkey_int.get_key(ikey);
57 keystr = tkey_sha1.get_key(ikey);
60 keystr = tkey_sha2.get_key(ikey);
63 rval = db.Find(keystr, mbd);
65 if(ikey < key_low.load(std::memory_order_consume))
68 if(rval == MBError::SUCCESS) {
69 if(keystr != std::string((char *)mbd.buff, mbd.data_len)) {
70 std::cout << "value not match for key " << ikey << ": " << keystr << "\n";
73 } else if(rval != MBError::NOT_EXIST) {
74 std::cout << "unexpected return from Find: " << rval << "\n";
83 static void Verify(DB &db)
85 int64_t key0 = key_low.load(std::memory_order_consume);
86 int64_t key1 = key_high.load(std::memory_order_consume);
87 TestKey tkey_int(MABAIN_TEST_KEY_TYPE_INT);
88 TestKey tkey_sha1(MABAIN_TEST_KEY_TYPE_SHA_128);
89 TestKey tkey_sha2(MABAIN_TEST_KEY_TYPE_SHA_256);
92 for(int64_t i = key0; i < key1; i++) {
93 keystr = tkey_int.get_key(i);
94 if(db.Find(keystr, mbd) != MBError::SUCCESS) {
95 std::cout << "failed to find key " << i << ": " << keystr << std::endl;
98 assert(keystr == std::string((char *)mbd.buff, mbd.data_len));
100 keystr = tkey_sha1.get_key(i);
101 if(db.Find(keystr, mbd) != MBError::SUCCESS) {
102 std::cout << "failed to find key " << i << ": " << keystr << std::endl;
105 assert(keystr == std::string((char *)mbd.buff, mbd.data_len));
107 keystr = tkey_sha2.get_key(i);
108 if(db.Find(keystr, mbd) != MBError::SUCCESS) {
109 std::cout << "failed to find key " << i << ": " << keystr << std::endl;
112 assert(keystr == std::string((char *)mbd.buff, mbd.data_len));
116 static void* AddThread(void *arg)
118 DB db(mbdir.c_str(), CONSTS::ReaderOptions());
119 int num = rand() % 1500;
122 TestKey tkey_int(MABAIN_TEST_KEY_TYPE_INT);
123 TestKey tkey_sha1(MABAIN_TEST_KEY_TYPE_SHA_128);
124 TestKey tkey_sha2(MABAIN_TEST_KEY_TYPE_SHA_256);
127 for(int i = 0; i < num; i++) {
128 key = key_high.fetch_add(1, std::memory_order_release);
129 keystr = tkey_int.get_key(key);
130 assert(db.Add(keystr, keystr) == MBError::SUCCESS);
132 keystr = tkey_sha1.get_key(key);
133 assert(db.Add(keystr, keystr) == MBError::SUCCESS);
135 keystr = tkey_sha2.get_key(key);
136 assert(db.Add(keystr, keystr) == MBError::SUCCESS);
142 static void Populate(int nt)
146 for(int i = 0; i < nt; i++) {
147 if(pthread_create(&tid[i], NULL, AddThread, NULL) != 0) {
148 std::cout << "failed to create MultiThreadAdd thread\n";
153 for(int i = 0; i < nt; i++) {
154 if(pthread_join(tid[i], NULL) != 0) {
155 std::cout << "failed to join MultiThreadAdd thread\n";
161 static void load_key_ids()
165 std::string path = mbdir + "/key_id";
166 ifs.open (path.c_str(), std::ofstream::in);
177 std::cout << "Loaded " << key_low << " " << key_high << "\n";
180 static void store_key_ids()
182 std::string path = mbdir + "/key_id";
184 fp = fopen(path.c_str(), "w");
186 fprintf(fp, "%d\n%d", (int)key_low.load(std::memory_order_consume),
187 (int)key_high.load(std::memory_order_consume));
191 static void* DeleteThread(void *arg)
193 DB db(mbdir.c_str(), CONSTS::ReaderOptions());
194 int num = rand() % 5;
197 TestKey tkey_int(MABAIN_TEST_KEY_TYPE_INT);
198 TestKey tkey_sha1(MABAIN_TEST_KEY_TYPE_SHA_128);
199 TestKey tkey_sha2(MABAIN_TEST_KEY_TYPE_SHA_256);
202 for(int i = 0; i < num; i++) {
203 key = key_low.fetch_add(1, std::memory_order_release);
205 keystr = tkey_int.get_key(key);
206 assert(db.Remove(keystr) == MBError::SUCCESS);
208 keystr = tkey_sha1.get_key(key);
209 assert(db.Remove(keystr) == MBError::SUCCESS);
211 keystr = tkey_sha2.get_key(key);
212 assert(db.Remove(keystr) == MBError::SUCCESS);
219 static void Prune(int nt)
223 for(int i = 0; i < nt; i++) {
224 if(pthread_create(&tid[i], NULL, DeleteThread, NULL) != 0) {
225 std::cout << "failed to create MultiThreadAdd thread\n";
230 for(int i = 0; i < nt; i++) {
231 if(pthread_join(tid[i], NULL) != 0) {
232 std::cout << "failed to join MultiThreadAdd thread\n";
241 if(pthread_join(wid, NULL) != 0) {
242 std::cout << "cannot join mbtest thread\n";
247 static void CheckCount()
249 DB *db = new DB(mbdir.c_str(), CONSTS::ReaderOptions(), memcap_i, memcap_d);
250 if(db == NULL) return;
253 for(DB::iterator iter = db->begin(false, false); iter != db->end(); ++iter) {
256 std::cout << "Count using iterator: " << count << "\tcount from API: "
257 << db->Count() << "\n";
263 if(pthread_create(&wid, NULL, run_mb_test, NULL) != 0) {
264 std::cout << "failed to create test thread" << std::endl;
268 static void* run_mb_test(void *arg)
270 int64_t run_stop_time = time(NULL) + run_time;
279 memset(&mbconf, 0, sizeof(mbconf));
280 mbconf.mbdir = mbdir.c_str();
281 options = CONSTS::WriterOptions() | CONSTS::ASYNC_WRITER_MODE;
282 mbconf.options = options;
283 mbconf.memcap_index = 128ULL*1024*1024;
284 mbconf.memcap_data = 128ULL*1024*1024;
285 mbconf.block_size_index = 64U*1024*1024;
286 mbconf.block_size_data = 64U*1024*1024;
287 mbconf.max_num_data_block = 3;
288 mbconf.max_num_index_block = 3;
289 mbconf.num_entry_per_bucket = 500;
290 DB *db = new DB(mbconf);
292 std::cerr << "failed to open writer db" << std::endl;
298 for(int i = 0; i < nreaders; i++) {
299 if(pthread_create(&tid, NULL, Reader, NULL) != 0) {
300 std::cout << "failed to create reader thread" << std::endl;
306 int64_t loop_cnt = 0;
307 while(!stop_processing) {
311 std::cout << "LOOP " << loop_cnt << ": " << db->Count() << "\n";
312 if(loop_cnt % 5 == 0) {
313 std::cout << "RUN RC\n";
314 int rval = db->CollectResource(24LL*1024*1024, 24LL*1024*1024, 128LL*1024*1024, 0xFFFFFFFFFFFF);
315 if(rval == MBError::SUCCESS) {
317 if(rcn % 57 == 0 && !(options & CONSTS::ASYNC_WRITER_MODE)) {
318 // Note if in async mode, the DB handle cannot be used for lookup.
319 std::cout << "Verifying after rc" << std::endl;
321 } else if(rcn % 20 == 0) {
324 mbconf.options = options;
331 } else if(rcn % 20000523 == 0) {
332 if(system("reboot") != 0) {
340 if(time(NULL) >= run_stop_time) {
341 stop_processing = true;
353 static void SetTestStatus(bool success)
357 cmd = std::string("touch ") + mbdir + "/_success";
359 cmd = std::string("rm ") + mbdir + "/_success >" + mbdir + "/out 2>" + mbdir + "/err";
361 if(system(cmd.c_str()) != 0) {
365 int main(int argc, char *argv[])
368 mbdir = std::string(argv[1]);
369 std::cout << "Test db directory is " << mbdir << "\n";
372 run_time = atoi(argv[2]);
373 std::cout << "running " << argv[0] << " for " << run_time << " seconds...\n";
376 DB::SetLogFile(mbdir + "/mabain.log");
377 SetTestStatus(false);