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 /* Insert a bunch of stuff */
42 #include <toku_time.h>
43
44 static const char *fname ="sinsert.ft";
45
46 enum { SERIAL_SPACING = 1<<6 };
47 int64_t ITEMS_TO_INSERT_PER_ITERATION = 1<<20;
48 int64_t BOUND_INCREASE_PER_ITERATION = SERIAL_SPACING*ITEMS_TO_INSERT_PER_ITERATION;
49
50 enum { NODE_SIZE = 1<<20 };
51 enum { BASEMENT_NODE_SIZE = 128 * 1024 };
52
53 static int nodesize = NODE_SIZE;
54 static int basementnodesize = BASEMENT_NODE_SIZE;
55 static enum toku_compression_method compression_method = TOKU_DEFAULT_COMPRESSION_METHOD;
56 static int keysize = sizeof (long long);
57 static int valsize = sizeof (long long);
58 static int do_verify =0; /* Do a slow verify after every k inserts. */
59 static int verify_period = 256; /* how many inserts between verifies. */
60
61 static int do_serial = 1;
62 static int do_random = 1;
63
64 static CACHETABLE ct;
65 static FT_HANDLE t;
66
setup(void)67 static void setup (void) {
68 int r;
69 unlink(fname);
70 toku_cachetable_create(&ct, 0, ZERO_LSN, nullptr);
71 r = toku_open_ft_handle(fname, 1, &t, nodesize, basementnodesize, compression_method, ct, nullptr, toku_builtin_compare_fun); assert(r==0);
72 }
73
toku_shutdown(void)74 static void toku_shutdown (void) {
75 int r;
76 r = toku_close_ft_handle_nolsn(t, 0); assert(r==0);
77 toku_cachetable_close(&ct);
78 }
long_long_to_array(unsigned char * a,unsigned long long l)79 static void long_long_to_array (unsigned char *a, unsigned long long l) {
80 int i;
81 for (i=0; i<8; i++)
82 a[i] = (l>>(56-8*i))&0xff;
83 }
84
insert(long long v)85 static void insert (long long v) {
86 unsigned char kc[keysize], vc[valsize];
87 DBT kt, vt;
88 memset(kc, 0, sizeof kc);
89 long_long_to_array(kc, v);
90 memset(vc, 0, sizeof vc);
91 long_long_to_array(vc, v);
92 toku_ft_insert(t, toku_fill_dbt(&kt, kc, keysize), toku_fill_dbt(&vt, vc, valsize), 0);
93 if (do_verify) {
94 static int inserts_since_last_verify = 0;
95 inserts_since_last_verify++;
96 if (inserts_since_last_verify % verify_period == 0) {
97 toku_cachetable_verify(ct);
98 }
99 }
100 }
101
serial_insert_from(long long from)102 static void serial_insert_from (long long from) {
103 long long i;
104 for (i=0; i<ITEMS_TO_INSERT_PER_ITERATION; i++) {
105 insert((from+i)*SERIAL_SPACING);
106 }
107 }
108
llrandom(void)109 static long long llrandom (void) {
110 return (((long long)(random()))<<32) + random();
111 }
112
random_insert_below(long long below)113 static void random_insert_below (long long below) {
114 long long i;
115 assert(0 < below);
116 for (i=0; i<ITEMS_TO_INSERT_PER_ITERATION; i++) {
117 insert(llrandom()%below);
118 }
119 }
120
biginsert(long long n_elements,struct timeval * starttime)121 static void biginsert (long long n_elements, struct timeval *starttime) {
122 long long i;
123 struct timeval t1,t2;
124 int iteration;
125 for (i=0, iteration=0; i<n_elements; i+=ITEMS_TO_INSERT_PER_ITERATION, iteration++) {
126 gettimeofday(&t1,0);
127 if (do_serial)
128 serial_insert_from(i);
129 gettimeofday(&t2,0);
130 if (verbose && do_serial) {
131 printf("serial %9.6fs %8.0f/s ", toku_tdiff(&t2, &t1), ITEMS_TO_INSERT_PER_ITERATION/toku_tdiff(&t2, &t1));
132 fflush(stdout);
133 }
134 gettimeofday(&t1,0);
135 if (do_random)
136 random_insert_below((i+ITEMS_TO_INSERT_PER_ITERATION)*SERIAL_SPACING);
137 gettimeofday(&t2,0);
138 if (verbose && do_random) {
139 printf("random %9.6fs %8.0f/s ", toku_tdiff(&t2, &t1), ITEMS_TO_INSERT_PER_ITERATION/toku_tdiff(&t2, &t1));
140 fflush(stdout);
141 }
142 if (verbose && (do_serial || do_random)) {
143 double f = 0;
144 if (do_serial) f += 1.0;
145 if (do_random) f += 1.0;
146 printf("cumulative %9.6fs %8.0f/s\n", toku_tdiff(&t2, starttime), (ITEMS_TO_INSERT_PER_ITERATION*f/toku_tdiff(&t2, starttime))*(iteration+1));
147 fflush(stdout);
148 }
149 }
150 }
151
usage(void)152 static void usage(void) {
153 printf("benchmark-test [OPTIONS] [ITERATIONS]\n");
154 printf("[-v]\n");
155 printf("[-q]\n");
156 printf("[--nodesize NODESIZE]\n");
157 printf("[--keysize KEYSIZE]\n");
158 printf("[--valsize VALSIZE]\n");
159 printf("[--noserial]\n");
160 printf("[--norandom]\n");
161 printf("[--verify]\n");
162 printf("[--verify_period PERIOD]\n");
163 }
164
165 int
test_main(int argc,const char * argv[])166 test_main (int argc, const char *argv[]) {
167 verbose=1; //Default
168 /* parse parameters */
169 int i;
170 for (i=1; i<argc; i++) {
171 const char *arg = argv[i];
172 if (arg[0] != '-')
173 break;
174 if (strcmp(arg, "--nodesize") == 0) {
175 if (i+1 < argc) {
176 i++;
177 nodesize = atoi(argv[i]);
178 }
179 } else if (strcmp(arg, "--keysize") == 0) {
180 if (i+1 < argc) {
181 i++;
182 keysize = atoi(argv[i]);
183 }
184 } else if (strcmp(arg, "--periter") == 0) {
185 if (i+1 < argc) {
186 i++;
187 ITEMS_TO_INSERT_PER_ITERATION = atoi(argv[i]);
188 }
189 } else if (strcmp(arg, "--valsize") == 0) {
190 if (i+1 < argc) {
191 i++;
192 valsize = atoi(argv[i]);
193 }
194 } else if (strcmp(arg, "--verify")==0) {
195 do_verify = 1;
196 } else if (strcmp(arg, "--verify_period")==0) {
197 if (i+1 < argc) {
198 i++;
199 verify_period = atoi(argv[i]);
200 }
201 } else if (strcmp(arg, "--noserial") == 0) {
202 do_serial = 0;
203 } else if (strcmp(arg, "--norandom") == 0) {
204 do_random = 0;
205 } else if (strcmp(arg, "-v")==0) {
206 verbose++;
207 } else if (strcmp(arg, "-q")==0) {
208 verbose = 0;
209 } else {
210 usage();
211 return 1;
212 }
213 }
214 fname = TOKU_TEST_FILENAME;
215
216 struct timeval t1,t2,t3;
217 long long total_n_items;
218 if (i < argc) {
219 char *end;
220 errno=0;
221 total_n_items = ITEMS_TO_INSERT_PER_ITERATION * (long long) strtol(argv[i], &end, 10);
222 assert(errno==0);
223 assert(*end==0);
224 assert(end!=argv[i]);
225 } else {
226 total_n_items = 1LL<<22; // 1LL<<16
227 }
228
229 if (verbose) {
230 printf("nodesize=%d\n", nodesize);
231 printf("keysize=%d\n", keysize);
232 printf("valsize=%d\n", valsize);
233 printf("Serial and random insertions of %" PRId64 " per batch\n", ITEMS_TO_INSERT_PER_ITERATION);
234 fflush(stdout);
235 }
236 setup();
237 gettimeofday(&t1,0);
238 biginsert(total_n_items, &t1);
239 gettimeofday(&t2,0);
240 toku_shutdown();
241 gettimeofday(&t3,0);
242 if (verbose) {
243 int f = 0;
244 if (do_serial) f += 1;
245 if (do_random) f += 1;
246 printf("Shutdown %9.6fs\n", toku_tdiff(&t3, &t2));
247 printf("Total time %9.6fs for %lld insertions = %8.0f/s\n", toku_tdiff(&t3, &t1), f*total_n_items, f*total_n_items/toku_tdiff(&t3, &t1));
248 fflush(stdout);
249 }
250 unlink(fname);
251
252 return 0;
253 }
254
255