summaryrefslogtreecommitdiffstats
path: root/storage/tokudb/PerconaFT/src/tests/key-val.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/tokudb/PerconaFT/src/tests/key-val.h')
-rw-r--r--storage/tokudb/PerconaFT/src/tests/key-val.h245
1 files changed, 245 insertions, 0 deletions
diff --git a/storage/tokudb/PerconaFT/src/tests/key-val.h b/storage/tokudb/PerconaFT/src/tests/key-val.h
new file mode 100644
index 00000000..294f5304
--- /dev/null
+++ b/storage/tokudb/PerconaFT/src/tests/key-val.h
@@ -0,0 +1,245 @@
+/* -*- 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."
+
+#pragma once
+
+//
+// Functions to create unique key/value pairs, row generators, checkers, ... for each of NUM_DBS
+//
+
+// To use, during initialization:
+// generate_permute_tables();
+// r = env->set_generate_row_callback_for_put(env, put_multiple_generate);
+//
+
+
+enum {MAX_DBS=32};
+enum {MAGIC=311};
+
+// a is the bit-wise permute table. For DB[i], permute bits as described in a[i] using 'twiddle32'
+// inv is the inverse bit-wise permute of a[]. To get the original value from a twiddled value, twiddle32 (again) with inv[]
+int a[MAX_DBS][32];
+int inv[MAX_DBS][32];
+
+// rotate right and left functions
+static inline uint32_t UU() rotr32(const uint32_t x, const uint32_t num) {
+ const uint32_t n = num % 32;
+ return (x >> n) | ( x << (32 - n));
+}
+static inline uint64_t UU() rotr64(const uint64_t x, const uint64_t num) {
+ const uint64_t n = num % 64;
+ return ( x >> n ) | ( x << (64 - n));
+}
+static inline uint32_t UU() rotl32(const uint32_t x, const uint32_t num) {
+ const uint32_t n = num % 32;
+ return (x << n) | ( x >> (32 - n));
+}
+static inline uint64_t UU() rotl64(const uint64_t x, const uint64_t num) {
+ const uint64_t n = num % 64;
+ return ( x << n ) | ( x >> (64 - n));
+}
+
+static void UU() generate_permute_tables(void) {
+ int i, j, tmp;
+ for(int db=0;db<MAX_DBS;db++) {
+ for(i=0;i<32;i++) {
+ a[db][i] = i;
+ }
+ for(i=0;i<32;i++) {
+ j = random() % (i + 1);
+ tmp = a[db][j];
+ a[db][j] = a[db][i];
+ a[db][i] = tmp;
+ }
+// if(db < NUM_DBS){ printf("a[%d] = ", db); for(i=0;i<32;i++) { printf("%2d ", a[db][i]); } printf("\n");}
+ for(i=0;i<32;i++) {
+ inv[db][a[db][i]] = i;
+ }
+ }
+}
+
+// permute bits of x based on permute table bitmap
+static uint32_t UU() twiddle32(uint32_t x, int db)
+{
+ uint32_t b = 0;
+ for(int i=0;i<32;i++) {
+ b |= (( x >> i ) & 1) << a[db][i];
+ }
+ return b;
+}
+
+// permute bits of x based on inverse permute table bitmap
+static uint32_t UU() inv_twiddle32(uint32_t x, int db)
+{
+ uint32_t b = 0;
+ for(int i=0;i<32;i++) {
+ b |= (( x >> i ) & 1) << inv[db][i];
+ }
+ return b;
+}
+
+// generate val from key, index
+static uint32_t UU() generate_val(int key, int i) {
+ return rotl32((key + MAGIC), i);
+}
+static uint32_t UU() pkey_for_val(int key, int i) {
+ return rotr32(key, i) - MAGIC;
+}
+
+// There is no handlerton in this test, so this function is a local replacement
+// for the handlerton's generate_row_for_put().
+static int UU() put_multiple_generate(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals, const DBT *src_key, const DBT *src_val) {
+ toku_dbt_array_resize(dest_keys, 1);
+ toku_dbt_array_resize(dest_vals, 1);
+ DBT *dest_key = &dest_keys->dbts[0];
+ DBT *dest_val = &dest_vals->dbts[0];
+ (void) src_db;
+ (void) src_val;
+
+ uint32_t which = *(uint32_t*)dest_db->app_private;
+
+ assert(which != 0);
+ assert(dest_db != src_db);
+ {
+ assert(dest_key->flags==DB_DBT_REALLOC);
+ if (dest_key->ulen < sizeof(uint32_t)) {
+ dest_key->data = toku_xrealloc(dest_key->data, sizeof(uint32_t));
+ dest_key->ulen = sizeof(uint32_t);
+ }
+ assert(dest_val->flags==DB_DBT_REALLOC);
+ if (dest_val->ulen < sizeof(uint32_t)) {
+ dest_val->data = toku_xrealloc(dest_val->data, sizeof(uint32_t));
+ dest_val->ulen = sizeof(uint32_t);
+ }
+ uint32_t *new_key = (uint32_t *)dest_key->data;
+ uint32_t *new_val = (uint32_t *)dest_val->data;
+
+ *new_key = twiddle32(*(uint32_t*)src_key->data, which);
+ *new_val = generate_val(*(uint32_t*)src_key->data, which);
+
+ dest_key->size = sizeof(uint32_t);
+ dest_val->size = sizeof(uint32_t);
+ //data is already set above
+ }
+
+// printf("pmg : dest_key.data = %u, dest_val.data = %u \n", *(unsigned int*)dest_key->data, *(unsigned int*)dest_val->data);
+
+ return 0;
+}
+
+UU()
+static int put_multiple_generate_switch(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals, const DBT *src_key, const DBT *src_val) {
+ toku_dbt_array_resize(dest_keys, 1);
+ toku_dbt_array_resize(dest_vals, 1);
+ DBT *dest_key = &dest_keys->dbts[0];
+ DBT *dest_val = &dest_vals->dbts[0];
+ dest_key->flags = 0;
+ dest_val->flags = 0;
+
+ (void) src_db;
+
+ uint32_t which = (uint32_t) (intptr_t) dest_db->app_private;
+ assert(which == 0);
+
+ // switch the key and val
+ dbt_init(dest_key, src_val->data, src_val->size);
+ dbt_init(dest_val, src_key->data, src_key->size);
+
+// printf("dest_key.data = %d\n", *(int*)dest_key->data);
+// printf("dest_val.data = %d\n", *(int*)dest_val->data);
+
+ return 0;
+}
+
+static int UU() uint_cmp(const void *ap, const void *bp) {
+ unsigned int an = *(unsigned int *)ap;
+ unsigned int bn = *(unsigned int *)bp;
+ if (an < bn)
+ return -1;
+ if (an > bn)
+ return +1;
+ return 0;
+}
+
+float last_progress = 0.0;
+static int UU() poll_print(void *extra, float progress) {
+ if ( verbose ) {
+ if ( last_progress + 0.01 < progress ) {
+ printf(" progress : %3.0f%%\n", progress * 100.0);
+ last_progress = progress;
+ }
+ }
+ (void) extra;
+ return 0;
+}
+
+enum {MAX_CLIENTS=10};
+static inline UU() uint32_t key_to_put(int iter, int offset)
+{
+ return (uint32_t)(((iter+1) * MAX_CLIENTS) + offset);
+}
+
+static int UU() generate_initial_table(DB *db, DB_TXN *txn, uint32_t rows)
+{
+ struct timeval start, now;
+ if ( verbose ) {
+ printf("generate_initial_table\n");
+ gettimeofday(&start,0);
+ }
+ int r = 0;
+ DBT key, val;
+ uint32_t k, v, i;
+ // create keys of stride MAX_CLIENTS
+ for (i=0; i<rows; i++)
+ {
+ k = key_to_put(i, 0);
+ v = generate_val(k, 0);
+ dbt_init(&key, &k, sizeof(k));
+ dbt_init(&val, &v, sizeof(v));
+ r = db->put(db, txn, &key, &val, 0);
+ if ( r != 0 ) break;
+ }
+ if ( verbose ) {
+ gettimeofday(&now,0);
+ int duration = (int)(now.tv_sec - start.tv_sec);
+ if ( duration > 0 )
+ printf("generate_initial_table : %u rows in %d sec = %d rows/sec\n", rows, duration, rows/duration);
+ }
+
+ return r;
+}