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