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 <stdio.h>
40 #include <assert.h>
41 #include <stdint.h>
42 #include <inttypes.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46 #include <sys/stat.h>
47 #include <db.h>
48 #include <toku_byteswap.h>
49 #include <portability/toku_path.h>
50 
51 static int verbose = 0;
52 static uint64_t maxk = 100000;
53 
usage(const char * prog)54 static int usage(const char *prog) {
55     fprintf(stderr, "%s: run single row insertions with prelocking\n", prog);
56     fprintf(stderr, "[--n %" PRIu64 "]\n", maxk);
57     return 1;
58 }
59 
inserter(DB_ENV * env,DB * db,uint64_t _maxk,int putflags,int expectr)60 static int inserter(DB_ENV *env, DB *db, uint64_t _maxk, int putflags, int expectr) {
61     if (verbose) printf("%p %p\n", env, db);
62     int r;
63     for (uint64_t k = 0; k < _maxk; k++) {
64 
65         if (verbose) printf("%" PRIu64 "\n", k);
66 
67         DB_TXN *txn;
68         r = env->txn_begin(env, NULL, &txn, 0);
69         assert(r == 0);
70 
71         r = db->pre_acquire_table_lock(db, txn);
72         assert(r == 0);
73 
74         uint64_t kk = bswap_64(k);
75         DBT key = { .data = &kk, .size = sizeof kk };
76         DBT val = { .data = &k, .size = sizeof k };
77         r = db->put(db, txn, &key, &val, putflags);
78         assert(r == expectr);
79 
80         r = txn->commit(txn, DB_TXN_NOSYNC);
81         assert(r == 0);
82     }
83 
84     return 0;
85 }
86 
env_init(DB_ENV ** envptr,const char * envdir)87 static int env_init(DB_ENV **envptr, const char *envdir) {
88     int r;
89     DB_ENV *env;
90 
91     r = db_env_create(&env, 0);
92     if (r == 0) {
93         // env setup
94 
95         // env open
96         r = env->open(env, envdir, DB_CREATE+DB_PRIVATE+DB_INIT_LOCK+DB_INIT_LOG+DB_INIT_MPOOL+DB_INIT_TXN, 0777);
97     }
98     if (r == 0)
99         *envptr = env;
100     return r;
101 }
102 
db_init(DB_ENV * env,const char * dbname,DB ** dbptr)103 static int db_init(DB_ENV *env, const char *dbname, DB **dbptr) {
104     int r;
105     DB *db;
106 
107     r = db_create(&db, env, 0);
108     if (r == 0) {
109         // db create
110         r = db->open(db, NULL, dbname, NULL, DB_BTREE, DB_CREATE, 0777);
111         if (r != 0) {
112             r = db->close(db, 0);
113             assert(r == 0);
114         }
115     }
116     if (r == 0)
117         *dbptr = db;
118     return r;
119 }
120 
main(int argc,char * argv[])121 int main(int argc, char *argv[]) {
122     int r;
123 
124     for (int i = 1; i < argc; i++) {
125         char *arg = argv[i];
126         if (strcmp(arg, "--n") == 0 && i+1 < argc) {
127             maxk = atoi(argv[++i]);
128             continue;
129         }
130         if (strcmp(arg, "--verbose") == 0 || strcmp(arg, "-v") == 0) {
131             verbose++;
132             continue;
133         }
134         if (strcmp(arg, "-q") == 0) {
135             verbose = 0;
136             continue;
137         }
138 
139         return usage(argv[0]);
140     }
141 
142     const char *envdir = TOKU_TEST_FILENAME;
143     char cmd[TOKU_PATH_MAX+sizeof("rm -rf ")];
144     snprintf(cmd, sizeof(cmd), "rm -rf %s", TOKU_TEST_FILENAME);
145     r = system(cmd);
146     assert(r == 0);
147     r = mkdir(envdir, 0777);
148     assert(r == 0);
149 
150     DB_ENV *env;
151     r = env_init(&env, envdir);
152     assert(r == 0);
153 
154     DB *db;
155     r = db_init(env, "db0", &db);
156     assert(r == 0);
157 
158     r = inserter(env, db, maxk, 0, 0);
159     assert(r == 0);
160 
161     r = inserter(env, db, maxk, DB_NOOVERWRITE, DB_KEYEXIST);
162     assert(r == 0);
163 
164     r = db->close(db, 0);
165     assert(r == 0);
166 
167     r = env->close(env, 0);
168     assert(r == 0);
169 
170     return 0;
171 }
172