summaryrefslogtreecommitdiffstats
path: root/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/tokudb/PerconaFT/ft/ft-test-helpers.cc')
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-test-helpers.cc268
1 files changed, 268 insertions, 0 deletions
diff --git a/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
new file mode 100644
index 00000000..ad1dda01
--- /dev/null
+++ b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
@@ -0,0 +1,268 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*======
+This file is part of PerconaFT.
+
+
+Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2,
+ as published by the Free Software Foundation.
+
+ PerconaFT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+
+----------------------------------------
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License, version 3,
+ as published by the Free Software Foundation.
+
+ PerconaFT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+======= */
+
+#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
+
+#include <my_global.h>
+#include "ft/ft.h"
+#include "ft/ft-cachetable-wrappers.h"
+#include "ft/ft-internal.h"
+#include "ft/ft-flusher.h"
+#include "ft/serialize/ft_node-serialize.h"
+#include "ft/node.h"
+#include "ft/ule.h"
+
+// dummymsn needed to simulate msn because messages are injected at a lower level than toku_ft_root_put_msg()
+#define MIN_DUMMYMSN ((MSN) {(uint64_t)1 << 62})
+static MSN dummymsn;
+static int testsetup_initialized = 0;
+
+
+// Must be called before any other test_setup_xxx() functions are called.
+void
+toku_testsetup_initialize(void) {
+ if (testsetup_initialized == 0) {
+ testsetup_initialized = 1;
+ dummymsn = MIN_DUMMYMSN;
+ }
+}
+
+static MSN
+next_dummymsn(void) {
+ ++(dummymsn.msn);
+ return dummymsn;
+}
+
+
+bool ignore_if_was_already_open;
+int toku_testsetup_leaf(FT_HANDLE ft_handle, BLOCKNUM *blocknum, int n_children, char **keys, int *keylens) {
+ FTNODE node;
+ assert(testsetup_initialized);
+ toku_create_new_ftnode(ft_handle, &node, 0, n_children);
+ for (int i = 0; i < n_children; i++) {
+ BP_STATE(node, i) = PT_AVAIL;
+ }
+
+ DBT *XMALLOC_N(n_children - 1, pivotkeys);
+ for (int i = 0; i + 1 < n_children; i++) {
+ toku_memdup_dbt(&pivotkeys[i], keys[i], keylens[i]);
+ }
+ node->pivotkeys.create_from_dbts(pivotkeys, n_children - 1);
+ for (int i = 0; i + 1 < n_children; i++) {
+ toku_destroy_dbt(&pivotkeys[i]);
+ }
+ toku_free(pivotkeys);
+
+ *blocknum = node->blocknum;
+ toku_unpin_ftnode(ft_handle->ft, node);
+ return 0;
+}
+
+// Don't bother to clean up carefully if something goes wrong. (E.g., it's OK to have malloced stuff that hasn't been freed.)
+int toku_testsetup_nonleaf (FT_HANDLE ft_handle, int height, BLOCKNUM *blocknum, int n_children, BLOCKNUM *children, char **keys, int *keylens) {
+ FTNODE node;
+ assert(testsetup_initialized);
+ toku_create_new_ftnode(ft_handle, &node, height, n_children);
+ for (int i = 0; i < n_children; i++) {
+ BP_BLOCKNUM(node, i) = children[i];
+ BP_STATE(node,i) = PT_AVAIL;
+ }
+ DBT *XMALLOC_N(n_children - 1, pivotkeys);
+ for (int i = 0; i + 1 < n_children; i++) {
+ toku_memdup_dbt(&pivotkeys[i], keys[i], keylens[i]);
+ }
+ node->pivotkeys.create_from_dbts(pivotkeys, n_children - 1);
+ for (int i = 0; i + 1 < n_children; i++) {
+ toku_destroy_dbt(&pivotkeys[i]);
+ }
+ toku_free(pivotkeys);
+
+ *blocknum = node->blocknum;
+ toku_unpin_ftnode(ft_handle->ft, node);
+ return 0;
+}
+
+int toku_testsetup_root(FT_HANDLE ft_handle, BLOCKNUM blocknum) {
+ assert(testsetup_initialized);
+ ft_handle->ft->h->root_blocknum = blocknum;
+ return 0;
+}
+
+int toku_testsetup_get_sersize(FT_HANDLE ft_handle, BLOCKNUM diskoff) // Return the size on disk
+{
+ assert(testsetup_initialized);
+ void *node_v;
+ ftnode_fetch_extra bfe;
+ bfe.create_for_full_read(ft_handle->ft);
+ int r = toku_cachetable_get_and_pin(
+ ft_handle->ft->cf, diskoff,
+ toku_cachetable_hash(ft_handle->ft->cf, diskoff),
+ &node_v,
+ get_write_callbacks_for_node(ft_handle->ft),
+ toku_ftnode_fetch_callback,
+ toku_ftnode_pf_req_callback,
+ toku_ftnode_pf_callback,
+ true,
+ &bfe
+ );
+ assert(r==0);
+ FTNODE CAST_FROM_VOIDP(node, node_v);
+ int size = toku_serialize_ftnode_size(node);
+ toku_unpin_ftnode(ft_handle->ft, node);
+ return size;
+}
+
+int toku_testsetup_insert_to_leaf (FT_HANDLE ft_handle, BLOCKNUM blocknum, const char *key, int keylen, const char *val, int vallen) {
+ void *node_v;
+ int r;
+
+ assert(testsetup_initialized);
+
+ ftnode_fetch_extra bfe;
+ bfe.create_for_full_read(ft_handle->ft);
+ r = toku_cachetable_get_and_pin(
+ ft_handle->ft->cf,
+ blocknum,
+ toku_cachetable_hash(ft_handle->ft->cf, blocknum),
+ &node_v,
+ get_write_callbacks_for_node(ft_handle->ft),
+ toku_ftnode_fetch_callback,
+ toku_ftnode_pf_req_callback,
+ toku_ftnode_pf_callback,
+ true,
+ &bfe
+ );
+ if (r!=0) return r;
+ FTNODE CAST_FROM_VOIDP(node, node_v);
+ toku_verify_or_set_counts(node);
+ assert(node->height==0);
+
+ DBT kdbt, vdbt;
+ ft_msg msg(
+ toku_fill_dbt(&kdbt, key, keylen),
+ toku_fill_dbt(&vdbt, val, vallen),
+ FT_INSERT,
+ next_dummymsn(),
+ toku_xids_get_root_xids());
+
+ static size_t zero_flow_deltas[] = { 0, 0 };
+ txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, true);
+ toku_ftnode_put_msg(
+ ft_handle->ft->cmp,
+ ft_handle->ft->update_fun,
+ node,
+ -1,
+ msg,
+ true,
+ &gc_info,
+ zero_flow_deltas,
+ NULL,
+ NULL);
+
+ toku_verify_or_set_counts(node);
+
+ toku_unpin_ftnode(ft_handle->ft, node);
+ return 0;
+}
+
+static int
+testhelper_string_key_cmp(DB *UU(e), const DBT *a, const DBT *b)
+{
+ char *CAST_FROM_VOIDP(s, a->data), *CAST_FROM_VOIDP(t, b->data);
+ return strcmp(s, t);
+}
+
+
+void
+toku_pin_node_with_min_bfe(FTNODE* node, BLOCKNUM b, FT_HANDLE t)
+{
+ ftnode_fetch_extra bfe;
+ bfe.create_for_min_read(t->ft);
+ toku_pin_ftnode(
+ t->ft,
+ b,
+ toku_cachetable_hash(t->ft->cf, b),
+ &bfe,
+ PL_WRITE_EXPENSIVE,
+ node,
+ true
+ );
+}
+
+int toku_testsetup_insert_to_nonleaf (FT_HANDLE ft_handle, BLOCKNUM blocknum, enum ft_msg_type msgtype, const char *key, int keylen, const char *val, int vallen) {
+ void *node_v;
+ int r;
+
+ assert(testsetup_initialized);
+
+ ftnode_fetch_extra bfe;
+ bfe.create_for_full_read(ft_handle->ft);
+ r = toku_cachetable_get_and_pin(
+ ft_handle->ft->cf,
+ blocknum,
+ toku_cachetable_hash(ft_handle->ft->cf, blocknum),
+ &node_v,
+ get_write_callbacks_for_node(ft_handle->ft),
+ toku_ftnode_fetch_callback,
+ toku_ftnode_pf_req_callback,
+ toku_ftnode_pf_callback,
+ true,
+ &bfe
+ );
+ if (r!=0) return r;
+ FTNODE CAST_FROM_VOIDP(node, node_v);
+ assert(node->height>0);
+
+ DBT k;
+ int childnum = toku_ftnode_which_child(node, toku_fill_dbt(&k, key, keylen), ft_handle->ft->cmp);
+
+ XIDS xids_0 = toku_xids_get_root_xids();
+ MSN msn = next_dummymsn();
+ toku::comparator cmp;
+ cmp.create(testhelper_string_key_cmp, nullptr);
+ toku_bnc_insert_msg(BNC(node, childnum), key, keylen, val, vallen, msgtype, msn, xids_0, true, cmp);
+ cmp.destroy();
+ // Hack to get the test working. The problem is that this test
+ // is directly queueing something in a FIFO instead of
+ // using ft APIs.
+ node->max_msn_applied_to_node_on_disk = msn;
+ node->set_dirty();
+ // Also hack max_msn_in_ft
+ ft_handle->ft->h->max_msn_in_ft = msn;
+
+ toku_unpin_ftnode(ft_handle->ft, node);
+ return 0;
+}