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 /* The goal of this test. Make sure that inserts stay behind deletes. */
40
41
42 #include "test.h"
43
44 #include <ft-cachetable-wrappers.h>
45 #include "ft-flusher.h"
46 #include "ft-flusher-internal.h"
47 #include "cachetable/checkpoint.h"
48
49 static TOKUTXN const null_txn = 0;
50
51 enum { NODESIZE = 1024, KSIZE=NODESIZE-100, TOKU_PSIZE=20 };
52
53 static void
doit(void)54 doit (void) {
55 BLOCKNUM node_leaf[3];
56 BLOCKNUM node_root;
57
58 CACHETABLE ct;
59 FT_HANDLE t;
60
61 int r;
62
63 toku_cachetable_create(&ct, 500*1024*1024, ZERO_LSN, nullptr);
64 unlink(TOKU_TEST_FILENAME);
65 r = toku_open_ft_handle(TOKU_TEST_FILENAME, 1, &t, NODESIZE, NODESIZE/2, TOKU_DEFAULT_COMPRESSION_METHOD, ct, null_txn, toku_builtin_compare_fun);
66 assert(r==0);
67
68 toku_testsetup_initialize(); // must precede any other toku_testsetup calls
69
70 r = toku_testsetup_leaf(t, &node_leaf[0], 1, NULL, NULL);
71 assert(r==0);
72 r = toku_testsetup_leaf(t, &node_leaf[1], 1, NULL, NULL);
73 assert(r==0);
74 r = toku_testsetup_leaf(t, &node_leaf[2], 1, NULL, NULL);
75 assert(r==0);
76
77 int keylens[2];
78 keylens[0] = 2;
79 keylens[1] = 2;
80 char first[2];
81 first[0] = 'f';
82 first[1] = 0;
83 char second[2];
84 second[0] = 'p';
85 second[1] = 0;
86
87 char* keys[2];
88 keys[0] = first;
89 keys[1] = second;
90 r = toku_testsetup_nonleaf(t, 1, &node_root, 3, node_leaf, keys, keylens);
91 assert(r==0);
92
93 r = toku_testsetup_root(t, node_root);
94 assert(r==0);
95
96
97 r = toku_testsetup_insert_to_nonleaf(
98 t,
99 node_root,
100 FT_INSERT,
101 "a",
102 2,
103 NULL,
104 0
105 );
106 r = toku_testsetup_insert_to_nonleaf(
107 t,
108 node_root,
109 FT_INSERT,
110 "m",
111 2,
112 NULL,
113 0
114 );
115
116 r = toku_testsetup_insert_to_nonleaf(
117 t,
118 node_root,
119 FT_INSERT,
120 "z",
121 2,
122 NULL,
123 0
124 );
125
126
127 // at this point, we have inserted three messages into
128 // the root, one in each buffer, let's verify this.
129
130 FTNODE node = NULL;
131 ftnode_fetch_extra bfe;
132 bfe.create_for_min_read(t->ft);
133 toku_pin_ftnode(
134 t->ft,
135 node_root,
136 toku_cachetable_hash(t->ft->cf, node_root),
137 &bfe,
138 PL_WRITE_EXPENSIVE,
139 &node,
140 true
141 );
142 assert(node->height == 1);
143 assert(node->n_children == 3);
144 assert(toku_bnc_nbytesinbuf(BNC(node, 0)) > 0);
145 assert(toku_bnc_nbytesinbuf(BNC(node, 1)) > 0);
146 assert(toku_bnc_nbytesinbuf(BNC(node, 2)) > 0);
147 toku_unpin_ftnode(t->ft, node);
148
149 // now let's run a hot optimize, that should only flush the middle buffer
150 DBT left;
151 toku_fill_dbt(&left, "g", 2);
152 DBT right;
153 toku_fill_dbt(&right, "n", 2);
154 uint64_t loops_run = 0;
155 r = toku_ft_hot_optimize(t, &left, &right, NULL, NULL, &loops_run);
156 assert(r==0);
157
158 // at this point, we have should have flushed
159 // only the middle buffer, let's verify this.
160 node = NULL;
161 bfe.create_for_min_read(t->ft);
162 toku_pin_ftnode(
163 t->ft,
164 node_root,
165 toku_cachetable_hash(t->ft->cf, node_root),
166 &bfe,
167 PL_WRITE_EXPENSIVE,
168 &node,
169 true
170 );
171 assert(node->height == 1);
172 assert(node->n_children == 3);
173 assert(toku_bnc_nbytesinbuf(BNC(node, 0)) > 0);
174 assert(toku_bnc_nbytesinbuf(BNC(node, 1)) == 0);
175 assert(toku_bnc_nbytesinbuf(BNC(node, 2)) > 0);
176 toku_unpin_ftnode(t->ft, node);
177
178 r = toku_close_ft_handle_nolsn(t, 0); assert(r==0);
179 toku_cachetable_close(&ct);
180 }
181
182 int
test_main(int argc,const char * argv[])183 test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
184 default_parse_args(argc, argv);
185 doit();
186 return 0;
187 }
188