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 // Create a lot of dirty nodes, kick off a checkpoint, and close the environment.
40 // Measure the time it takes to close the environment since we are speeding up that
41 // function.
42
43 #include "test.h"
44 #include <toku_time.h>
45
46 // Insert max_rows key/val pairs into the db
do_inserts(DB_ENV * env,DB * db,uint64_t max_rows,size_t val_size)47 static void do_inserts(DB_ENV *env, DB *db, uint64_t max_rows, size_t val_size) {
48 char val_data[val_size]; memset(val_data, 0, val_size);
49 int r;
50 DB_TXN *txn = nullptr;
51 r = env->txn_begin(env, nullptr, &txn, 0);
52 CKERR(r);
53
54 for (uint64_t i = 1; i <= max_rows; i++) {
55 // pick a sequential key but it does not matter for this test.
56 uint64_t k[2] = {
57 htonl(i), random64(),
58 };
59 DBT key = { .data = k, .size = sizeof k };
60 DBT val = { .data = val_data, .size = (uint32_t) val_size };
61 r = db->put(db, txn, &key, &val, 0);
62 CKERR(r);
63
64 if ((i % 1000) == 0) {
65 if (verbose)
66 fprintf(stderr, "put %" PRIu64 "\n", i);
67 r = txn->commit(txn, 0);
68 CKERR(r);
69 r = env->txn_begin(env, nullptr, &txn, 0);
70 CKERR(r);
71 }
72 }
73
74 r = txn->commit(txn, 0);
75 CKERR(r);
76 }
77
78 // Create a cache with a lot of dirty nodes, kick off a checkpoint, and measure the time to
79 // close the environment.
big_shutdown(void)80 static void big_shutdown(void) {
81 int r;
82
83 DB_ENV *env = nullptr;
84 r = db_env_create(&env, 0);
85 CKERR(r);
86 r = env->set_cachesize(env, 8, 0, 1);
87 CKERR(r);
88 r = env->open(env, TOKU_TEST_FILENAME,
89 DB_INIT_MPOOL|DB_CREATE|DB_THREAD |DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_TXN|DB_PRIVATE,
90 S_IRWXU+S_IRWXG+S_IRWXO);
91 CKERR(r);
92
93 DB *db = nullptr;
94 r = db_create(&db, env, 0);
95 CKERR(r);
96 r = db->open(db, nullptr, "foo.db", 0, DB_BTREE, DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
97 CKERR(r);
98
99 do_inserts(env, db, 1000000, 1024);
100
101 // kick the checkpoint thread
102 if (verbose)
103 fprintf(stderr, "env->checkpointing_set_period\n");
104 r = env->checkpointing_set_period(env, 2);
105 CKERR(r);
106 sleep(3);
107
108 if (verbose)
109 fprintf(stderr, "db->close\n");
110 r = db->close(db, 0);
111 CKERR(r);
112
113 // measure the shutdown time
114 uint64_t tstart = toku_current_time_microsec();
115 if (verbose)
116 fprintf(stderr, "env->close\n");
117 r = env->close(env, 0);
118 CKERR(r);
119 uint64_t tend = toku_current_time_microsec();
120 if (verbose)
121 fprintf(stderr, "env->close complete %" PRIu64 " sec\n", (tend - tstart)/1000000);
122 }
123
test_main(int argc,char * const argv[])124 int test_main (int argc, char *const argv[]) {
125 default_parse_args(argc, argv);
126
127 // init the env directory
128 toku_os_recursive_delete(TOKU_TEST_FILENAME);
129 int r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO);
130 CKERR(r);
131
132 // run the test
133 big_shutdown();
134
135 return 0;
136 }
137