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