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 TokuDB
6 
7 
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9 
10     TokuDBis 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     TokuDB 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 TokuDB.  If not, see <http://www.gnu.org/licenses/>.
21 
22 ======= */
23 
24 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
25 
26 // test tokudb cardinality in status dictionary
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <assert.h>
31 #include <memory.h>
32 #include <errno.h>
33 #include <sys/stat.h>
34 #include <db.h>
35 typedef unsigned long long ulonglong;
36 #include <tokudb_status.h>
37 #include <tokudb_buffer.h>
38 
39 #include "fake_mysql.h"
40 
41 #if __APPLE__
42 typedef unsigned long ulong;
43 #endif
44 #include <tokudb_card.h>
45 
46 // verify that we can create and close a status dictionary
test_create(DB_ENV * env)47 static void test_create(DB_ENV *env) {
48     int error;
49 
50     DB_TXN *txn = NULL;
51     error = env->txn_begin(env, NULL, &txn, 0);
52     assert(error == 0);
53 
54     DB *status_db = NULL;
55     error = tokudb::create_status(env, &status_db, "status.db", txn);
56     assert(error == 0);
57 
58     error = txn->commit(txn, 0);
59     assert(error == 0);
60 
61     error = tokudb::close_status(&status_db);
62     assert(error == 0);
63 }
64 
65 // verify that no card row in status works
test_no_card(DB_ENV * env)66 static void test_no_card(DB_ENV *env) {
67     int error;
68 
69     DB_TXN *txn = NULL;
70     error = env->txn_begin(env, NULL, &txn, 0);
71     assert(error == 0);
72 
73     DB *status_db = NULL;
74     error = tokudb::open_status(env, &status_db, "status.db", txn);
75     assert(error == 0);
76 
77     error = tokudb::get_card_from_status(status_db, txn, 0, NULL);
78     assert(error == DB_NOTFOUND);
79 
80     error = txn->commit(txn, 0);
81     assert(error == 0);
82 
83     error = tokudb::close_status(&status_db);
84     assert(error == 0);
85 }
86 
87 // verify that a card row with 0 array elements works
test_0(DB_ENV * env)88 static void test_0(DB_ENV *env) {
89     int error;
90 
91     DB_TXN *txn = NULL;
92     error = env->txn_begin(env, NULL, &txn, 0);
93     assert(error == 0);
94 
95     DB *status_db = NULL;
96     error = tokudb::open_status(env, &status_db, "status.db", txn);
97     assert(error == 0);
98 
99     tokudb::set_card_in_status(status_db, txn, 0, NULL);
100 
101     error = tokudb::get_card_from_status(status_db, txn, 0, NULL);
102     assert(error == 0);
103 
104     error = txn->commit(txn, 0);
105     assert(error == 0);
106 
107     error = tokudb::close_status(&status_db);
108     assert(error == 0);
109 }
110 
111 // verify that writing and reading card info works for several sized card arrays
test_10(DB_ENV * env)112 static void test_10(DB_ENV *env) {
113     int error;
114 
115     for (uint64_t i = 0; i < 20; i++) {
116 
117         uint64_t rec_per_key[i];
118         for (uint64_t j = 0; j < i; j++)
119             rec_per_key[j] = j == 0 ? 10+i : 10 * rec_per_key[j-1];
120 
121         DB_TXN *txn = NULL;
122         error = env->txn_begin(env, NULL, &txn, 0);
123         assert(error == 0);
124 
125         DB *status_db = NULL;
126         error = tokudb::open_status(env, &status_db, "status.db", txn);
127         assert(error == 0);
128 
129         tokudb::set_card_in_status(status_db, txn, i, rec_per_key);
130 
131         uint64_t stored_rec_per_key[i];
132         error = tokudb::get_card_from_status(status_db, txn, i, stored_rec_per_key);
133         assert(error == 0);
134 
135         for (uint64_t j = 0; j < i; j++)
136             assert(rec_per_key[j] == stored_rec_per_key[j]);
137 
138         error = txn->commit(txn, 0);
139         assert(error == 0);
140 
141         error = tokudb::close_status(&status_db);
142         assert(error == 0);
143 
144         error = env->txn_begin(env, NULL, &txn, 0);
145         assert(error == 0);
146 
147         error = tokudb::open_status(env, &status_db, "status.db", txn);
148         assert(error == 0);
149 
150         tokudb::set_card_in_status(status_db, txn, i, rec_per_key);
151 
152         error = tokudb::get_card_from_status(status_db, txn, i, stored_rec_per_key);
153         assert(error == 0);
154 
155         for (uint64_t j = 0; j < i; j++)
156             assert(rec_per_key[j] == stored_rec_per_key[j]);
157 
158         error = txn->commit(txn, 0);
159         assert(error == 0);
160 
161         // test delete card
162         error = env->txn_begin(env, NULL, &txn, 0);
163         assert(error == 0);
164 
165         error = tokudb::delete_card_from_status(status_db, txn);
166         assert(error == 0);
167 
168         error = tokudb::get_card_from_status(status_db, txn, 0, NULL);
169         assert(error == DB_NOTFOUND);
170 
171         error = txn->commit(txn, 0);
172         assert(error == 0);
173 
174         error = tokudb::close_status(&status_db);
175         assert(error == 0);
176     }
177 }
178 
main()179 int main() {
180     int error;
181 
182     error = system("rm -rf " __FILE__ ".testdir");
183     assert(error == 0);
184 
185     error = mkdir(__FILE__ ".testdir", S_IRWXU+S_IRWXG+S_IRWXO);
186     assert(error == 0);
187 
188     DB_ENV *env = NULL;
189     error = db_env_create(&env, 0);
190     assert(error == 0);
191 
192     error = env->open(env, __FILE__ ".testdir", DB_INIT_MPOOL + DB_INIT_LOG + DB_INIT_LOCK + DB_INIT_TXN + DB_PRIVATE + DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
193     assert(error == 0);
194 
195     test_create(env);
196     test_no_card(env);
197     test_0(env);
198     test_10(env);
199 
200     error = env->close(env, 0);
201     assert(error == 0);
202 
203     return 0;
204 }
205