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 "manager_unit_test.h"
40 
41 namespace toku {
42 
create_cb(locktree * lt,void * extra)43 static int create_cb(locktree *lt, void *extra) {
44     lt->set_userdata(extra);
45     bool *k = (bool *) extra;
46     invariant(!(*k));
47     (*k) = true;
48     return 0;
49 }
50 
destroy_cb(locktree * lt)51 static void destroy_cb(locktree *lt) {
52     bool *k = (bool *) lt->get_userdata();
53     invariant(*k);
54     (*k) = false;
55 }
56 
my_cmp(DB * UU (db),const DBT * UU (a),const DBT * UU (b))57 static int my_cmp(DB *UU(db), const DBT *UU(a), const DBT *UU(b)) {
58     return 0;
59 }
60 
test_reference_release_lt(void)61 void manager_unit_test::test_reference_release_lt(void) {
62     locktree_manager mgr;
63     mgr.create(create_cb, destroy_cb, nullptr, nullptr);
64     toku::comparator my_comparator;
65     my_comparator.create(my_cmp, nullptr);
66 
67     DICTIONARY_ID a = { 0 };
68     DICTIONARY_ID b = { 1 };
69     DICTIONARY_ID c = { 2 };
70     bool aok = false;
71     bool bok = false;
72     bool cok = false;
73 
74     locktree *alt = mgr.get_lt(a, my_comparator, &aok);
75     invariant_notnull(alt);
76     locktree *blt = mgr.get_lt(b, my_comparator, &bok);
77     invariant_notnull(alt);
78     locktree *clt = mgr.get_lt(c, my_comparator, &cok);
79     invariant_notnull(alt);
80 
81     // three distinct locktrees should have been returned
82     invariant(alt != blt && alt != clt && blt != clt);
83 
84     // on create callbacks should have been called
85     invariant(aok);
86     invariant(bok);
87     invariant(cok);
88 
89     // add 3 refs. b should still exist.
90     mgr.reference_lt(blt);
91     mgr.reference_lt(blt);
92     mgr.reference_lt(blt);
93     invariant(bok);
94     // remove 3 refs. b should still exist.
95     mgr.release_lt(blt);
96     mgr.release_lt(blt);
97     mgr.release_lt(blt);
98     invariant(bok);
99 
100     // get another handle on a and b, they shoudl be the same
101     // as the original alt and blt
102     locktree *blt2 = mgr.get_lt(b, my_comparator, &bok);
103     invariant(blt2 == blt);
104     locktree *alt2 = mgr.get_lt(a, my_comparator, &aok);
105     invariant(alt2 == alt);
106 
107     // remove one ref from everything. c should die. a and b are ok.
108     mgr.release_lt(alt);
109     mgr.release_lt(blt);
110     mgr.release_lt(clt);
111     invariant(aok);
112     invariant(bok);
113     invariant(!cok);
114 
115     // release a and b. both should die.
116     mgr.release_lt(blt2);
117     mgr.release_lt(alt2);
118     invariant(!aok);
119     invariant(!bok);
120 
121     my_comparator.destroy();
122     mgr.destroy();
123 }
124 
125 } /* namespace toku */
126 
main(void)127 int main(void) {
128     toku::manager_unit_test test;
129     test.test_reference_release_lt();
130     return 0;
131 }
132