inital commit
[c11concurrency-benchmarks.git] / mabain / src / unittest / dict_mem_test.cpp
1 /**
2  * Copyright (C) 2018 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 <string>
20
21 #include <gtest/gtest.h>
22
23 #include "../dict_mem.h"
24 #include "../drm_base.h"
25 #include "../integer_4b_5b.h"
26 #include "../resource_pool.h"
27
28 using namespace mabain;
29
30 namespace {
31
32 #define DICT_MEM_TEST_DIR "/var/tmp/mabain_test/"
33
34 class DictMemTest : public ::testing::Test
35 {
36 public:
37     DictMemTest() {
38         dmm = NULL;
39         header = NULL;
40         memset(&lfree, 0, sizeof(lfree));
41     }
42     virtual ~DictMemTest() {
43         DestroyDMM();
44     }
45
46     virtual void SetUp() {
47         std::string cmd = std::string("mkdir -p ") + DICT_MEM_TEST_DIR;
48         if(system(cmd.c_str()) != 0) {
49         }
50     }
51     virtual void TearDown() {
52         std::string cmd = std::string("rm -rf ") + DICT_MEM_TEST_DIR + "/_*";
53         if(system(cmd.c_str()) != 0) {
54         }
55         ResourcePool::getInstance().RemoveAll();
56     }
57
58     void Init() {
59         dmm = new DictMem(std::string(DICT_MEM_TEST_DIR), true, 8*1024*1024,
60                       CONSTS::ACCESS_MODE_WRITER | CONSTS::USE_SLIDING_WINDOW,
61                       8*1024*1024, 1, 0);
62         dmm->InitRootNode();
63         EXPECT_EQ(dmm->IsValid(), true);
64         header = dmm->GetHeaderPtr();
65         EXPECT_EQ(header != NULL, true);
66         lfree.LockFreeInit(&header->lock_free, header, CONSTS::ACCESS_MODE_WRITER);
67         dmm->InitLockFreePtr(&lfree);
68     }
69
70     void DestroyDMM() {
71         if(dmm != NULL) {
72             dmm->Destroy();
73             delete dmm;
74             dmm = NULL;
75         }
76     }
77
78 protected:
79     DictMem *dmm;
80     IndexHeader *header;
81     LockFree lfree;
82 };
83
84 TEST_F(DictMemTest, Constructor_test)
85 {
86     dmm = new DictMem(std::string(DICT_MEM_TEST_DIR), true, 8*1024*1024,
87                       CONSTS::ACCESS_MODE_WRITER, 8*1024*1024, 1, 0);
88     dmm->PrintStats(std::cout);
89     EXPECT_EQ(dmm->IsValid(), false);
90     dmm->InitRootNode();
91     EXPECT_EQ(dmm->IsValid(), true);
92     dmm->PrintStats(std::cout);
93     DestroyDMM();
94
95     dmm = new DictMem(std::string(DICT_MEM_TEST_DIR), false, 8*1024*1024,
96                       CONSTS::ACCESS_MODE_WRITER, 8*1024*1024, 1, 0);
97     EXPECT_EQ(dmm->IsValid(), true);
98     DestroyDMM();
99
100     dmm = new DictMem(std::string(DICT_MEM_TEST_DIR), false, 8*1024*1024,
101                       CONSTS::ACCESS_MODE_READER, 8*1024*1024, 1, 0);
102     EXPECT_EQ(dmm->IsValid(), false);
103
104     DestroyDMM();
105
106     int error = 0;
107     try {
108         dmm = new DictMem(std::string(DICT_MEM_TEST_DIR), false, 8*1024*1024,
109                           CONSTS::ACCESS_MODE_WRITER, 12*1024*1024, 1, 0);
110     } catch (int err) {
111         error = err;
112     }
113     EXPECT_EQ(error, MBError::INVALID_SIZE);
114     EXPECT_EQ(dmm==NULL, true);
115 }
116
117 TEST_F(DictMemTest, AddRootEdge_test)
118 {
119     Init();
120
121     EdgePtrs edge_ptrs;
122     size_t offset;
123     uint8_t *shm_ptr;
124
125     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
126     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
127     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "mabain-test", 11, 1234);
128     EXPECT_EQ(edge_ptrs.flag_ptr[0], EDGE_FLAG_DATA_OFF);
129     offset = Get5BInteger(edge_ptrs.ptr);
130     shm_ptr = dmm->GetShmPtr(offset, 10);
131     EXPECT_EQ(shm_ptr != NULL, true);
132     if(memcmp(shm_ptr, "abain-test", 10)) {
133         EXPECT_EQ(1, 2);
134     }
135     offset = Get6BInteger(edge_ptrs.offset_ptr);
136     EXPECT_EQ(offset, 1234u);
137     shm_ptr = dmm->GetShmPtr(header->excep_lf_offset, EDGE_SIZE);
138     EXPECT_EQ(shm_ptr != NULL, true);
139     if(memcmp(shm_ptr, edge_ptrs.ptr, EDGE_SIZE)) {
140         EXPECT_EQ(1, 2);
141     }
142     EXPECT_EQ(header->excep_updating_status, EXCEP_STATUS_NONE);
143
144     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
145     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'x', edge_ptrs), MBError::SUCCESS);
146     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "xyz", 3, 2234);
147     EXPECT_EQ(edge_ptrs.flag_ptr[0], EDGE_FLAG_DATA_OFF);
148     offset = Get6BInteger(edge_ptrs.offset_ptr);
149     EXPECT_EQ(offset, 2234u);
150     shm_ptr = dmm->GetShmPtr(header->excep_lf_offset, EDGE_SIZE);
151     EXPECT_EQ(shm_ptr != NULL, true);
152     if(memcmp(shm_ptr, edge_ptrs.ptr, EDGE_SIZE)) {
153         EXPECT_EQ(1, 2);
154     }
155     EXPECT_EQ(header->excep_updating_status, EXCEP_STATUS_NONE);
156 }
157
158 TEST_F(DictMemTest, InsertNode_test)
159 {
160     Init();
161
162     EdgePtrs edge_ptrs;
163     size_t offset;
164     uint8_t *shm_ptr;
165     MBData mbd;
166     int rval;
167
168     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
169     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
170     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "mabain-test", 11, 1234);
171
172     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
173     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
174     EXPECT_EQ(edge_ptrs.len_ptr[0] >= 6, true);
175     rval = dmm->InsertNode(edge_ptrs, 6, 1334, mbd);
176     EXPECT_EQ(rval, MBError::SUCCESS);
177     EXPECT_EQ(header->excep_updating_status, EXCEP_STATUS_NONE);
178     offset = Get6BInteger(edge_ptrs.offset_ptr);
179     shm_ptr = dmm->GetShmPtr(offset, dmm->GetNodeSizePtr()[0]);
180     EXPECT_EQ(shm_ptr != NULL, true);
181     EXPECT_EQ(shm_ptr[0], FLAG_NODE_NONE | FLAG_NODE_MATCH);
182     EXPECT_EQ(shm_ptr[1], 0);
183     EXPECT_EQ(shm_ptr[8], (uint8_t)'-');
184     EXPECT_EQ(Get6BInteger(shm_ptr+2), 1334u);
185     shm_ptr = dmm->GetShmPtr(header->excep_lf_offset, EDGE_SIZE);
186     EXPECT_EQ(shm_ptr != NULL, true);
187     if(memcmp(shm_ptr, edge_ptrs.ptr, EDGE_SIZE)) {
188         EXPECT_EQ(1, 2);
189     }
190     EXPECT_EQ(edge_ptrs.len_ptr[0], 6);
191     EXPECT_EQ(edge_ptrs.flag_ptr[0], 0);
192     if(memcmp(edge_ptrs.ptr, "abain", 5)) {
193         EXPECT_EQ(1, 2);
194     }
195 }
196
197 TEST_F(DictMemTest, InsertNode_test1)
198 {
199     Init();
200
201     EdgePtrs edge_ptrs;
202     size_t offset;
203     uint8_t *shm_ptr;
204     MBData mbd;
205     int rval;
206
207     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
208     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
209     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "mabain-testabcdefghijk", 22, 1234);
210
211     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
212     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
213     EXPECT_EQ(edge_ptrs.len_ptr[0] >= 6, true);
214     rval = dmm->InsertNode(edge_ptrs, 6, 1334, mbd);
215     EXPECT_EQ(rval, MBError::SUCCESS);
216     EXPECT_EQ(header->excep_updating_status, EXCEP_STATUS_NONE);
217     offset = Get6BInteger(edge_ptrs.offset_ptr);
218     shm_ptr = dmm->GetShmPtr(offset, dmm->GetNodeSizePtr()[0]);
219     EXPECT_EQ(shm_ptr != NULL, true);
220     EXPECT_EQ(shm_ptr[0], FLAG_NODE_NONE | FLAG_NODE_MATCH);
221     EXPECT_EQ(shm_ptr[1], 0);
222     EXPECT_EQ(shm_ptr[8], (uint8_t)'-');
223     EXPECT_EQ(Get6BInteger(shm_ptr+2), 1334u);
224     shm_ptr = dmm->GetShmPtr(header->excep_lf_offset, EDGE_SIZE);
225     EXPECT_EQ(shm_ptr != NULL, true);
226     if(memcmp(shm_ptr, edge_ptrs.ptr, EDGE_SIZE)) {
227         EXPECT_EQ(1, 2);
228     }
229     EXPECT_EQ(edge_ptrs.len_ptr[0], 6);
230     EXPECT_EQ(edge_ptrs.flag_ptr[0], 0);
231     if(memcmp(edge_ptrs.ptr, "abain", 5)) {
232         EXPECT_EQ(1, 2);
233     }
234 }
235
236 TEST_F(DictMemTest, InsertNode_test2)
237 {
238     Init();
239
240     EdgePtrs edge_ptrs;
241     size_t offset;
242     uint8_t *shm_ptr;
243     MBData mbd;
244     int rval;
245
246     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
247     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'x', edge_ptrs), MBError::SUCCESS);
248     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "xxxxxxxmabain-test", 18, 1234);
249
250     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
251     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'x', edge_ptrs), MBError::SUCCESS);
252     EXPECT_EQ(edge_ptrs.len_ptr[0] >= 6, true);
253     rval = dmm->InsertNode(edge_ptrs, 13, 1334, mbd);
254     EXPECT_EQ(rval, MBError::SUCCESS);
255     EXPECT_EQ(header->excep_updating_status, EXCEP_STATUS_NONE);
256     offset = Get6BInteger(edge_ptrs.offset_ptr);
257     shm_ptr = dmm->GetShmPtr(offset, dmm->GetNodeSizePtr()[0]);
258     EXPECT_EQ(shm_ptr != NULL, true);
259     EXPECT_EQ(shm_ptr[0], FLAG_NODE_NONE | FLAG_NODE_MATCH);
260     EXPECT_EQ(shm_ptr[1], 0);
261     EXPECT_EQ(shm_ptr[8], (uint8_t)'-');
262     EXPECT_EQ(Get6BInteger(shm_ptr+2), 1334u);
263     shm_ptr = dmm->GetShmPtr(header->excep_lf_offset, EDGE_SIZE);
264     EXPECT_EQ(shm_ptr != NULL, true);
265     if(memcmp(shm_ptr, edge_ptrs.ptr, EDGE_SIZE)) {
266         EXPECT_EQ(1, 2);
267     }
268     EXPECT_EQ(edge_ptrs.len_ptr[0], 13);
269     EXPECT_EQ(edge_ptrs.flag_ptr[0], 0);
270     EXPECT_EQ(Get5BInteger(edge_ptrs.ptr), 3631u);
271 }
272
273 TEST_F(DictMemTest, AddLink_test)
274 {
275     Init();
276     EdgePtrs edge_ptrs;
277     uint8_t *shm_ptr;
278     MBData mbd;
279     int rval;
280
281     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
282     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
283     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "mabain-test", 18, 1234);
284
285     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
286     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
287     rval = dmm->AddLink(edge_ptrs, 7, (const uint8_t *)"klsakkslslsldds",
288                         15, 12345, mbd);
289     EXPECT_EQ(rval, MBError::SUCCESS);
290     EXPECT_EQ(edge_ptrs.offset, 1681u);
291     EXPECT_EQ(header->excep_updating_status, EXCEP_STATUS_NONE);
292     EXPECT_EQ(Get6BInteger(edge_ptrs.offset_ptr), 3609u);
293     shm_ptr = dmm->GetShmPtr(3609, 10);
294     EXPECT_EQ((int)shm_ptr[0], 0);
295     EXPECT_EQ((int)shm_ptr[1], 1);
296     EXPECT_EQ((char)shm_ptr[8], 't');
297     EXPECT_EQ((char)shm_ptr[9], 'k');
298     EXPECT_EQ(Get5BInteger(edge_ptrs.ptr), 3655u);
299     shm_ptr = dmm->GetShmPtr(3655, 10);
300     EXPECT_EQ(std::string((const char *)shm_ptr, 5).compare("abain"), 0);
301 }
302
303 TEST_F(DictMemTest, UpdateNode_test)
304 {
305     Init();
306     EdgePtrs edge_ptrs;
307     uint8_t *shm_ptr;
308     MBData mbd;
309     int rval;
310
311     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
312     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
313     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "mabain-test", 18, 1234);
314
315     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
316     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
317     rval = dmm->AddLink(edge_ptrs, 7, (const uint8_t *)"klsakkslslsldds",
318                         15, 12345, mbd);
319     EXPECT_EQ(rval, MBError::SUCCESS);
320
321     uint8_t tmp_buff[256];
322     int match_len = 7;
323     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
324     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
325     bool next = dmm->FindNext((const uint8_t*)"abcdefg", 7, match_len, edge_ptrs, tmp_buff);
326     EXPECT_EQ(next, false);
327     rval = dmm->UpdateNode(edge_ptrs, (const uint8_t*)"abcdefg", 7, 12345);
328     EXPECT_EQ(rval, MBError::SUCCESS);
329     EXPECT_EQ(edge_ptrs.offset, 1681u);
330     EXPECT_EQ(Get5BInteger(edge_ptrs.ptr), 3655u);
331     shm_ptr = dmm->GetShmPtr(3655, 6);
332     EXPECT_EQ(std::string((const char*)shm_ptr, 6).compare("abain-"), 0);
333 }
334
335 TEST_F(DictMemTest, FindNext_test)
336 {
337     Init();
338     EdgePtrs edge_ptrs;
339     MBData mbd;
340     int rval;
341
342     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
343     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
344     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "mabain-abc", 18, 1234);
345
346     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
347     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
348     rval = dmm->AddLink(edge_ptrs, 7, (const uint8_t *)"hijk", 4, 12345, mbd);
349     EXPECT_EQ(rval, MBError::SUCCESS);
350
351     bool next;
352     uint8_t key[256];
353     uint8_t tmp_buff[256];
354     int match_len = 7;
355
356     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
357     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
358     next = dmm->FindNext((const uint8_t*)"xyz293ksk", 9, match_len,
359                               edge_ptrs, tmp_buff);
360     EXPECT_EQ(next, false);
361     rval = dmm->UpdateNode(edge_ptrs, (const uint8_t*)"xyz293ksk", 9, 22345);
362     EXPECT_EQ(rval, MBError::SUCCESS);
363
364     for(int i = 0; i < 256; i++) {
365         key[i] = (uint8_t) i;
366     }
367     for(int i = 0; i < 256; i++) {
368         memset(&edge_ptrs, 0, sizeof(edge_ptrs));
369         EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
370         next = dmm->FindNext((const uint8_t*)key+i, 1, match_len,
371                              edge_ptrs, tmp_buff);
372         if((char)key[i] == 'a' || (char)key[i] == 'h' || (char) key[i] == 'x') {
373             EXPECT_EQ(next, true);
374         } else {
375             EXPECT_EQ(next, false);
376         }
377     }
378 }
379
380 TEST_F(DictMemTest, GetRootEdge_test)
381 {
382     Init();
383
384     EdgePtrs edge_ptrs;
385     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
386     EXPECT_EQ(dmm->GetRootEdge_Writer(false, 'm', edge_ptrs), MBError::SUCCESS);
387     dmm->AddRootEdge(edge_ptrs, (const uint8_t *) "mabain-unittest", 15, 1234);
388     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
389     EXPECT_EQ(dmm->GetRootEdge(false, 'm', edge_ptrs), MBError::SUCCESS);
390     EXPECT_EQ(edge_ptrs.offset, 1681u);
391     EXPECT_EQ(Get5BInteger(edge_ptrs.ptr), 3592u);
392
393     uint8_t *ptr = dmm->GetShmPtr(3592, 14);
394     EXPECT_EQ(memcmp(ptr, "abain-unittest", 14)==0, true);
395 }
396
397 TEST_F(DictMemTest, GetRootEdge_Writer_test)
398 {
399     Init();
400
401     EdgePtrs edge_ptrs;
402     memset(&edge_ptrs, 0, sizeof(edge_ptrs));
403     for(int i = 0; i < 256; i++) {
404         EXPECT_EQ(dmm->GetRootEdge_Writer(false, i, edge_ptrs), MBError::SUCCESS);
405     }
406 }
407
408 TEST_F(DictMemTest, ClearRootEdge_test)
409 {
410     Init();
411     uint8_t buff[1024];
412     EdgePtrs edge_ptrs;
413
414     dmm->WriteData(buff, 0, dmm->GetRootOffset());
415
416     dmm->ClearRootEdge(0);
417     dmm->GetRootEdge(0, 0, edge_ptrs); 
418     EXPECT_EQ(memcmp(edge_ptrs.edge_buff, DictMem::empty_edge, EDGE_SIZE)==0, true);
419
420     dmm->ClearRootEdge(10);
421     dmm->GetRootEdge(0, 10, edge_ptrs); 
422     EXPECT_EQ(memcmp(edge_ptrs.edge_buff, DictMem::empty_edge, EDGE_SIZE)==0, true);
423
424     dmm->ClearRootEdge(111);
425     dmm->GetRootEdge(0, 111, edge_ptrs); 
426     EXPECT_EQ(memcmp(edge_ptrs.edge_buff, DictMem::empty_edge, EDGE_SIZE)==0, true);
427 }
428
429 TEST_F(DictMemTest, ReserveData_test)
430 {
431     Init();
432
433     uint8_t buff[256];
434     int size;
435     size_t offset = 0;
436
437     size = 100;
438     dmm->ReserveData(buff, size, offset, false);
439     EXPECT_EQ(header->m_index_offset, 3692u);
440     EXPECT_EQ(header->m_index_offset, offset+100);
441 }
442
443 TEST_F(DictMemTest, NextEdge_test)
444 {
445     Init();
446 }
447
448 TEST_F(DictMemTest, RemoveEdgeByIndex_test)
449 {
450     Init();
451 }
452
453 TEST_F(DictMemTest, InitRootNode_test)
454 {
455     Init();
456
457     dmm->InitRootNode();
458     EXPECT_EQ(header->m_index_offset, 3592u);
459 }
460
461 TEST_F(DictMemTest, WriteEdge_test)
462 {
463     Init();
464
465     header->m_index_offset = 10000;
466     EdgePtrs edge_ptrs;
467     edge_ptrs.offset = 1234;
468     edge_ptrs.ptr = edge_ptrs.edge_buff;
469     dmm->WriteEdge(edge_ptrs);
470     EXPECT_EQ(header->excep_updating_status, EXCEP_STATUS_NONE);
471 }
472
473 TEST_F(DictMemTest, WriteData_test)
474 {
475     Init();
476
477     size_t offset;
478     int size;
479     uint8_t buff[32];
480     uint8_t *shm_ptr;
481
482     offset = 12345;
483     size = 21;
484     header->m_index_offset = offset + 10000;
485     for(int i = 0; i < size; i++) {
486         buff[i] = (uint8_t) i;
487     }
488     dmm->WriteData(buff, size, offset);
489     dmm->Flush();
490     shm_ptr = dmm->GetShmPtr(offset, size);
491     EXPECT_EQ(shm_ptr != NULL, true); 
492     for(int i = 0; i < size; i++) {
493         EXPECT_EQ((int)shm_ptr[i], i);
494     }
495 }
496
497 TEST_F(DictMemTest, Flush_test)
498 {
499    Init();
500    uint8_t buff[32];
501    header->m_index_offset = 10000000;
502    dmm->WriteData(buff, 32, 10000);
503    dmm->Flush();
504 }
505
506 }