diff options
Diffstat (limited to 'innobase/btr/ts/tsbtrfull.c')
-rw-r--r-- | innobase/btr/ts/tsbtrfull.c | 4925 |
1 files changed, 4925 insertions, 0 deletions
diff --git a/innobase/btr/ts/tsbtrfull.c b/innobase/btr/ts/tsbtrfull.c new file mode 100644 index 00000000000..fc8bbb7bffc --- /dev/null +++ b/innobase/btr/ts/tsbtrfull.c @@ -0,0 +1,4925 @@ +/************************************************************************ +Test for the B-tree + +(c) 1994-1997 Innobase Oy + +Created 2/16/1996 Heikki Tuuri +*************************************************************************/ + +#include "os0proc.h" +#include "sync0sync.h" +#include "ut0mem.h" +#include "mem0mem.h" +#include "mem0pool.h" +#include "data0data.h" +#include "data0type.h" +#include "dict0dict.h" +#include "buf0buf.h" +#include "os0file.h" +#include "os0thread.h" +#include "fil0fil.h" +#include "fsp0fsp.h" +#include "rem0rec.h" +#include "rem0cmp.h" +#include "mtr0mtr.h" +#include "log0log.h" +#include "page0page.h" +#include "page0cur.h" +#include "trx0trx.h" +#include "dict0boot.h" +#include "trx0sys.h" +#include "dict0crea.h" +#include "btr0btr.h" +#include "btr0pcur.h" +#include "btr0cur.h" +#include "btr0sea.h" +#include "rem0rec.h" +#include "srv0srv.h" +#include "que0que.h" +#include "com0com.h" +#include "usr0sess.h" +#include "lock0lock.h" +#include "trx0roll.h" +#include "trx0purge.h" +#include "row0ins.h" +#include "row0upd.h" +#include "row0row.h" +#include "row0del.h" +#include "lock0lock.h" +#include "ibuf0ibuf.h" + +os_file_t files[1000]; + +mutex_t ios_mutex; +ulint ios; +ulint n[10]; + +mutex_t incs_mutex; +ulint incs; + +byte bigbuf[1000000]; + +#define N_SPACES 2 /* must be >= 2 */ +#define N_FILES 1 +#define FILE_SIZE 8096 /* must be > 512 */ +#define POOL_SIZE 1524 +#define IBUF_SIZE 200 +#define COUNTER_OFFSET 1500 + +#define LOOP_SIZE 150 +#define N_THREADS 5 + +#define COUNT 1 + +ulint zero = 0; + +buf_block_t* bl_arr[POOL_SIZE]; + +ulint dummy = 0; + +/************************************************************************ +Io-handler thread function. */ + +ulint +handler_thread( +/*===========*/ + void* arg) +{ + ulint segment; + void* mess; + ulint i; + bool ret; + + segment = *((ulint*)arg); + + printf("Io handler thread %lu starts\n", segment); + + for (i = 0;; i++) { + fil_aio_wait(segment); + + mutex_enter(&ios_mutex); + ios++; + mutex_exit(&ios_mutex); + + } + + return(0); +} + +/************************************************************************* +Creates the files for the file system test and inserts them to the file +system. */ + +void +create_files(void) +/*==============*/ +{ + bool ret; + ulint i, k; + char name[20]; + os_thread_t thr[10]; + os_thread_id_t id[10]; + + printf("--------------------------------------------------------\n"); + printf("Create or open database files\n"); + + strcpy(name, "tsfile00"); + + for (k = 0; k < N_SPACES; k++) { + for (i = 0; i < N_FILES; i++) { + + name[6] = (char)((ulint)'0' + k); + name[7] = (char)((ulint)'0' + i); + + files[i] = os_file_create(name, OS_FILE_CREATE, + OS_FILE_TABLESPACE, &ret); + if (ret == FALSE) { + ut_a(os_file_get_last_error() == + OS_FILE_ALREADY_EXISTS); + + files[i] = os_file_create( + name, OS_FILE_OPEN, + OS_FILE_TABLESPACE, &ret); + ut_a(ret); + } else { + if (k == 1) { + ut_a(os_file_set_size(files[i], + 8192 * IBUF_SIZE, 0)); + } else { + ut_a(os_file_set_size(files[i], + 8192 * FILE_SIZE, 0)); + } + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k, OS_FILE_TABLESPACE); + } + + ut_a(fil_validate()); + + fil_node_create(name, FILE_SIZE, k); + } + } + + ios = 0; + + mutex_create(&ios_mutex); + mutex_set_level(&ios_mutex, SYNC_NO_ORDER_CHECK); + + for (i = 0; i < 9; i++) { + n[i] = i; + + thr[i] = os_thread_create(handler_thread, n + i, id + i); + } +} + +/************************************************************************ +Inits space headers of spaces 0 and 1. */ + +void +init_spaces(void) +/*=============*/ +{ + mtr_t mtr; + + mtr_start(&mtr); + + fsp_header_init(0, FILE_SIZE * N_FILES, &mtr); + fsp_header_init(1, IBUF_SIZE, &mtr); + + mtr_commit(&mtr); +} + +/********************************************************************* +Test for table creation. */ + +ulint +test1( +/*==*/ + void* arg) +{ + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + dict_index_t* index; + dict_table_t* table; + que_fork_t* fork; + que_thr_t* thr; + trx_t* trx; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 1. CREATE TABLE WITH 3 COLUMNS AND WITH 3 INDEXES\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + table = dict_mem_table_create("TS_TABLE1", 0, 3); + + dict_mem_table_add_col(table, "COL1", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL2", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL3", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + /*------------------------------------*/ + /* CREATE TABLE */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = tab_create_graph_create(fork, thr, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_TABLES"); + dict_table_print_by_name("SYS_COLUMNS"); */ + /*-------------------------------------*/ + /* CREATE CLUSTERED INDEX */ + + index = dict_mem_index_create("TS_TABLE1", "IND1", 0, + DICT_UNIQUE | DICT_CLUSTERED, 1); + dict_mem_index_add_field(index, "COL1", 0); + + ut_a(mem_heap_validate(index->heap)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = ind_create_graph_create(fork, thr, index, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_INDEXES"); + dict_table_print_by_name("SYS_FIELDS"); */ + + /*-------------------------------------*/ + /* CREATE SECONDARY INDEX */ + + index = dict_mem_index_create("TS_TABLE1", "IND2", 0, 0, 1); + + dict_mem_index_add_field(index, "COL2", 0); + + ut_a(mem_heap_validate(index->heap)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = ind_create_graph_create(fork, thr, index, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_INDEXES"); + dict_table_print_by_name("SYS_FIELDS"); */ + + /*-------------------------------------*/ + /* CREATE ANOTHER SECONDARY INDEX */ + + index = dict_mem_index_create("TS_TABLE1", "IND3", 0, 0, 1); + + dict_mem_index_add_field(index, "COL2", 0); + + ut_a(mem_heap_validate(index->heap)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = ind_create_graph_create(fork, thr, index, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +#ifdef notdefined + /*-------------------------------------*/ + /* CREATE YET ANOTHER SECONDARY INDEX */ + + index = dict_mem_index_create("TS_TABLE1", "IND4", 0, 0, 1); + + dict_mem_index_add_field(index, "COL2", 0); + + ut_a(mem_heap_validate(index->heap)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = ind_create_graph_create(fork, thr, index, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); +#endif +/* dict_table_print_by_name("SYS_INDEXES"); + dict_table_print_by_name("SYS_FIELDS"); */ + + return(0); +} + +/********************************************************************* +Another test for table creation. */ + +ulint +test1_5( +/*====*/ + void* arg) +{ + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + dict_index_t* index; + dict_table_t* table; + que_fork_t* fork; + que_thr_t* thr; + trx_t* trx; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 1.5. CREATE TABLE WITH 3 COLUMNS AND WITH 1 INDEX\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + table = dict_mem_table_create("TS_TABLE2", 0, 3); + + dict_mem_table_add_col(table, "COL1", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL2", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL3", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + /*------------------------------------*/ + /* CREATE TABLE */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = tab_create_graph_create(fork, thr, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_TABLES"); + dict_table_print_by_name("SYS_COLUMNS"); */ + /*-------------------------------------*/ + /* CREATE CLUSTERED INDEX */ + + index = dict_mem_index_create("TS_TABLE2", "IND1", 0, + DICT_CLUSTERED | DICT_UNIQUE, 1); + + dict_mem_index_add_field(index, "COL1", 0); + + ut_a(mem_heap_validate(index->heap)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = ind_create_graph_create(fork, thr, index, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_INDEXES"); + dict_table_print_by_name("SYS_FIELDS"); */ + + return(0); +} + +/********************************************************************* +Another test for table creation. */ + +ulint +test1_6( +/*====*/ + void* arg) +{ + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + dict_index_t* index; + dict_table_t* table; + que_fork_t* fork; + que_thr_t* thr; + trx_t* trx; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 1.6. CREATE TABLE WITH 3 COLUMNS AND WITH 1 INDEX\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + table = dict_mem_table_create("TS_TABLE3", 0, 3); + + dict_mem_table_add_col(table, "COL1", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL2", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL3", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + /*------------------------------------*/ + /* CREATE TABLE */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = tab_create_graph_create(fork, thr, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_TABLES"); + dict_table_print_by_name("SYS_COLUMNS"); */ + /*-------------------------------------*/ + /* CREATE CLUSTERED INDEX */ + + index = dict_mem_index_create("TS_TABLE3", "IND1", 0, DICT_CLUSTERED, + 2); + dict_mem_index_add_field(index, "COL1", 0); + dict_mem_index_add_field(index, "COL2", 0); + + ut_a(mem_heap_validate(index->heap)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = ind_create_graph_create(fork, thr, index, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_INDEXES"); + dict_table_print_by_name("SYS_FIELDS"); */ + + return(0); +} + +/********************************************************************* +Another test for table creation. */ + +ulint +test1_7( +/*====*/ + void* arg) +{ + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + dict_index_t* index; + dict_table_t* table; + que_fork_t* fork; + que_thr_t* thr; + trx_t* trx; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 1.7. CREATE TABLE WITH 12 COLUMNS AND WITH 1 INDEX\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + table = dict_mem_table_create("TS_TABLE4", 0, 12); + + dict_mem_table_add_col(table, "COL1", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL2", DATA_VARCHAR, + DATA_ENGLISH, 10, 0); + dict_mem_table_add_col(table, "COL3", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL4", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL5", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL6", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL7", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL8", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL9", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL10", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL11", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + dict_mem_table_add_col(table, "COL12", DATA_VARCHAR, + DATA_ENGLISH, 100, 0); + /*------------------------------------*/ + /* CREATE TABLE */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = tab_create_graph_create(fork, thr, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_TABLES"); + dict_table_print_by_name("SYS_COLUMNS"); */ + /*-------------------------------------*/ + /* CREATE CLUSTERED INDEX */ + + index = dict_mem_index_create("TS_TABLE4", "IND1", 0, + DICT_CLUSTERED | DICT_UNIQUE, 1); + + dict_mem_index_add_field(index, "COL1", 0); + + ut_a(mem_heap_validate(index->heap)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = ind_create_graph_create(fork, thr, index, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* dict_table_print_by_name("SYS_INDEXES"); + dict_table_print_by_name("SYS_FIELDS"); */ + + return(0); +} + +/********************************************************************* +Test for inserts. */ + +ulint +test2( +/*==*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + dict_tree_t* tree; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + byte buf[100]; + ulint count = 0; + ins_node_t* node; + dict_index_t* index; +/* ulint size; */ + dtuple_t* entry; + btr_pcur_t pcur; + mtr_t mtr; + + printf("-------------------------------------------------\n"); + printf("TEST 2. MASSIVE INSERT\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + btr_search_print_info(); + + /*-------------------------------------*/ + /* MASSIVE RANDOM INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < *((ulint*)arg); i++) { + + rnd = (rnd + 7857641) % 200000; + + dtuple_gen_test_tuple3(row, rnd, + DTUPLE_TEST_RND30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + if (i % 1000 == 0) { + printf( + "********************************Inserted %lu rows\n", i); + ibuf_print(); + } + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); +/* + for (i = 0; i < 10; i++) { + size = ibuf_contract(TRUE); + + printf("%lu bytes will be contracted\n", size); + + os_thread_sleep(1000000); + } +*/ + index = dict_table_get_next_index(dict_table_get_first_index(table)); + tree = dict_index_get_tree(index); + btr_validate_tree(tree); + + index = dict_table_get_next_index(index); + tree = dict_index_get_tree(index); + btr_validate_tree(tree); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + btr_search_print_info(); + + /* Check inserted entries */ + rnd = 0; + + entry = dtuple_create(heap, 1); + + for (i = 0; i < *((ulint*)arg); i++) { + + rnd = (rnd + 7857641) % 200000; + dtuple_gen_search_tuple3(entry, rnd, buf); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, + &mtr); + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + } + + btr_validate_tree(tree); + +/* btr_print_tree(tree, 5); */ + + /*-------------------------------------*/ + /* ROLLBACK */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu inserts %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(1000000); + + btr_validate_tree(tree); + +/* btr_search_print_info(); + dict_table_print_by_name("TS_TABLE1"); */ + /*-------------------------------------*/ +#ifdef notdefined + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); +#endif + /*-------------------------------------*/ + count++; + + if (count < 1) { + goto loop; + } + + mem_heap_free(heap); + return(0); +} + +/********************************************************************* +Another test for inserts. */ + +ulint +test2_1( +/*====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + byte buf[100]; + ins_node_t* node; + ulint count = 0; + ulint rnd; + dtuple_t* row; +/* dict_tree_t* tree; + dict_index_t* index; + dtuple_t* entry; + btr_pcur_t pcur; + mtr_t mtr; */ + + printf("-------------------------------------------------\n"); + printf("TEST 2.1. MASSIVE ASCENDING INSERT\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* MASSIVE INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < *((ulint*)arg); i++) { + + dtuple_gen_test_tuple3(row, rnd, DTUPLE_TEST_FIXED30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + if (i % 5000 == 0) { + /* ibuf_print(); */ + /* buf_print(); */ + + /* buf_print_io(); */ + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", + i, tm - oldtm); + } + + rnd = rnd + 1; + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + +#ifdef notdefined +/* dict_table_print_by_name("TS_TABLE1"); */ + + ibuf_print(); + + index = dict_table_get_first_index(table); + + btr_search_index_print_info(index); + + btr_validate_tree(dict_index_get_tree(index)); + + index = dict_table_get_next_index(index); + + btr_search_index_print_info(index); + + btr_validate_tree(dict_index_get_tree(index)); + + index = dict_table_get_next_index(index); + + btr_search_index_print_info(index); + + btr_validate_tree(dict_index_get_tree(index)); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + /* Check inserted entries */ + + btr_search_print_info(); + + entry = dtuple_create(heap, 1); + dtuple_gen_search_tuple3(entry, 0, buf); + + mtr_start(&mtr); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_open(index, entry, PAGE_CUR_L, BTR_SEARCH_LEAF, &pcur, &mtr); + ut_a(btr_pcur_is_before_first_in_tree(&pcur, &mtr)); + + for (i = 0; i < *((ulint*)arg); i++) { + ut_a(btr_pcur_move_to_next(&pcur, &mtr)); + + dtuple_gen_search_tuple3(entry, i, buf); + + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); + } + + ut_a(!btr_pcur_move_to_next(&pcur, &mtr)); + ut_a(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); +#endif +#ifdef notdefined + /*-------------------------------------*/ + /* ROLLBACK */ + +/* btr_validate_tree(tree); */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu inserts %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(1000000); + + + dtuple_gen_search_tuple3(entry, 0, buf); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_L, BTR_SEARCH_LEAF, &pcur, &mtr); + ut_a(btr_pcur_is_before_first_in_tree(&pcur, &mtr)); + + ut_a(!btr_pcur_move_to_next(&pcur, &mtr)); + + ut_a(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + btr_search_print_info(); + +#endif + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + /*-------------------------------------*/ + + count++; +/* btr_validate_tree(tree); */ + + if (count < 1) { + goto loop; + } + + mem_heap_free(heap); + + return(0); +} + +/********************************************************************* +Another test for inserts. */ + +ulint +test2_2( +/*====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + dict_index_t* index; + dict_tree_t* tree; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + dtuple_t* entry; + byte buf[100]; + ulint count = 0; + ins_node_t* node; + btr_pcur_t pcur; + mtr_t mtr; + + printf("-------------------------------------------------\n"); + printf("TEST 2.2. MASSIVE DESCENDING INSERT\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* MASSIVE INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = *((ulint*)arg) + 1; + + oldtm = ut_clock(); + + for (i = 0; i < *((ulint*)arg); i++) { + + rnd = (rnd - 1) % 200000; + + dtuple_gen_test_tuple3(row, rnd, DTUPLE_TEST_FIXED30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + if (i % 1000 == 0) { +/* printf( + "********************************Inserted %lu rows\n", i); + ibuf_print(); */ + } + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + + /* Check inserted entries */ + + entry = dtuple_create(heap, 1); + dtuple_gen_search_tuple3(entry, 0, buf); + + mtr_start(&mtr); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_open(index, entry, PAGE_CUR_L, BTR_SEARCH_LEAF, &pcur, &mtr); + ut_a(btr_pcur_is_before_first_in_tree(&pcur, &mtr)); + + for (i = 0; i < *((ulint*)arg); i++) { + ut_a(btr_pcur_move_to_next(&pcur, &mtr)); + + dtuple_gen_search_tuple3(entry, i + 1, buf); + + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); + } + + ut_a(!btr_pcur_move_to_next(&pcur, &mtr)); + ut_a(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + btr_validate_tree(tree); +/* dict_table_print_by_name("TS_TABLE1"); */ + /*-------------------------------------*/ + /* ROLLBACK */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu inserts %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(1000000); + + dtuple_gen_search_tuple3(entry, 0, buf); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_L, BTR_SEARCH_LEAF, &pcur, &mtr); + ut_a(btr_pcur_is_before_first_in_tree(&pcur, &mtr)); + + ut_a(!btr_pcur_move_to_next(&pcur, &mtr)); + + ut_a(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + /*-------------------------------------*/ +#ifdef notdefined + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); +#endif + /*-------------------------------------*/ + count++; + + if (count < 1) { + goto loop; + } + + btr_validate_tree(tree); + mem_heap_free(heap); + return(0); +} + +/********************************************************************* +Multithreaded test for random inserts. */ + +ulint +test2mt( +/*====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + dict_index_t* index; + dict_tree_t* tree; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + byte buf[100]; + ulint count = 0; + ins_node_t* node; + + printf("-------------------------------------------------\n"); + printf("TEST 2MT. MULTITHREADED RANDOM INSERT\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + rnd = 78675; +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* MASSIVE INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + for (i = 0; i < *((ulint*)arg); i++) { + + if (i % 100 == 0) { +/* buf_print(); */ +/* ibuf_print(); */ + } + + rnd = (rnd + 7857641) % 500; + + dtuple_gen_test_tuple3(row, rnd, DTUPLE_TEST_FIXED30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + + /*-------------------------------------*/ + /* ROLLBACK */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu inserts %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(3000000); + /*-------------------------------------*/ +#ifdef notdefined + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); +#endif + /*-------------------------------------*/ + count++; + + if (count < COUNT) { + goto loop; + } + + return(0); +} + +/********************************************************************* +Test for multithreaded sequential inserts. */ + +ulint +test2_1mt( +/*======*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + dict_index_t* index; + dict_tree_t* tree; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + byte buf[100]; + ulint count = 0; + ins_node_t* node; + + printf("-------------------------------------------------\n"); + printf("TEST 2.1MT. MULTITHREADED ASCENDING INSERT\n"); + + rnd = 8757677; + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* MASSIVE INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + rnd += 98667501; + + for (i = 0; i < *((ulint*)arg); i++) { + + rnd = (rnd + 1) % 500; + + dtuple_gen_test_tuple3(row, rnd, DTUPLE_TEST_FIXED30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + + /*-------------------------------------*/ + /* ROLLBACK */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu inserts %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(3000000); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + + /*-------------------------------------*/ +#ifdef notdefined + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); +#endif + /*-------------------------------------*/ + count++; + + if (count < COUNT) { + goto loop; + } + + return(0); +} + +/********************************************************************* +Test for multithreaded sequential inserts. */ + +ulint +test2_2mt( +/*======*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + byte buf[100]; + ulint count = 0; + ins_node_t* node; + + printf("-------------------------------------------------\n"); + printf("TEST 2.2MT. MULTITHREADED DESCENDING INSERT\n"); + + rnd = 87677; + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* MASSIVE INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + rnd += 78667; + + for (i = 0; i < *((ulint*)arg); i++) { + + rnd = (rnd - 1) % 500; + + dtuple_gen_test_tuple3(row, rnd, DTUPLE_TEST_RND30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + + /*-------------------------------------*/ + /* ROLLBACK */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu inserts %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(3000000); + /*-------------------------------------*/ +#ifdef notdefined + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); +#endif + /*-------------------------------------*/ + count++; + + mem_print_info(); + + if (count < COUNT) { + goto loop; + } + + return(0); +} + +/********************************************************************* +Test for updates. */ + +ulint +test3( +/*==*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + dtuple_t* entry; + byte buf[100]; + ulint count = 0; + btr_pcur_t pcur; + upd_t* update; + upd_field_t* ufield; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + upd_node_t* node; + byte* ptr; + ulint len; + ulint err; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 3. UPDATES\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + thr->child = ins_node_create(fork, thr, row, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < 3; i++) { + dtuple_gen_test_tuple3(row, i, DTUPLE_TEST_RND30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + + dict_table_print_by_name("TS_TABLE1"); + /*-------------------------------------*/ + /* UPDATE ROWS */ + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + update = upd_create(1, heap); + + node = upd_node_create(fork, thr, table, &pcur, update, heap); + thr->child = node; + + node->cmpl_info = 0; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + dtuple_gen_test_tuple3(row, 1, DTUPLE_TEST_RND30, buf); + + entry = dtuple_create(heap, 2); + dfield_copy(dtuple_get_nth_field(entry, 0), + dtuple_get_nth_field(row, 0)); + dfield_copy(dtuple_get_nth_field(entry, 1), + dtuple_get_nth_field(row, 1)); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + btr_pcur_store_position(&pcur, &mtr); + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + btr_pcur_commit(&pcur); + + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 2, table); + dfield_set_data(&(ufield->new_val), "updated field", 14); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + mtr_start(&mtr); + + ut_a(btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr)); + + ptr = rec_get_nth_field(btr_pcur_get_rec(&pcur), 5, &len); + + ut_a(ut_memcmp(ptr, "updated field", 14) == 0); + + btr_pcur_commit(&pcur); + + dict_table_print_by_name("TS_TABLE1"); + + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 0, table); + dfield_set_data(&(ufield->new_val), "31415926", 9); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + dict_table_print_by_name("TS_TABLE1"); + /*-------------------------------------*/ + /* ROLLBACK */ +#ifdef notdefined + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu updates %lu milliseconds\n", + i, tm - oldtm); + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + + /*-------------------------------------*/ +#endif + dict_table_print_by_name("TS_TABLE1"); + count++; + + if (count < 1) { + goto loop; + } + + return(0); +} + +/********************************************************************* +Init for update test. */ + +ulint +test4_1(void) +/*=========*/ +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + byte buf[100]; + + printf("-------------------------------------------------\n"); + printf("TEST 4.1. UPDATE INIT\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + thr->child = ins_node_create(fork, thr, row, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < 200; i++) { + + dtuple_gen_test_tuple3(row, i, DTUPLE_TEST_FIXED30, buf); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + + dict_table_print_by_name("TS_TABLE1"); + + return(0); +} + +/************************************************************************* +Checks that the multithreaded update test has rolled back its updates. */ + +void +test4_2(void) +/*=========*/ +{ + dtuple_t* entry; + mem_heap_t* heap; + mem_heap_t* heap2; + mtr_t mtr; + byte buf[32]; + sess_t* sess; + com_endpoint_t* com_endpoint; + que_fork_t* fork; + dict_table_t* table; + dict_index_t* index; + dict_tree_t* tree; + que_thr_t* thr; + trx_t* trx; + ulint i; + dtuple_t* row; + btr_pcur_t pcur; + rec_t* rec; + + printf("-------------------------------------------------\n"); + printf("TEST 4.2. CHECK UPDATE RESULT\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*------------------------------------------*/ + + table = dict_table_get("TS_TABLE1", trx); + + index = dict_table_get_first_index(table); + + entry = dtuple_create(heap, 1); + dtuple_gen_search_tuple3(entry, 0, buf); + + mtr_start(&mtr); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_open(index, entry, PAGE_CUR_L, BTR_SEARCH_LEAF, &pcur, &mtr); + ut_a(btr_pcur_is_before_first_in_tree(&pcur, &mtr)); + + for (i = 0; i < 200; i++) { + ut_a(btr_pcur_move_to_next(&pcur, &mtr)); + + dtuple_gen_search_tuple3(entry, i, buf); + + rec = btr_pcur_get_rec(&pcur); + + ut_a(0 == cmp_dtuple_rec(entry, rec)); + + heap2 = mem_heap_create(200); + + row = row_build(ROW_COPY_DATA, index, rec, heap2); + + ut_a(30 == dfield_get_len(dtuple_get_nth_field(row, 2))); + ut_a(0 == ut_memcmp( + dfield_get_data(dtuple_get_nth_field(row, 2)), + "12345678901234567890123456789", 30)); + + mem_heap_free(heap2); + } + + ut_a(!btr_pcur_move_to_next(&pcur, &mtr)); + ut_a(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); +} + +/********************************************************************* +Test for massive updates. */ + +ulint +test4mt( +/*====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* entry; + byte buf[100]; + byte buf2[4000]; + ulint count = 0; + btr_pcur_t pcur; + upd_t* update; + upd_field_t* ufield; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + upd_node_t* node; + ulint err; + ulint thr_no; + ulint tuple_no; + + printf("-------------------------------------------------\n"); + printf("TEST 4. MULTITHREADED UPDATES\n"); + + thr_no = *((ulint*)arg); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + /*-------------------------------------*/ + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + update = upd_create(1, heap); + + node = upd_node_create(fork, thr, table, &pcur, update, heap); + thr->child = node; + + node->cmpl_info = 0; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 87607651; + + entry = dtuple_create(heap, 1); + + oldtm = ut_clock(); + + thr_no = *((ulint*)arg); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IX, thr)); + + for (i = 0; i < 300; i++) { + + rnd += 874681; + tuple_no = (rnd % 40) * 5 + thr_no; + + dtuple_gen_search_tuple3(entry, tuple_no, buf); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + btr_pcur_store_position(&pcur, &mtr); + +/* printf("Thread %lu to update row %lu\n", thr_no, tuple_no); */ + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + btr_pcur_commit(&pcur); + + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 2, table); + dfield_set_data(&(ufield->new_val), buf2, rnd % 3000); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + } /* for (i = ... */ + + tm = ut_clock(); + printf("Wall time for %lu updates %lu milliseconds\n", + i, tm - oldtm); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + + lock_validate(); + +/* lock_print_info(); */ + +/* mem_print_info(); */ + + mem_pool_print_info(mem_comm_pool); + + /*-------------------------------------*/ + /* ROLLBACK */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu updates %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(2000000); + + btr_validate_tree(tree); + + ut_a(trx->conc_state != TRX_ACTIVE); + ut_a(UT_LIST_GET_LEN(trx->trx_locks) == 0); + + count++; + + if (count < 2) { + + goto loop; + } + + return(0); +} + +/********************************************************************* +Test for join. */ + +ulint +test6( +/*==*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + byte buf[100]; + ulint count = 0; + dtuple_t* entry; + dict_index_t* index; + dict_tree_t* tree; + btr_pcur_t pcur; + btr_pcur_t pcur2; + mtr_t mtr; + mtr_t mtr2; + ulint rnd; + ulint latch_mode; + + printf("-------------------------------------------------\n"); + printf("TEST 6. MASSIVE EQUIJOIN\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + /*--------------*/ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + /*--------------*/ + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /* Check inserted entries */ + + entry = dtuple_create(heap, 1); + dtuple_gen_search_tuple3(entry, 0, buf); + + mtr_start(&mtr); + + table = dict_table_get("TS_TABLE1", trx); + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + oldtm = ut_clock(); + + btr_pcur_open(index, entry, PAGE_CUR_L, BTR_SEARCH_LEAF, &pcur, &mtr); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IS, thr)); + + rnd = 98651; + + for (i = 0; i < *((ulint*)arg); i++) { + + ut_a(btr_pcur_move_to_next(&pcur, &mtr)); + + btr_pcur_store_position(&pcur, &mtr); + + ut_a(DB_SUCCESS == lock_clust_rec_cons_read_check( + btr_pcur_get_rec(&pcur), + index)); + + btr_pcur_commit_specify_mtr(&pcur, &mtr); + + if (i % 1211 == 0) { + dummy++; + } + + rnd = 55321; + + dtuple_gen_search_tuple3(entry, rnd % *((ulint*)arg), buf); + +/* if (i == 0) { */ + latch_mode = BTR_SEARCH_LEAF; +/* } else { + latch_mode = BTR_SEARCH_LEAF | BTR_GUESS_LATCH; + } */ + + mtr_start(&mtr2); + + btr_pcur_open(index, entry, PAGE_CUR_LE, latch_mode, + &pcur2, &mtr2); + + ut_a(DB_SUCCESS == lock_clust_rec_cons_read_check( + btr_pcur_get_rec(&pcur2), + index)); + + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur2))); + + mtr_commit(&mtr2); + + mtr_start(&mtr); + + btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); + } + + ut_a(!btr_pcur_move_to_next(&pcur, &mtr)); + ut_a(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + tm = ut_clock(); + printf("Wall time for join of %lu rows %lu milliseconds\n", + i, tm - oldtm); + btr_search_index_print_info(index); + /*-------------------------------------*/ + /* COMMIT */ + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); +/* printf("Wall time for commit %lu milliseconds\n", tm - oldtm); */ + + /*-------------------------------------*/ + count++; +/* btr_validate_tree(tree); */ + + if (count < 3) { + goto loop; + } + + mem_heap_free(heap); + return(0); +} + +/********************************************************************* +Test for lock wait. Requires Test 4.1 first. */ + +ulint +test7( +/*==*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + trx_t* trx2; + ulint rnd; + dtuple_t* entry; + dtuple_t* row; + byte buf[100]; + byte buf2[4000]; + ulint count = 0; + btr_pcur_t pcur; + upd_t* update; + upd_field_t* ufield; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + upd_node_t* node; + ulint err; + ulint thr_no; + ulint tuple_no; + + printf("-------------------------------------------------\n"); + printf("TEST 7. LOCK WAIT\n"); + + thr_no = *((ulint*)arg); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx2 = sess->trx; + + mutex_exit(&kernel_mutex); + + /*-------------------------------------*/ + /* UPDATE by trx */ + ut_a(trx_start(trx, ULINT_UNDEFINED)); + ut_a(trx_start(trx2, ULINT_UNDEFINED)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + update = upd_create(1, heap); + + node = upd_node_create(fork, thr, table, &pcur, update, heap); + thr->child = node; + + node->cmpl_info = 0; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 87607651; + + entry = dtuple_create(heap, 2); + + oldtm = ut_clock(); + + thr_no = *((ulint*)arg); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IX, thr)); + + rnd += 874681; + tuple_no = 3; + + dtuple_gen_search_tuple3(entry, tuple_no, buf); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + btr_pcur_store_position(&pcur, &mtr); + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + btr_pcur_commit(&pcur); + + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 2, table); + dfield_set_data(&(ufield->new_val), buf2, rnd % 1500); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + tm = ut_clock(); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + + lock_validate(); + + lock_print_info(); + + /*-------------------------------------*/ + /* INSERT by trx2 */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx2; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx2); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + thr->child = ins_node_create(fork, thr, row, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx2->sess); + + trx2->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + dtuple_gen_test_tuple3(row, 2, DTUPLE_TEST_FIXED30, buf); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + /* Insert should be left to wait until trx releases the row lock */ + + que_run_threads(thr); + + tm = ut_clock(); + + lock_validate(); + + lock_print_info(); + + /*-------------------------------------*/ + /* COMMIT of trx */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + + /*-------------------------------------*/ + os_thread_sleep(1000000); + + printf( + "trx2 can now continue to do the insert, after trx committed.\n"); + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + + lock_validate(); + + lock_print_info(); + + dict_table_print_by_name("TS_TABLE1"); + + return(0); +} + +/********************************************************************* +Inserts for TPC-A. */ + +ulint +test8A( +/*===*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + dict_index_t* index; + dict_tree_t* tree; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + dtuple_t* entry; + byte buf[100]; + ulint count = 0; + ins_node_t* node; + btr_pcur_t pcur; + mtr_t mtr; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 8A. 1000 INSERTS FOR TPC-A\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + btr_search_print_info(); + + /*-------------------------------------*/ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE2", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < 1000; i++) { + dtuple_gen_test_tuple_TPC_A(row, rnd, buf); + + rnd = rnd + 1; + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + btr_validate_tree(tree); + + /* Check inserted entries */ + rnd = 0; + + entry = dtuple_create(heap, 1); + + for (i = 0; i < 1000; i++) { + dtuple_gen_search_tuple_TPC_A(entry, rnd, buf); + + rnd = rnd + 1; + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, + &mtr); + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + } + + btr_validate_tree(tree); + + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + + /*-------------------------------------*/ + count++; + + if (count < 1) { + goto loop; + } + +/* dict_table_print_by_name("TS_TABLE2"); */ + + mem_heap_free(heap); + return(0); +} + +/********************************************************************* +Test for TPC-A transaction. */ + +ulint +test8( +/*==*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork1; + que_fork_t* fork2; + que_fork_t* cfork; + dict_table_t* table; + dict_table_t* table2; + que_thr_t* thr; + trx_t* trx; + ulint i; + dtuple_t* row; + dtuple_t* entry; + byte buf[100]; + ulint count = 0; + btr_pcur_t pcur; + upd_t* update; + upd_field_t* ufield; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + upd_node_t* node; + ulint err; + ins_node_t* inode; + ulint rnd = 0; + + arg = arg; + + printf("-------------------------------------------------\n"); + printf("TEST 8. TPC-A %lu \n", *((ulint*)arg)); + + oldtm = ut_clock(); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + /*-----------------------------------*/ + + fork1 = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork1->trx = trx; + + thr = que_thr_create(fork1, fork1, heap); + + table = dict_table_get("TS_TABLE3", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + inode = ins_node_create(fork1, thr, row, table, heap); + + thr->child = inode; + + row_ins_init_sys_fields_at_sql_compile(inode->row, inode->table, heap); + row_ins_init_sys_fields_at_sql_prepare(inode->row, inode->table, trx); + + inode->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork1, trx->sess); + + trx->graph = fork1; + + mutex_exit(&kernel_mutex); + + fork2 = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork2->trx = trx; + + thr = que_thr_create(fork2, fork2, heap); + + table2 = dict_table_get("TS_TABLE2", trx); + + update = upd_create(1, heap); + + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 1, table2); + + entry = dtuple_create(heap, 1); + dfield_copy(dtuple_get_nth_field(entry, 0), + dtuple_get_nth_field(row, 0)); + + node = upd_node_create(fork2, thr, table2, &pcur, update, heap); + thr->child = node; + + node->cmpl_info = UPD_NODE_NO_ORD_CHANGE | UPD_NODE_NO_SIZE_CHANGE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork2, trx->sess); + + trx->graph = fork2; + + mutex_exit(&kernel_mutex); + + cfork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + cfork->trx = trx; + + thr = que_thr_create(cfork, cfork, heap); + + thr->child = commit_node_create(cfork, thr, heap); + + oldtm = ut_clock(); + +loop: +/* printf("Round %lu\n", count); */ + + /*-------------------------------------*/ + /* INSERT */ + +/* printf("Trx %lu %lu starts, thr %lu\n", + ut_dulint_get_low(trx->id), + (ulint)trx, + *((ulint*)arg)); */ + + dtuple_gen_test_tuple3(row, count, DTUPLE_TEST_FIXED30, buf); + + ins_node_reset(inode); + + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(fork1, SESS_COMM_EXECUTE, 0); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + /*-------------------------------------*/ + /* 3 UPDATES */ + + ut_a(DB_SUCCESS == lock_table(0, table2, LOCK_IX, thr)); + + for (i = 0; i < 3; i++) { + + rnd += 876751; + + if (count % 1231 == 0) { + dummy++; + } + + dtuple_gen_search_tuple_TPC_A(entry, rnd % 1000, buf); + + index = dict_table_get_first_index(table2); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_LEAF, &pcur, &mtr); + +/* ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); */ + +/* btr_pcur_store_position(&pcur, &mtr); */ + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + ufield = upd_get_nth_field(update, 0); + + dfield_set_data(&(ufield->new_val), "1234", 5); + + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(fork2, SESS_COMM_EXECUTE, 0); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + } /* for (i = ... */ + + /*-------------------------------------*/ + /* COMMIT */ + + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(cfork, SESS_COMM_EXECUTE, 0); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + count++; + + if (count < *((ulint*)arg)) { + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + goto loop; + } + +/* printf("Trx %lu %lu committed\n", ut_dulint_get_low(trx->id), + (ulint)trx); */ + tm = ut_clock(); + printf("Wall time for TPC-A %lu trxs %lu milliseconds\n", + count, tm - oldtm); + + btr_search_index_print_info(index); + btr_search_index_print_info(dict_table_get_first_index(table)); + +/* mem_print_info(); */ + /*-------------------------------------*/ + + +/* dict_table_print_by_name("TS_TABLE2"); + dict_table_print_by_name("TS_TABLE3"); */ + + return(0); +} + +/********************************************************************* +Inserts for TPC-C. */ + +ulint +test9A( +/*===*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + byte buf[100]; + ulint count = 0; + ins_node_t* node; +/* dtuple_t* entry; + btr_pcur_t pcur; + mtr_t mtr; + dict_index_t* index; + dict_tree_t* tree; +*/ + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 9A. INSERTS FOR TPC-C\n"); + +#define TPC_C_TABLE_SIZE 15000 + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + btr_search_print_info(); + + /*-------------------------------------*/ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE4", trx); + + row = dtuple_create(heap, 12 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + node = ins_node_create(fork, thr, row, table, heap); + + thr->child = node; + + row_ins_init_sys_fields_at_sql_compile(node->row, node->table, heap); + row_ins_init_sys_fields_at_sql_prepare(node->row, node->table, trx); + + node->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < TPC_C_TABLE_SIZE; i++) { + + dtuple_gen_test_tuple_TPC_C(row, rnd, buf); + + rnd = rnd + 1; + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + +#ifdef notdefined + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + btr_validate_tree(tree); + + /* Check inserted entries */ + rnd = 0; + + entry = dtuple_create(heap, 1); + + for (i = 0; i < TPC_C_TABLE_SIZE; i++) { + + dtuple_gen_search_tuple_TPC_C(entry, rnd, buf); + + rnd = rnd + 1; + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, + &mtr); + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + } + + btr_validate_tree(tree); +#endif + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + + /*-------------------------------------*/ + count++; + + if (count < 1) { + goto loop; + } + +/* dict_table_print_by_name("TS_TABLE4"); */ + +/* mem_heap_free(heap); */ + return(0); +} + +/********************************************************************* +Test for TPC-C transaction. Test 9A must be run first to populate table. */ + +ulint +test9( +/*==*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork1; + que_fork_t* fork2; + que_fork_t* cfork; + dict_table_t* table; + dict_table_t* table2; + que_thr_t* thr; + trx_t* trx; + ulint j; + ulint i; + byte* ptr; + ulint len; + dtuple_t* row; + dtuple_t* entry; + byte buf[100]; + ulint count = 0; + btr_pcur_t pcur; + upd_t* update; + upd_field_t* ufield; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + upd_node_t* node; + ulint err; + ins_node_t* inode; + ulint rnd = 0; + byte buf2[240]; + rec_t* rec; + + arg = arg; + + printf("-------------------------------------------------\n"); + printf("TEST 9. TPC-C %lu \n", *((ulint*)arg)); + + oldtm = ut_clock(); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + /*-----------------------------------*/ + + fork1 = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork1->trx = trx; + + thr = que_thr_create(fork1, fork1, heap); + + table = dict_table_get("TS_TABLE3", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + inode = ins_node_create(fork1, thr, row, table, heap); + + thr->child = inode; + + row_ins_init_sys_fields_at_sql_compile(inode->row, inode->table, heap); + row_ins_init_sys_fields_at_sql_prepare(inode->row, inode->table, trx); + + inode->init_all_sys_fields = FALSE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork1, trx->sess); + + trx->graph = fork1; + + mutex_exit(&kernel_mutex); + + fork2 = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork2->trx = trx; + + thr = que_thr_create(fork2, fork2, heap); + + table2 = dict_table_get("TS_TABLE4", trx); + + update = upd_create(3, heap); + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 1, table2); + ufield = upd_get_nth_field(update, 1); + + upd_field_set_col_no(ufield, 1, table2); + ufield = upd_get_nth_field(update, 2); + + upd_field_set_col_no(ufield, 1, table2); + + entry = dtuple_create(heap, 1); + dfield_copy(dtuple_get_nth_field(entry, 0), + dtuple_get_nth_field(row, 0)); + + node = upd_node_create(fork2, thr, table2, &pcur, update, heap); + thr->child = node; + + node->cmpl_info = UPD_NODE_NO_ORD_CHANGE | UPD_NODE_NO_SIZE_CHANGE; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork2, trx->sess); + + trx->graph = fork2; + + mutex_exit(&kernel_mutex); + + cfork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + cfork->trx = trx; + + thr = que_thr_create(cfork, cfork, heap); + + thr->child = commit_node_create(cfork, thr, heap); + + oldtm = ut_clock(); +loop: + ut_a(DB_SUCCESS == lock_table(0, table2, LOCK_IS, thr)); + ut_a(DB_SUCCESS == lock_table(0, table2, LOCK_IX, thr)); + +/* printf("Round %lu\n", count); */ + +for (j = 0; j < 13; j++) { + + /*-------------------------------------*/ + /* SELECT FROM 'ITEM' */ + + rnd += 876751; + + dtuple_gen_search_tuple_TPC_C(entry, rnd % TPC_C_TABLE_SIZE, buf); + + index = dict_table_get_first_index(table2); + tree = dict_index_get_tree(index); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_S, thr); + ut_a(err == DB_SUCCESS); + + rec = btr_pcur_get_rec(&pcur); + + for (i = 0; i < 5; i++) { + ptr = rec_get_nth_field(rec, i + 2, &len); + + ut_memcpy(buf2 + i * 24, ptr, len); + } + + mtr_commit(&mtr); + + /*-------------------------------------*/ + /* UPDATE 'STOCK' */ + + rnd += 876751; + + if (count % 1231 == 0) { + dummy++; + } + + dtuple_gen_search_tuple_TPC_C(entry, rnd % TPC_C_TABLE_SIZE, buf); + + index = dict_table_get_first_index(table2); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_LEAF, &pcur, &mtr); + + ut_a(0 == cmp_dtuple_rec(entry, btr_pcur_get_rec(&pcur))); + +/* btr_pcur_store_position(&pcur, &mtr); */ + + rec = btr_pcur_get_rec(&pcur); + + for (i = 0; i < 10; i++) { + ptr = rec_get_nth_field(rec, i + 2, &len); + + ut_memcpy(buf2 + i * 24, ptr, len); + } + +/* btr_pcur_commit(&pcur); */ + +/* err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); */ + ut_a(DB_SUCCESS == lock_clust_rec_cons_read_check( + btr_pcur_get_rec(&pcur), + index)); +/* ut_a(err == DB_SUCCESS); */ + + ufield = upd_get_nth_field(update, 0); + + dfield_set_data(&(ufield->new_val), "1234", 5); + + ufield = upd_get_nth_field(update, 1); + + dfield_set_data(&(ufield->new_val), "1234", 5); + + ufield = upd_get_nth_field(update, 2); + + dfield_set_data(&(ufield->new_val), "1234", 5); + + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(fork2, SESS_COMM_EXECUTE, 0); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + btr_pcur_close(&pcur); + /*-------------------------------------*/ + /* INSERT INTO 'ORDERLINE' */ + +/* printf("Trx %lu %lu starts, thr %lu\n", + ut_dulint_get_low(trx->id), + (ulint)trx, + *((ulint*)arg)); */ + + dtuple_gen_test_tuple3(row, count * 13 + j, DTUPLE_TEST_FIXED30, buf); + + ins_node_reset(inode); + + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(fork1, SESS_COMM_EXECUTE, 0); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +} + /*-------------------------------------*/ + /* COMMIT */ + + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(cfork, SESS_COMM_EXECUTE, 0); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + +/* printf("Trx %lu %lu committed\n", ut_dulint_get_low(trx->id), + (ulint)trx); */ + count++; + + if (count < *((ulint*)arg)) { + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + goto loop; + } + + tm = ut_clock(); + printf("Wall time for TPC-C %lu trxs %lu milliseconds\n", + count, tm - oldtm); + + btr_search_index_print_info(index); + btr_search_index_print_info(dict_table_get_first_index(table)); + +/* mem_print_info(); */ + /*-------------------------------------*/ +/* dict_table_print_by_name("TS_TABLE2"); + dict_table_print_by_name("TS_TABLE3"); */ + + return(0); +} + +/********************************************************************* +Init for purge test. */ + +ulint +test10_1( +/*=====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* row; + byte buf[100]; + ulint thr_no; + + thr_no = *((ulint*)arg); + + printf("-------------------------------------------------\n"); + printf("TEST 10.1. PURGE INIT\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + /*-------------------------------------*/ + /* INSERT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_INSERT, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + row = dtuple_create(heap, 3 + DATA_N_SYS_COLS); + + dict_table_copy_types(row, table); + + thr->child = ins_node_create(fork, thr, row, table, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < 200; i++) { + + dtuple_gen_test_tuple3(row, i * 100 + thr_no, + DTUPLE_TEST_FIXED30, buf); + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + tm = ut_clock(); + printf("Wall time for %lu inserts %lu milliseconds\n", i, tm - oldtm); + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + return(0); +} + +/********************************************************************* +Test for purge. */ + +ulint +test10_2( +/*=====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* entry; + byte buf[100]; + byte buf2[1000]; + ulint count = 0; + btr_pcur_t pcur; + upd_t* update; + upd_field_t* ufield; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + upd_node_t* node; + ulint err; + ulint thr_no; + ulint tuple_no; + + printf("-------------------------------------------------\n"); + printf("TEST 10.2. PURGE TEST UPDATES\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + /*-------------------------------------*/ + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + update = upd_create(2, heap); + + node = upd_node_create(fork, thr, table, &pcur, update, heap); + thr->child = node; + + node->cmpl_info = 0; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 87607651; + + entry = dtuple_create(heap, 1); + + oldtm = ut_clock(); + + thr_no = *((ulint*)arg); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IX, thr)); + + for (i = 0; i < 200; i++) { + + tuple_no = i; + + dtuple_gen_search_tuple3(entry, tuple_no * 100 + thr_no, buf); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + btr_pcur_store_position(&pcur, &mtr); + +/* printf("Thread %lu to update row %lu\n", thr_no, tuple_no); */ + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + btr_pcur_commit(&pcur); + + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 0, table); + + dtuple_gen_search_tuple3(entry, tuple_no * 100 + 10 + thr_no, buf); + + dfield_set_data(&(ufield->new_val), dfield_get_data( + dtuple_get_nth_field(entry, 0)), + dfield_get_len( + dtuple_get_nth_field(entry, 0))); + ufield = upd_get_nth_field(update, 1); + + upd_field_set_col_no(ufield, 1, table); + + rnd += 98326761; + + dfield_set_data(&(ufield->new_val), buf2, rnd % 200); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + fsp_validate(0); + + } /* for (i = ... */ + + tm = ut_clock(); + printf("Wall time for %lu updates %lu milliseconds\n", + i, tm - oldtm); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + +/* lock_print_info(); */ + +/* mem_print_info(); */ + + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + + count++; + + if (count < 1) { + + goto loop; + } + + return(0); +} + +/********************************************************************* +Test for purge. */ + +ulint +test10_2_r( +/*=======*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* entry; + byte buf[100]; + byte buf2[1000]; + ulint count = 0; + btr_pcur_t pcur; + upd_t* update; + upd_field_t* ufield; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + upd_node_t* node; + ulint err; + ulint thr_no; + ulint tuple_no; + + printf("-------------------------------------------------\n"); + printf("TEST 10.2. PURGE TEST UPDATES\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); +loop: + /*-------------------------------------*/ + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + update = upd_create(2, heap); + + node = upd_node_create(fork, thr, table, &pcur, update, heap); + thr->child = node; + + node->cmpl_info = 0; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + rnd = 87607651; + + entry = dtuple_create(heap, 1); + + oldtm = ut_clock(); + + thr_no = *((ulint*)arg); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IX, thr)); + + for (i = 0; i < 200; i++) { + + tuple_no = i; + + dtuple_gen_search_tuple3(entry, tuple_no * 100 + thr_no, buf); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + btr_pcur_store_position(&pcur, &mtr); + +/* printf("Thread %lu to update row %lu\n", thr_no, tuple_no); */ + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + btr_pcur_commit(&pcur); + + ufield = upd_get_nth_field(update, 0); + + upd_field_set_col_no(ufield, 0, table); + + dtuple_gen_search_tuple3(entry, tuple_no * 100 + 10 + thr_no, buf); + + dfield_set_data(&(ufield->new_val), dfield_get_data( + dtuple_get_nth_field(entry, 0)), + dfield_get_len( + dtuple_get_nth_field(entry, 0))); + ufield = upd_get_nth_field(update, 1); + + upd_field_set_col_no(ufield, 1, table); + + rnd += 98326761; + + dfield_set_data(&(ufield->new_val), buf2, rnd % 2000); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + fsp_validate(0); + + } /* for (i = ... */ + + tm = ut_clock(); + printf("Wall time for %lu updates %lu milliseconds\n", + i, tm - oldtm); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + +/* lock_print_info(); */ + + mem_pool_print_info(mem_comm_pool); + + /*-------------------------------------*/ + /* ROLLBACK */ + + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = roll_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback of %lu updates %lu milliseconds\n", + i, tm - oldtm); + + os_thread_sleep(2000000); + + count++; + + if (count < 1) { + + goto loop; + } + + return(0); +} + +/********************************************************************* +Test for purge. */ + +ulint +test10_3( +/*=====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* entry; + byte buf[100]; + btr_pcur_t pcur; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + del_node_t* node; + ulint err; + ulint thr_no; + ulint tuple_no; + + printf("-------------------------------------------------\n"); + printf("TEST 10.3. PURGE TEST DELETES\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + /*-------------------------------------*/ + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + node = del_node_create(fork, thr, table, &pcur, heap); + thr->child = node; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + entry = dtuple_create(heap, 1); + + oldtm = ut_clock(); + + thr_no = *((ulint*)arg); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IX, thr)); + + for (i = 0; i < 200; i++) { + + rnd = i; + tuple_no = rnd; + + dtuple_gen_search_tuple3(entry, tuple_no * 100 + 10 + thr_no, buf); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + btr_pcur_store_position(&pcur, &mtr); + +/* printf("Thread %lu to update row %lu\n", thr_no, tuple_no); */ + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + btr_pcur_commit(&pcur); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + } /* for (i = ... */ + + tm = ut_clock(); + printf("Wall time for %lu delete markings %lu milliseconds\n", + i, tm - oldtm); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + +/* lock_print_info(); */ + +/* mem_print_info(); */ + + /*-------------------------------------*/ + /* COMMIT */ + fork = que_fork_create(NULL, NULL, QUE_FORK_EXECUTE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + thr->child = commit_node_create(fork, thr, heap); + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for commit %lu milliseconds\n", tm - oldtm); + + return(0); +} + +/********************************************************************* +Test for purge. */ + +ulint +test10_5( +/*=====*/ + void* arg) +{ + ulint tm, oldtm; + sess_t* sess; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* fork; + dict_table_t* table; + que_thr_t* thr; + trx_t* trx; + ulint i; + ulint rnd; + dtuple_t* entry; + byte buf[100]; + btr_pcur_t pcur; + dict_tree_t* tree; + dict_index_t* index; + mtr_t mtr; + del_node_t* node; + ulint err; + ulint thr_no; + ulint tuple_no; + + printf("-------------------------------------------------\n"); + printf("TEST 10.5. PURGE TEST UNCOMMITTED DELETES\n"); + + heap = mem_heap_create(512); + + com_endpoint = (com_endpoint_t*)heap; /* This is a dummy non-NULL + value */ + mutex_enter(&kernel_mutex); + + sess = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user1", 6); + + trx = sess->trx; + + mutex_exit(&kernel_mutex); + + /*-------------------------------------*/ + ut_a(trx_start(trx, ULINT_UNDEFINED)); + + fork = que_fork_create(NULL, NULL, QUE_FORK_UPDATE, heap); + fork->trx = trx; + + thr = que_thr_create(fork, fork, heap); + + table = dict_table_get("TS_TABLE1", trx); + + node = del_node_create(fork, thr, table, &pcur, heap); + thr->child = node; + + mutex_enter(&kernel_mutex); + + que_graph_publish(fork, trx->sess); + + trx->graph = fork; + + mutex_exit(&kernel_mutex); + + entry = dtuple_create(heap, 1); + + oldtm = ut_clock(); + + thr_no = *((ulint*)arg); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IX, thr)); + + for (i = 0; i < 50; i++) { + + rnd = i; + tuple_no = rnd % 100; + + dtuple_gen_search_tuple3(entry, tuple_no * 100 + 10 + thr_no, buf); + + index = dict_table_get_first_index(table); + tree = dict_index_get_tree(index); + + btr_pcur_set_mtr(&pcur, &mtr); + + mtr_start(&mtr); + + btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); + + btr_pcur_store_position(&pcur, &mtr); + +/* printf("Thread %lu to update row %lu\n", thr_no, tuple_no); */ + + err = lock_clust_rec_read_check_and_lock(0, btr_pcur_get_rec(&pcur), + index, LOCK_X, thr); + ut_a(err == DB_SUCCESS); + + btr_pcur_commit(&pcur); + + mutex_enter(&kernel_mutex); + + ut_a( + thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + } /* for (i = ... */ + + tm = ut_clock(); + printf("Wall time for %lu delete markings %lu milliseconds\n", + i, tm - oldtm); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + printf("Validating tree\n"); + btr_validate_tree(tree); + printf("Validated\n"); + +/* lock_print_info(); */ + +/* mem_print_info(); */ + + return(0); +} + +/********************************************************************* +Multithreaded test for purge. */ + +ulint +test10mt( +/*=====*/ + void* arg) +{ + ulint i; + ulint thr_no; + + thr_no = *((ulint*)arg); + + printf("Thread %lu starts purge test\n", thr_no); + + for (i = 0; i < 2; i++) { + test10_1(arg); + + sync_print(); + + fsp_validate(0); + + test10_2_r(arg); + sync_print(); + + test10_2(arg); + sync_print(); + + lock_validate(); + + test10_3(arg); + sync_print(); + } + + printf("Thread %lu ends purge test\n", thr_no); + + return(0); +} + +/********************************************************************* +Purge test. */ + +ulint +test10_4( +/*=====*/ + void* arg) +{ + ulint i; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 10.4. PURGE TEST\n"); + + for (i = 0; i < 30; i++) { + trx_purge(); + + printf("%lu pages purged\n", purge_sys->n_pages_handled); + + os_thread_sleep(5000000); + } + +/* dict_table_print_by_name("TS_TABLE1"); */ + + return(0); +} + +/********************************************************************* +This thread is used to test insert buffer merge. */ + +ulint +test_ibuf_merge( +/*============*/ + void* arg) +{ + ulint sum_sizes; + ulint volume; + + ut_ad(arg); + + printf("Starting ibuf merge\n"); + + sum_sizes = 0; + volume = 1; + + while (volume) { + volume = ibuf_contract(FALSE); + + sum_sizes += volume; + } + + printf("Ibuf merged %lu bytes\n", sum_sizes); + + os_thread_sleep(5000000); + + return(0); +} + +/********************************************************************* +This thread is used to measure contention of latches. */ + +ulint +test_measure_cont( +/*==============*/ + void* arg) +{ + ulint i, j; + ulint count; + + ut_ad(arg); + + printf("Starting contention measurement\n"); + + for (i = 0; i < 1000; i++) { + count = 0; + + for (j = 0; j < 100; j++) { + + os_thread_sleep(10000); + + if ((&(buf_pool->mutex))->lock_word) { + + count++; + } + } + + printf("Mutex reserved %lu of %lu peeks\n", count, j); + } + + return(0); +} + +/******************************************************************** +Main test function. */ + +void +main(void) +/*======*/ +{ + ulint tm, oldtm; + os_thread_id_t id[10]; + ulint n1000[10]; + ulint i; + ulint n5000 = 500; + ulint n2; + +/* buf_debug_prints = TRUE; */ + log_do_write = FALSE; + btr_search_use_hash = FALSE; + + srv_boot("initfile"); + os_aio_init(576, 9, 100); + fil_init(25); + buf_pool_init(POOL_SIZE, POOL_SIZE); + fsp_init(); + log_init(); + lock_sys_create(1024); + + create_files(); + + init_spaces(); + + sess_sys_init_at_db_start(); + + trx_sys_create(); + + dict_create(); + +/* os_thread_sleep(500000); */ + + oldtm = ut_clock(); + + ut_rnd_set_seed(19); + + test1(NULL); + test1_5(NULL); + test1_6(NULL); + test1_7(NULL); + +/* for (i = 0; i < 2; i++) { + + n1000[i] = i; + id[i] = id[i]; + + os_thread_create(test10mt, n1000 + i, id + i); + } +*/ + i = 4; + + n1000[i] = i; + id[i] = id[i]; + +/* os_thread_create(test10_4, n1000 + i, id + i); */ + + i = 5; + +/* test10mt(&i); + + i = 6; + + test10mt(&i); + + trx_purge(); + printf("%lu pages purged\n", purge_sys->n_pages_handled); + + dict_table_print_by_name("TS_TABLE1"); */ + +/* os_thread_create(test_measure_cont, &n3, id + 0); */ + +/* mem_print_info(); */ + +/* dict_table_print_by_name("TS_TABLE1"); */ + + n2 = 2000; + +/* test2_1(&n2); */ + + sync_print(); + + test9A(&n2); + + sync_print(); + + log_print(); + + test9(&n2); + + log_print(); + + sync_print(); +/* test6(&n2); */ + +/* test2(&n2); */ + +/* test2_2(&n2); */ + +/* mem_print_info(); */ + + for (i = 0; i < 2; i++) { + + n1000[i] = 1000 + 10 * i; + id[i] = id[i]; + +/* os_thread_create(test2mt, n1000 + i, id + i); + os_thread_create(test2_1mt, n1000 + i, id + i); + os_thread_create(test2_2mt, n1000 + i, id + i); */ + } + + n2 = 2000; + +/* test2mt(&n2); */ + +/* buf_print(); + ibuf_print(); + rw_lock_list_print_info(); + mutex_list_print_info(); + + dict_table_print_by_name("TS_TABLE1"); */ + +/* mem_print_info(); */ + + n2 = 1000; + +/* test4_1(); + test4_2(); + + for (i = 0; i < 2; i++) { + n1000[i] = i; + id[i] = id[i]; + os_thread_create(test4mt, n1000 + i, id + i); + } + + n2 = 4; + test4mt(&n2); + test4mt(&n2); + test4_2(); + lock_print_info(); */ + +/* test7(&n2); */ + +/* os_thread_sleep(25000000); */ + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} |