1 /*
2  * Copyright (C) 2010-2020 Codership Oy <info@codership.com>
3  *
4  * $Id$
5  */
6 
7 #include "gcache_page_store.hpp"
8 #include "gcache_bh.hpp"
9 #include "gcache_page_test.hpp"
10 
11 using namespace gcache;
12 
ps_free(void * ptr)13 void ps_free (void* ptr)
14 {
15     BufferHeader* const bh(ptr2BH(ptr));
16     BH_release (bh);
17     bh->seqno_g = SEQNO_ILL;
18 }
19 
START_TEST(test1)20 START_TEST(test1)
21 {
22     const char* const dir_name = "";
23     ssize_t const bh_size = sizeof(gcache::BufferHeader);
24     ssize_t const keep_size = 1;
25     ssize_t const page_size = 2 + bh_size;
26 
27     gcache::PageStore ps (dir_name, keep_size, page_size, 0, false);
28 
29     ck_assert_msg(ps.count()       == 0,"expected count 0, got %zu",ps.count());
30     ck_assert_msg(ps.total_pages() == 0,"expected 0 pages, got %zu",ps.total_pages());
31     ck_assert_msg(ps.total_size()  == 0,"expected size 0, got %zu", ps.total_size());
32 
33     void* buf = ps.malloc (3 + bh_size);
34 
35     ck_assert(0 != buf);
36     ck_assert_msg(ps.count()       == 1,"expected count 1, got %zu",ps.count());
37     ck_assert_msg(ps.total_pages() == 1,"expected 1 pages, got %zu",ps.total_pages());
38 
39     void* tmp = ps.realloc (buf, 2 + bh_size);
40 
41     ck_assert(buf == tmp);
42     ck_assert_msg(ps.count()       == 1,"expected count 1, got %zu",ps.count());
43     ck_assert_msg(ps.total_pages() == 1,"expected 1 pages, got %zu",ps.total_pages());
44 
45     tmp = ps.realloc (buf, 4 + bh_size); // here new page should be allocated
46 
47     ck_assert(0   != tmp);
48     ck_assert(buf != tmp);
49     ck_assert_msg(ps.count()       == 2,"expected count 2, got %zu",ps.count());
50     ck_assert_msg(ps.total_pages() == 1,"expected 1 pages, got %zu",ps.total_pages());
51 
52     ps_free(tmp);
53     ps.discard (ptr2BH(tmp));
54 
55     ck_assert_msg(ps.count()       == 2,"expected count 2, got %zu",ps.count());
56     ck_assert_msg(ps.total_pages() == 0,"expected 0 pages, got %zu",ps.total_pages());
57     ck_assert_msg(ps.total_size()  == 0,"expected size 0, got %zu", ps.total_size());
58 }
59 END_TEST
60 
START_TEST(test2)61 START_TEST(test2)
62 {
63     const char* const dir_name = "";
64     ssize_t const bh_size = sizeof(gcache::BufferHeader);
65     ssize_t const keep_size = 1;
66     ssize_t page_size = (1 << 20) + bh_size;
67 
68     gcache::PageStore ps (dir_name, keep_size, page_size, 0, false);
69 
70     mark_point();
71 
72     uint8_t* buf = static_cast<uint8_t*>(ps.malloc (page_size));
73 
74     ck_assert(0 != buf);
75 
76     while (--page_size)
77     {
78         buf[page_size] = page_size;
79     }
80 
81     mark_point();
82 
83     ps_free(buf);
84     ps.discard (ptr2BH(buf));
85 }
86 END_TEST
87 
START_TEST(test3)88 START_TEST(test3) // check that all page size is efficiently used
89 {
90     const char* const dir_name = "";
91     ssize_t const keep_size = 1;
92     ssize_t const page_size = 1024;
93 
94     gcache::PageStore ps (dir_name, keep_size, page_size, 0, false);
95 
96     mark_point();
97 
98     ssize_t ptr_size = (page_size / 2);
99 
100     void* ptr1 = ps.malloc (ptr_size);
101     ck_assert(0 != ptr1);
102 
103     void* ptr2 = ps.malloc (ptr_size);
104     ck_assert(0 != ptr2);
105 
106     ck_assert_msg(ps.count() == 1, "ps.count() = %zd, expected 1", ps.count());
107 
108     // check that ptr2 is adjacent to ptr1
109     void* tmp = static_cast<uint8_t*>(ptr1) + ptr_size;
110 
111     ck_assert_msg(tmp == ptr2, "tmp = %p, ptr2 = %p", tmp, ptr2);
112 
113     ps_free(ptr1); ps.discard(ptr2BH(ptr1));
114     ps_free(ptr2); ps.discard(ptr2BH(ptr2));
115 }
116 END_TEST
117 
gcache_page_suite()118 Suite* gcache_page_suite()
119 {
120     Suite* s = suite_create("gcache::PageStore");
121     TCase* tc;
122 
123     tc = tcase_create("test");
124     tcase_add_test(tc, test1);
125     tcase_add_test(tc, test2);
126     tcase_add_test(tc, test3);
127     suite_add_tcase(s, tc);
128 
129     return s;
130 }
131