1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 #ident "$Id$"
4 /*======
5 This file is part of PerconaFT.
6
7
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9
10 PerconaFT is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License, version 2,
12 as published by the Free Software Foundation.
13
14 PerconaFT is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
21
22 ----------------------------------------
23
24 PerconaFT is free software: you can redistribute it and/or modify
25 it under the terms of the GNU Affero General Public License, version 3,
26 as published by the Free Software Foundation.
27
28 PerconaFT is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU Affero General Public License for more details.
32
33 You should have received a copy of the GNU Affero General Public License
34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
35 ======= */
36
37 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
38
39 #include "test.h"
40
41 bool pf_called;
42
43 enum pin_evictor_test_type {
44 pin_in_memory,
45 pin_fetch,
46 pin_partial_fetch
47 };
48
pf_req_callback(void * UU (ftnode_pv),void * UU (read_extraargs))49 static bool pf_req_callback(void* UU(ftnode_pv), void* UU(read_extraargs)) {
50 return true;
51 }
52
pf_callback(void * UU (ftnode_pv),void * UU (disk_data),void * UU (read_extraargs),int UU (fd),PAIR_ATTR * sizep)53 static int pf_callback(void* UU(ftnode_pv), void* UU(disk_data), void* UU(read_extraargs), int UU(fd), PAIR_ATTR* sizep) {
54 *sizep = make_pair_attr(8);
55 return 0;
56 }
57
58
59 static void
cachetable_test(enum pin_evictor_test_type test_type,bool nonblocking)60 cachetable_test (enum pin_evictor_test_type test_type, bool nonblocking) {
61 const int test_limit = 7;
62 int r;
63 CACHETABLE ct;
64 toku_cachetable_create(&ct, test_limit, ZERO_LSN, nullptr);
65 evictor_test_helpers::set_hysteresis_limits(&ct->ev, test_limit, test_limit);
66 evictor_test_helpers::disable_ev_thread(&ct->ev);
67 const char *fname1 = TOKU_TEST_FILENAME;
68 unlink(fname1);
69 CACHEFILE f1;
70 r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
71
72 void* v1;
73 CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
74 r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
75 r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
76
77 // at this point, we should have 8 bytes of data in a cachetable that supports 7
78 // adding data via get_and_pin or get_and_pin_nonblocking should induce eviction
79 uint64_t old_num_ev_runs = 0;
80 uint64_t new_num_ev_runs = 0;
81 if (test_type == pin_in_memory) {
82 old_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
83 if (nonblocking) {
84 r = toku_cachetable_get_and_pin_nonblocking(f1, make_blocknum(1), 1, &v1, wc, def_fetch, def_pf_req_callback, def_pf_callback, PL_WRITE_EXPENSIVE, NULL, NULL);
85 assert_zero(r);
86 }
87 else {
88 r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
89 assert_zero(r);
90 }
91 new_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
92 assert(new_num_ev_runs == old_num_ev_runs);
93 r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
94 assert_zero(r);
95 }
96 else if (test_type == pin_fetch) {
97 old_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
98 if (nonblocking) {
99 r = toku_cachetable_get_and_pin_nonblocking(f1, make_blocknum(2), 2, &v1, wc, def_fetch, def_pf_req_callback, def_pf_callback, PL_WRITE_EXPENSIVE, NULL, NULL);
100 assert(r == TOKUDB_TRY_AGAIN);
101 new_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
102 assert(new_num_ev_runs > old_num_ev_runs);
103 }
104 else {
105 r = toku_cachetable_get_and_pin(f1, make_blocknum(2), 2, &v1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
106 assert_zero(r);
107 new_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
108 assert(new_num_ev_runs > old_num_ev_runs);
109 r = toku_test_cachetable_unpin(f1, make_blocknum(2), 2, CACHETABLE_CLEAN, make_pair_attr(8));
110 assert_zero(r);
111 }
112 }
113 else if (test_type == pin_partial_fetch) {
114 old_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
115 if (nonblocking) {
116 r = toku_cachetable_get_and_pin_nonblocking(f1, make_blocknum(1), 1, &v1, wc, def_fetch, pf_req_callback, pf_callback, PL_WRITE_EXPENSIVE, NULL, NULL);
117 assert(r == TOKUDB_TRY_AGAIN);
118 new_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
119 assert(new_num_ev_runs > old_num_ev_runs);
120 }
121 else {
122 r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, wc, def_fetch, pf_req_callback, pf_callback, true, NULL);
123 assert_zero(r);
124 new_num_ev_runs = evictor_test_helpers::get_num_eviction_runs(&ct->ev);
125 assert(new_num_ev_runs > old_num_ev_runs);
126 r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
127 assert_zero(r);
128 }
129 }
130 else {
131 assert(false);
132 }
133
134 toku_cachetable_verify(ct);
135 toku_cachefile_close(&f1, false, ZERO_LSN);
136 toku_cachetable_close(&ct);
137 }
138
139 int
test_main(int argc,const char * argv[])140 test_main(int argc, const char *argv[]) {
141 default_parse_args(argc, argv);
142 cachetable_test(pin_in_memory, true);
143 cachetable_test(pin_fetch, true);
144 cachetable_test(pin_partial_fetch, true);
145 cachetable_test(pin_in_memory, false);
146 cachetable_test(pin_fetch, false);
147 cachetable_test(pin_partial_fetch, false);
148 return 0;
149 }
150