diff options
author | unknown <monty@donna.mysql.com> | 2001-02-17 14:19:19 +0200 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2001-02-17 14:19:19 +0200 |
commit | 2662b59306ef0cd495fa6e2edf7129e58a11393a (patch) | |
tree | bfe39951a73e906579ab819bf5198ad8f3a64a36 /innobase/btr/ts | |
parent | 66de55a56bdcf2f7a9c0c4f8e19b3e761475e202 (diff) | |
download | mariadb-git-2662b59306ef0cd495fa6e2edf7129e58a11393a.tar.gz |
Added Innobase to source distribution
Docs/manual.texi:
Added Innobase documentation
configure.in:
Incremented version
include/my_base.h:
Added option for Innobase
myisam/mi_check.c:
cleanup
mysql-test/t/bdb.test:
cleanup
mysql-test/t/innobase.test:
Extended with new tests from bdb.test
mysql-test/t/merge.test:
Added test of SHOW create
mysys/my_init.c:
Fix for UNIXWARE 7
scripts/mysql_install_db.sh:
Always write how to start mysqld
scripts/safe_mysqld.sh:
Fixed type
sql/ha_innobase.cc:
Update to new version
sql/ha_innobase.h:
Update to new version
sql/handler.h:
Added 'update_table_comment()' and 'append_create_info()'
sql/sql_delete.cc:
Fixes for Innobase
sql/sql_select.cc:
Fixes for Innobase
sql/sql_show.cc:
Append create information (for MERGE tables)
sql/sql_update.cc:
Fixes for Innobase
Diffstat (limited to 'innobase/btr/ts')
-rw-r--r-- | innobase/btr/ts/isql.c | 312 | ||||
-rw-r--r-- | innobase/btr/ts/makefile | 16 | ||||
-rw-r--r-- | innobase/btr/ts/trash/TSIT.C | 483 | ||||
-rw-r--r-- | innobase/btr/ts/trash/tsbtrold5.c | 798 | ||||
-rw-r--r-- | innobase/btr/ts/trash/tscli.c | 2263 | ||||
-rw-r--r-- | innobase/btr/ts/tsbtr97.c | 5080 | ||||
-rw-r--r-- | innobase/btr/ts/tsbtrfull.c | 4925 | ||||
-rw-r--r-- | innobase/btr/ts/tsbtrins.c | 802 | ||||
-rw-r--r-- | innobase/btr/ts/tscli.c | 3380 | ||||
-rw-r--r-- | innobase/btr/ts/tsrecv.c | 4909 | ||||
-rw-r--r-- | innobase/btr/ts/tsrecv97.c | 4909 | ||||
-rw-r--r-- | innobase/btr/ts/tss.c | 397 | ||||
-rw-r--r-- | innobase/btr/ts/tssrv.c | 535 |
13 files changed, 28809 insertions, 0 deletions
diff --git a/innobase/btr/ts/isql.c b/innobase/btr/ts/isql.c new file mode 100644 index 00000000000..db56aa65a66 --- /dev/null +++ b/innobase/btr/ts/isql.c @@ -0,0 +1,312 @@ +/************************************************************************ +Test for the client: interactive SQL + +(c) 1996-1997 Innobase Oy + +Created 2/16/1996 Heikki Tuuri +*************************************************************************/ + +#include "univ.i" +#include "ib_odbc.h" +#include "mem0mem.h" +#include "sync0sync.h" +#include "os0thread.h" +#include "os0proc.h" +#include "os0sync.h" +#include "srv0srv.h" + +ulint n_exited = 0; + +char cli_srv_endpoint_name[100]; +char cli_user_name[100]; + +ulint n_warehouses = ULINT_MAX; +ulint n_customers_d = ULINT_MAX; +bool is_tpc_d = FALSE; +ulint n_rounds = ULINT_MAX; +ulint n_users = ULINT_MAX; +ulint startdate = 0; +ulint enddate = 0; +bool own_warehouse = FALSE; + +ulint mem_pool_size = ULINT_MAX; + +/************************************************************************* +Reads a keywords and a values from an initfile. In case of an error, exits +from the process. */ +static +void +cli_read_initfile( +/*==============*/ + FILE* initfile) /* in: file pointer */ +{ + char str_buf[10000]; + ulint ulint_val; + + srv_read_init_val(initfile, FALSE, "SRV_ENDPOINT_NAME", str_buf, + &ulint_val); + + ut_a(ut_strlen(str_buf) < COM_MAX_ADDR_LEN); + + ut_memcpy(cli_srv_endpoint_name, str_buf, COM_MAX_ADDR_LEN); + + srv_read_init_val(initfile, FALSE, "USER_NAME", str_buf, + &ulint_val); + ut_a(ut_strlen(str_buf) < COM_MAX_ADDR_LEN); + + ut_memcpy(cli_user_name, str_buf, COM_MAX_ADDR_LEN); + + srv_read_init_val(initfile, TRUE, "MEM_POOL_SIZE", str_buf, + &mem_pool_size); + + srv_read_init_val(initfile, TRUE, "N_WAREHOUSES", str_buf, + &n_warehouses); + + srv_read_init_val(initfile, TRUE, "N_CUSTOMERS_D", str_buf, + &n_customers_d); + + srv_read_init_val(initfile, TRUE, "IS_TPC_D", str_buf, + &is_tpc_d); + + srv_read_init_val(initfile, TRUE, "N_ROUNDS", str_buf, + &n_rounds); + + srv_read_init_val(initfile, TRUE, "N_USERS", str_buf, + &n_users); + + srv_read_init_val(initfile, TRUE, "STARTDATE", str_buf, + &startdate); + + srv_read_init_val(initfile, TRUE, "ENDDATE", str_buf, + &enddate); + + srv_read_init_val(initfile, TRUE, "OWN_WAREHOUSE", str_buf, + &own_warehouse); +} + +/************************************************************************* +Reads configuration info for the client. */ +static +void +cli_boot( +/*=====*/ + char* name) /* in: the initialization file name */ +{ + FILE* initfile; + + initfile = fopen(name, "r"); + + if (initfile == NULL) { + printf( + "Error in client booting: could not open initfile whose name is %s!\n", + name); + os_process_exit(1); + } + + cli_read_initfile(initfile); + + fclose(initfile); +} + +/********************************************************************* +Interactive SQL loop. */ +static +void +isql( +/*=*/ + FILE* inputfile) /* in: input file containing SQL strings, + or stdin */ +{ + HENV env; + HDBC conn; + RETCODE ret; + HSTMT sql_query; + ulint tm, oldtm; + char buf[1000]; + char* str; + ulint count; + ulint n_begins; + ulint len; + ulint n; + ulint i; + ulint n_lines; + + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLConnect(conn, (UCHAR*)cli_srv_endpoint_name, + (SWORD)ut_strlen(cli_srv_endpoint_name), + cli_user_name, + (SWORD)ut_strlen(cli_user_name), + (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + printf("Interactive SQL performs queries by first making a stored\n"); + printf("procedure from them, and then calling the procedure.\n"); + printf("Put a semicolon after each statement and\n"); + printf("end your query with two <enter>s.\n\n"); + printf("You can also give a single input file\n"); + printf("as a command line argument to isql.\n\n"); + printf("In the file separate SQL queries and procedure bodies\n"); + printf("by a single empty line. Do not write the final END; into\n"); + printf("a procedure body.\n\n"); + + count = 0; +loop: + count++; + n = 0; + n_lines = 0; + + sprintf(buf, "PROCEDURE P%s%lu () IS\nBEGIN ", cli_user_name, + count); + for (;;) { + len = ut_strlen(buf + n) - 1; + n += len; + + if (len == 0) { + break; + } else { + sprintf(buf + n, "\n"); + n++; + n_lines++; + } + + str = fgets(buf + n, 1000, inputfile); + + if ((str == NULL) && (inputfile != stdin)) { + /* Reached end-of-file: switch to input from + keyboard */ + + inputfile = stdin; + + break; + } + + ut_a(str); + } + + if (n_lines == 1) { + /* Empty procedure */ + + goto loop; + } + + /* If the statement is actually the body of a procedure, + erase the first BEGIN from the string: */ + + n_begins = 0; + + for (i = 0; i < n - 5; i++) { + + if (ut_memcmp(buf + i, "BEGIN", 5) == 0) { + + n_begins++; + } + } + + if (n_begins > 1) { + + for (i = 0; i < n - 5; i++) { + + if (ut_memcmp(buf + i, "BEGIN", 5) == 0) { + + /* Erase the first BEGIN: */ + ut_memcpy(buf + i, " ", 5); + + break; + } + } + } + + sprintf(buf + n, "END;\n"); + + printf("SQL procedure to execute:\n%s\n", buf); + + ret = SQLAllocStmt(conn, &sql_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(sql_query, (UCHAR*)buf, ut_strlen(buf)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(sql_query); + + ut_a(ret == SQL_SUCCESS); + + sprintf(buf, "{P%s%lu ()}", cli_user_name, count); + + ret = SQLAllocStmt(conn, &sql_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(sql_query, (UCHAR*)buf, ut_strlen(buf)); + + ut_a(ret == SQL_SUCCESS); + + printf("Starting to execute the query\n"); + + oldtm = ut_clock(); + + ret = SQLExecute(sql_query); + + tm = ut_clock(); + + printf("Wall time for query %lu milliseconds\n\n", tm - oldtm); + + ut_a(ret == SQL_SUCCESS); + + goto loop; +} + +/******************************************************************** +Main test function. */ + +void +main(int argc, char* argv[]) +/*========================*/ +{ + ulint tm, oldtm; + FILE* inputfile; + + if (argc > 2) { + printf("Only one input file allowed\n"); + + os_process_exit(1); + + } else if (argc == 2) { + inputfile = fopen(argv[1], "r"); + + if (inputfile == NULL) { + printf( + "Error: could not open the inputfile whose name is %s!\n", + argv[1]); + os_process_exit(1); + } + } else { + inputfile = stdin; + } + + cli_boot("cli_init"); + + sync_init(); + + mem_init(mem_pool_size); + + oldtm = ut_clock(); + + isql(inputfile); + + tm = ut_clock(); + + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} diff --git a/innobase/btr/ts/makefile b/innobase/btr/ts/makefile new file mode 100644 index 00000000000..58364717472 --- /dev/null +++ b/innobase/btr/ts/makefile @@ -0,0 +1,16 @@ +include ..\..\makefile.i + +doall: tssrv tscli isql + +tssrv: ..\btr.lib tssrv.c + $(CCOM) $(CFL) -I.. -I..\.. ..\btr.lib ..\..\eval.lib ..\..\ibuf.lib ..\..\trx.lib ..\..\pars.lib ..\..\que.lib ..\..\lock.lib ..\..\row.lib ..\..\read.lib ..\..\srv.lib ..\..\com.lib ..\..\usr.lib ..\..\thr.lib ..\..\fut.lib ..\..\fsp.lib ..\..\page.lib ..\..\dyn.lib ..\..\mtr.lib ..\..\log.lib ..\..\rem.lib ..\..\fil.lib ..\..\buf.lib ..\..\dict.lib ..\..\data.lib ..\..\mach.lib ..\..\ha.lib ..\..\ut.lib ..\..\sync.lib ..\..\mem.lib ..\..\os.lib tssrv.c $(LFL) + +tscli: ..\btr.lib tscli.c + $(CCOM) $(CFL) -I.. -I..\.. ..\btr.lib ..\..\ib_odbc.lib ..\..\eval.lib ..\..\ibuf.lib ..\..\trx.lib ..\..\pars.lib ..\..\que.lib ..\..\lock.lib ..\..\row.lib ..\..\read.lib ..\..\srv.lib ..\..\com.lib ..\..\usr.lib ..\..\thr.lib ..\..\fut.lib ..\..\fsp.lib ..\..\page.lib ..\..\dyn.lib ..\..\mtr.lib ..\..\log.lib ..\..\rem.lib ..\..\fil.lib ..\..\buf.lib ..\..\dict.lib ..\..\data.lib ..\..\mach.lib ..\..\ha.lib ..\..\ut.lib ..\..\sync.lib ..\..\mem.lib ..\..\os.lib tscli.c $(LFL) + +isql: ..\btr.lib isql.c + $(CCOM) $(CFL) -I.. -I..\.. ..\btr.lib ..\..\ib_odbc.lib ..\..\eval.lib ..\..\ibuf.lib ..\..\trx.lib ..\..\pars.lib ..\..\que.lib ..\..\lock.lib ..\..\row.lib ..\..\read.lib ..\..\srv.lib ..\..\com.lib ..\..\usr.lib ..\..\thr.lib ..\..\fut.lib ..\..\fsp.lib ..\..\page.lib ..\..\dyn.lib ..\..\mtr.lib ..\..\log.lib ..\..\rem.lib ..\..\fil.lib ..\..\buf.lib ..\..\dict.lib ..\..\data.lib ..\..\mach.lib ..\..\ha.lib ..\..\ut.lib ..\..\sync.lib ..\..\mem.lib ..\..\os.lib isql.c $(LFL) + +tsrecv: ..\btr.lib tsrecv.c + $(CCOM) $(CFL) -I.. -I..\.. ..\btr.lib ..\..\ibuf.lib ..\..\trx.lib ..\..\pars.lib ..\..\que.lib ..\..\lock.lib ..\..\row.lib ..\..\read.lib ..\..\srv.lib ..\..\com.lib ..\..\usr.lib ..\..\thr.lib ..\..\fut.lib ..\..\fsp.lib ..\..\page.lib ..\..\dyn.lib ..\..\mtr.lib ..\..\log.lib ..\..\rem.lib ..\..\fil.lib ..\..\buf.lib ..\..\dict.lib ..\..\data.lib ..\..\mach.lib ..\..\ha.lib ..\..\ut.lib ..\..\sync.lib ..\..\mem.lib ..\..\os.lib tsrecv.c $(LFL) + diff --git a/innobase/btr/ts/trash/TSIT.C b/innobase/btr/ts/trash/TSIT.C new file mode 100644 index 00000000000..775d4036c6d --- /dev/null +++ b/innobase/btr/ts/trash/TSIT.C @@ -0,0 +1,483 @@ +/************************************************************************ +The test module for the record manager of MVB. + +(c) 1994 Heikki Tuuri + +Created 1/25/1994 Heikki Tuuri +*************************************************************************/ + + +#include "rm0phr.h" +#include "rm0lgr.h" +#include "ut0ut.h" +#include "buf0mem.h" +#include "rm0ipg.h" +#include "../it0it.h" +#include "../it0hi.h" +#include "../it0ads.h" + +byte buf[100]; +byte buf2[100]; +lint lintbuf[2048]; + +byte numbuf[6000]; +byte numlogrecbuf[100]; +phr_record_t* qs_table[100000]; + +lint qs_comp = 0; + +extern +void +test1(void); + +#ifdef NOT_DEFINED + +void +q_sort(lint low, lint up) +{ + phr_record_t* temp, *pivot; + lint i, j; + + + pivot = qs_table[(low + up) / 2]; + + i = low; + j = up; + + while (i < j) { + qs_comp++; + if (cmp_phr_compare(qs_table[i], pivot)<= 0) { + i++; + } else { + j--; + temp = qs_table[i]; + qs_table[i] = qs_table[j]; + qs_table[j] = temp; + } + } + + if (j == up) { + temp = qs_table[(low + up) / 2]; + qs_table[(low + up) / 2] = qs_table[up - 1]; + qs_table[up - 1] = temp; + j--; + } + + + if (j - low <= 1) { + /* do nothing */ + } else if (j - low == 2) { + qs_comp++; + if (cmp_phr_compare(qs_table[low], + qs_table[low + 1]) + <= 0) { + /* do nothing */ + } else { + temp = qs_table[low]; + qs_table[low] = qs_table[low + 1]; + qs_table[low + 1] = temp; + } + } else { + q_sort(low, j); + } + + if (up - j <= 1) { + /* do nothing */ + } else if (up - j == 2) { + qs_comp++; + if (cmp_phr_compare(qs_table[j], + qs_table[j + 1]) + <= 0) { + /* do nothing */ + } else { + temp = qs_table[j]; + qs_table[j] = qs_table[j + 1]; + qs_table[j + 1] = temp; + } + } else { + q_sort(j, up); + } +} + +#endif + +extern +void +test1(void) +{ + phr_record_t* physrec; + phr_record_t* rec1; + phr_record_t* rec2; + lgr_record_t* logrec; + lgrf_field_t* logfield; + lint len; + byte* str; + lint len2; + lint tm; + lint oldtm; + lint i, j, k, l, m; + bool b; + it_cur_cursor_t cursor; + ipg_cur_cursor_t* page_cursor; + ipg_page_t* page; + + byte c4, c3, c2, c1, c0; + lint rand, rnd1, rnd2; + byte* nb; + lgr_record_t* numlogrec; + byte* pgbuf; + mem_stream_t* stream; + lint tree1, tree2, tree3; + lint dummy1, dummy2; + + pgbuf = (byte*)lintbuf; + + stream = mem_stream_create(0); + + printf("-------------------------------------------\n"); + printf("TEST 1. Speed and basic tests.\n"); + + logrec = lgr_create_logical_record(stream, 2); + + nb = numbuf; + + c4 = '0'; + c3 = '0'; + for (c2 = '0'; c2 <= '9'; c2++) { + for (c1 = '0'; c1 <= '9'; c1++) { + for (c0 = '0'; c0 <= '9'; c0++) { + *nb = c4; nb++; + *nb = c3; nb++; + *nb = c2; nb++; + *nb = c1; nb++; + *nb = c0; nb++; + *nb = '\0'; nb++; + } + } + } + + numlogrec = lgr_create_logical_record(stream, 2); + + + tree1 = it_create_index_tree(); + + oldtm = ut_clock(); + + rand = 99900; + rnd1 = 67; + for (j = 0; j < 1; j++) { + for (i = 0 ; i < 100000; i++) { + + rand = (rand + 1) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); +/* + it_insert(tree1, numlogrec); +*/ + + + + it_cur_search_tree_to_nth_level(tree1, 1, numlogrec, + IPG_SE_L_GE, &cursor, &dummy1, &dummy2); + +/* + it_cur_set_to_first(tree1, &cursor); +*/ + + it_cur_insert_record(&cursor, numlogrec); + + } + } + tm = ut_clock(); + printf("Time for inserting %ld recs = %ld \n", i* j, tm - oldtm); + +/* it_print_tree(tree1, 10);*/ + hi_print_info(); + ads_print_info(); +/* + oldtm = ut_clock(); + + rand = 11113; + for (i = 0; i < 5000; i++) { + + rand = (rand + 57123) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); + + it_cur_search_tree_to_nth_level(tree1, 1, numlogrec, + IPG_SE_L_GE, &cursor, &dummy1, &dummy2); + + } + tm = ut_clock(); + printf("Time for searching %ld recs = %ld \n", i, tm - oldtm); +*/ + + it_cur_set_to_first(tree1, &cursor); + + rec1 = ipg_cur_get_record(it_cur_get_page_cursor(&cursor)); + + for (i = 0;; i++) { + it_cur_move_to_next(&cursor); + if (it_cur_end_of_level(&cursor)) { + break; + } + rec2 = ipg_cur_get_record(it_cur_get_page_cursor(&cursor)); + ut_a(cmp_phr_compare(rec1, rec2) == -1); + rec1 = rec2; + } + + printf("tree1 checked for right sorted order!\n"); + +#ifdef not_defined + + oldtm = ut_clock(); + + for (j = 0; j < 1; j++) { + rand = 11113; + for (i = 0; i < 3000; i++) { + + rand = (rand + 57123) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); + + physrec = hi_search(numlogrec); + + ut_a(physrec); + } + + } + ut_a(physrec); + tm = ut_clock(); + printf("Time for hi_search %ld recs = %ld \n", i * j, + tm - oldtm); + + + + oldtm = ut_clock(); + + for (i = 0; i < 100000; i++) { +/* j += lgr_fold(numlogrec, -1, -1);*/ +/* b += phr_lgr_equal(physrec, numlogrec, -1);*/ + k += ut_hash_lint(j, HI_TABLE_SIZE); + } + + +/* ut_a(b);*/ + tm = ut_clock(); + printf("Time for fold + equal %ld recs %s = %ld \n", i, physrec, + tm - oldtm); + + printf("%ld %ld %ld\n", j, b, k); + + hi_print_info(); + + tree2 = it_create_index_tree(); + + rand = 90000; + for (i = 0; i < 300; i++) { + + rand = (rand + 1) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); + + it_cur_search_tree_to_nth_level(tree2, 1, numlogrec, + IPG_SE_L_GE, &cursor); + + it_cur_insert_record(&cursor, numlogrec); + + } + + oldtm = ut_clock(); + + rand = 10000; + for (i = 0; i < 3000; i++) { + + rand = (rand + 1) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); + + it_cur_search_tree_to_nth_level(tree2, 1, numlogrec, + IPG_SE_L_GE, &cursor); + + it_cur_insert_record(&cursor, numlogrec); + + } + tm = ut_clock(); + printf("Time for inserting sequentially %ld recs = %ld \n", + i, tm - oldtm); + + +/* it_print_tree(tree2, 10); */ + + + tree3 = it_create_index_tree(); + + rand = 0; + for (i = 0; i < 300; i++) { + + rand = (rand + 1) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); + + it_cur_search_tree_to_nth_level(tree3, 1, numlogrec, + IPG_SE_L_GE, &cursor); + + it_cur_insert_record(&cursor, numlogrec); + + } + + oldtm = ut_clock(); + + rand = 100000; + for (i = 0; i < 3000; i++) { + + rand = (rand - 1) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); + + it_cur_search_tree_to_nth_level(tree3, 1, numlogrec, + IPG_SE_L_GE, &cursor); + + it_cur_insert_record(&cursor, numlogrec); + + } + tm = ut_clock(); + printf("Time for inserting sequentially downw. %ld recs = %ld \n", + i, tm - oldtm); + + +/* it_print_tree(tree3, 10); */ + +#endif + +} + +#ifdef NOT_DEFINED + +/* Test of quicksort */ +void +test2(void) +{ + mem_stream_t* stream; + byte* stbuf; + lgrf_field_t* logfield; + lint tm; + lint oldtm; + lint i, j, k, l, m; + lint rand; + lgr_record_t* numlogrec; + phr_record_t* ph_rec; + + stream = mem_stream_create(1000); + + numlogrec = lgr_create_logical_record(stream, 2); + + oldtm = ut_clock(); + + rand = 11113; + for (i = 0; i < 50000; i++) { + stbuf = mem_stream_alloc(stream, 30); + + rand = (rand + 57123) % 100000; + + logfield = lgr_get_nth_field(numlogrec, 0); + lgrf_set_data(logfield, numbuf + 6 * (rand / 300)); + lgrf_set_len(logfield, 6); + + logfield = lgr_get_nth_field(numlogrec, 1); + lgrf_set_data(logfield, numbuf + 6 * (rand % 300)); + lgrf_set_len(logfield, 6); + + ph_rec = phr_create_physical_record(stbuf, 30, numlogrec); + + qs_table[i] = ph_rec; + + } + tm = ut_clock(); + printf("Time for inserting %ld recs to mem stream = %ld \n", + i, tm - oldtm); + + + oldtm = ut_clock(); + + q_sort(0, 50000); + + tm = ut_clock(); + printf("Time for quicksort of %ld recs = %ld, comps: %ld \n", + i, tm - oldtm, qs_comp); + + + + for (i = 1; i < 49999; i++) { + ut_a(-1 == + cmp_phr_compare(qs_table[i], qs_table[i+1] + )); + } + tm = ut_clock(); + + + oldtm = ut_clock(); + for (i = 1; i < 50000; i++) { + k += cmp_phr_compare(qs_table[i & 0xF], + qs_table[5]); + } + tm = ut_clock(); + printf("%ld\n", k); + + printf("Time for cmp of %ld ph_recs = %ld \n", + i, tm - oldtm); + + mem_stream_free(stream); + +} +#endif + +void +main(void) +{ + test1(); +/* test2(); */ +} + diff --git a/innobase/btr/ts/trash/tsbtrold5.c b/innobase/btr/ts/trash/tsbtrold5.c new file mode 100644 index 00000000000..370cf0b14bd --- /dev/null +++ b/innobase/btr/ts/trash/tsbtrold5.c @@ -0,0 +1,798 @@ +/************************************************************************ +The test for the index tree + +(c) 1994-1996 Innobase Oy + +Created 2/16/1996 Heikki Tuuri +*************************************************************************/ + +#include "sync0sync.h" +#include "ut0mem.h" +#include "mem0mem.h" +#include "data0data.h" +#include "data0type.h" +#include "dict0dict.h" +#include "buf0buf.h" +#include "os0file.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 "..\btr0btr.h" +#include "..\btr0cur.h" +#include "..\btr0pcur.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 1 +#define N_FILES 2 +#define FILE_SIZE 1000 /* must be > 512 */ +#define POOL_SIZE 1000 +#define COUNTER_OFFSET 1500 + +#define LOOP_SIZE 150 +#define N_THREADS 5 + + +ulint zero = 0; + +buf_block_t* bl_arr[POOL_SIZE]; + +/************************************************************************ +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++) { + ret = fil_aio_wait(segment, &mess); + ut_a(ret); + + buf_page_io_complete((buf_block_t*)mess); + + 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[5]; + os_thread_id_t id[5]; + + printf("--------------------------------------------------------\n"); + printf("Create or open database files\n"); + + strcpy(name, "j:\\tsfile00"); + + for (k = 0; k < N_SPACES; k++) { + for (i = 0; i < N_FILES; i++) { + + name[9] = (char)((ulint)'0' + k); + name[10] = (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); + } + + 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); + + for (i = 0; i < 5; i++) { + n[i] = i; + + thr[i] = os_thread_create(handler_thread, n + i, id + i); + } +} + +/************************************************************************ +Inits space header of space 0. */ + +void +init_space(void) +/*============*/ +{ + mtr_t mtr; + + printf("Init space header\n"); + + mtr_start(&mtr); + + fsp_header_init(0, FILE_SIZE * N_FILES, &mtr); + + mtr_commit(&mtr); +} + +/********************************************************************* +Test for index page. */ + +void +test1(void) +/*=======*/ +{ + dtuple_t* tuple; + mem_heap_t* heap; + ulint rnd = 0; + dict_index_t* index; + dict_table_t* table; + dict_tree_t* tree; + mtr_t mtr; + byte buf[8]; + ulint i; + ulint tm, oldtm; + btr_pcur_t cursor; + + printf("-------------------------------------------------\n"); + printf("TEST 1. Basic test\n"); + + heap = mem_heap_create(0); + + table = dict_mem_table_create("TS_TABLE1", 2); + + 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_table_add_to_cache(table); + + index = dict_mem_index_create("TS_TABLE1", "IND1", 0, 2, 0); + + dict_mem_index_add_field(index, "COL1", 0); + dict_mem_index_add_field(index, "COL2", 0); + + dict_index_add_to_cache(index); + + index = dict_index_get("TS_TABLE1", "IND1"); + ut_a(index); + + tree = dict_index_get_tree(index); + + tuple = dtuple_create(heap, 3); + + mtr_start(&mtr); + + btr_root_create(tree, 0, &mtr); + + mtr_commit(&mtr); + + mtr_start(&mtr); + + dtuple_gen_test_tuple3(tuple, 0, buf); + btr_insert(tree, tuple, &mtr); + + mtr_commit(&mtr); + + rnd = 90000; + + oldtm = ut_clock(); + + for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { + + mtr_start(&mtr); + + if (i == 77000) { + rnd = rnd % 200000; + } + + rnd = (rnd + 15675751) % 200000; + + dtuple_gen_test_tuple3(tuple, rnd, buf); + + btr_insert(tree, tuple, &mtr); + + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + + rnd = 90000; + + oldtm = ut_clock(); + + for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { + + mtr_start(&mtr); + + if (i == 50000) { + rnd = rnd % 200000; + } + + rnd = (rnd + 595659561) % 200000; + + dtuple_gen_test_tuple3(tuple, rnd, buf); + + btr_pcur_open(tree, tuple, PAGE_CUR_GE, + BTR_SEARCH_LEAF, &cursor, &mtr); + + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + + rnd = 0; + + oldtm = ut_clock(); + + for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { + + mtr_start(&mtr); + + rnd = (rnd + 35608971) % 200000 + 1; + + dtuple_gen_test_tuple3(tuple, rnd, buf); + + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + +/* btr_print_tree(tree, 3); */ + + mem_heap_free(heap); +} + + +#ifdef notdefined + + mtr_start(&mtr); + + block = buf_page_create(0, 5, &mtr); + buf_page_x_lock(block, &mtr); + + frame = buf_block_get_frame(block); + + page = page_create(frame, &mtr); + + for (i = 0; i < 512; i++) { + + rnd = (rnd + 534671) % 512; + + if (i % 27 == 0) { + ut_a(page_validate(page, index)); + } + + dtuple_gen_test_tuple(tuple, rnd); + +/* dtuple_print(tuple);*/ + + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + + ut_a(rec); + + rec_validate(rec); +/* page_print_list(page, 151); */ + } + +/* page_print_list(page, 151); */ + + ut_a(page_validate(page, index)); + ut_a(page_get_n_recs(page) == 512); + + for (i = 0; i < 512; i++) { + + rnd = (rnd + 7771) % 512; + + if (i % 27 == 0) { + ut_a(page_validate(page, index)); + } + + dtuple_gen_test_tuple(tuple, rnd); + +/* dtuple_print(tuple);*/ + + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + page_cur_delete_rec(&cursor, &mtr); + + ut_a(rec); + + rec_validate(rec); +/* page_print_list(page, 151); */ + } + + ut_a(page_get_n_recs(page) == 0); + + ut_a(page_validate(page, index)); + page = page_create(frame, &mtr); + + rnd = 311; + + for (i = 0; i < 512; i++) { + + rnd = (rnd + 1) % 512; + + if (i % 27 == 0) { + ut_a(page_validate(page, index)); + } + + dtuple_gen_test_tuple(tuple, rnd); + +/* dtuple_print(tuple);*/ + + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + + ut_a(rec); + + rec_validate(rec); +/* page_print_list(page, 151); */ + } + + ut_a(page_validate(page, index)); + ut_a(page_get_n_recs(page) == 512); + + rnd = 217; + + for (i = 0; i < 512; i++) { + + rnd = (rnd + 1) % 512; + + if (i % 27 == 0) { + ut_a(page_validate(page, index)); + } + + dtuple_gen_test_tuple(tuple, rnd); + +/* dtuple_print(tuple);*/ + + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + page_cur_delete_rec(&cursor, &mtr); + + ut_a(rec); + + rec_validate(rec); +/* page_print_list(page, 151); */ + } + + ut_a(page_validate(page, index)); + ut_a(page_get_n_recs(page) == 0); + page = page_create(frame, &mtr); + + rnd = 291; + + for (i = 0; i < 512; i++) { + + rnd = (rnd - 1) % 512; + + if (i % 27 == 0) { + ut_a(page_validate(page, index)); + } + + dtuple_gen_test_tuple(tuple, rnd); + +/* dtuple_print(tuple);*/ + + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + + ut_a(rec); + + rec_validate(rec); +/* page_print_list(page, 151); */ + } + + ut_a(page_validate(page, index)); + ut_a(page_get_n_recs(page) == 512); + + rnd = 277; + + for (i = 0; i < 512; i++) { + + rnd = (rnd - 1) % 512; + + if (i % 27 == 0) { + ut_a(page_validate(page, index)); + } + + dtuple_gen_test_tuple(tuple, rnd); + +/* dtuple_print(tuple);*/ + + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + page_cur_delete_rec(&cursor, &mtr); + + ut_a(rec); + + rec_validate(rec); +/* page_print_list(page, 151); */ + } + + ut_a(page_validate(page, index)); + ut_a(page_get_n_recs(page) == 0); + + mtr_commit(&mtr); + mem_heap_free(heap); +} + +/********************************************************************* +Test for index page. */ + +void +test2(void) +/*=======*/ +{ + page_t* page; + dtuple_t* tuple; + mem_heap_t* heap; + ulint i, j; + ulint rnd = 0; + rec_t* rec; + page_cur_t cursor; + dict_index_t* index; + dict_table_t* table; + buf_block_t* block; + buf_frame_t* frame; + ulint tm, oldtm; + byte buf[8]; + mtr_t mtr; + + printf("-------------------------------------------------\n"); + printf("TEST 2. Speed test\n"); + + oldtm = ut_clock(); + + for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { + ut_memcpy(bigbuf, bigbuf + 800, 800); + } + + tm = ut_clock(); + printf("Wall time for %lu mem copys of 800 bytes %lu millisecs\n", + i, tm - oldtm); + + oldtm = ut_clock(); + + rnd = 0; + for (i = 0; i < 1000 * UNIV_DBC * UNIV_DBC; i++) { + ut_memcpy(bigbuf + rnd, bigbuf + rnd + 800, 800); + rnd += 1600; + if (rnd > 995000) { + rnd = 0; + } + } + + tm = ut_clock(); + printf("Wall time for %lu mem copys of 800 bytes %lu millisecs\n", + i, tm - oldtm); + + heap = mem_heap_create(0); + + table = dict_table_create("TS_TABLE2", 2); + + dict_table_add_col(table, "COL1", DATA_VARCHAR, DATA_ENGLISH, 10, 0); + dict_table_add_col(table, "COL2", DATA_VARCHAR, DATA_ENGLISH, 10, 0); + + ut_a(0 == dict_table_publish(table)); + + index = dict_index_create("TS_TABLE2", "IND2", 0, 2, 0); + + dict_index_add_field(index, "COL1", 0); + dict_index_add_field(index, "COL2", 0); + + ut_a(0 == dict_index_publish(index)); + + index = dict_index_get("TS_TABLE2", "IND2"); + ut_a(index); + + tuple = dtuple_create(heap, 2); + + oldtm = ut_clock(); + + rnd = 677; + for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { + + mtr_start(&mtr); + + block = buf_page_create(0, 5, &mtr); + buf_page_x_lock(block, &mtr); + + frame = buf_block_get_frame(block); + + page = page_create(frame, &mtr); + + for (j = 0; j < 250; j++) { + rnd = (rnd + 54841) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + ut_a(rec); + } + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf("Wall time for insertion of %lu recs %lu milliseconds\n", + i * j, tm - oldtm); + + mtr_start(&mtr); + + block = buf_page_get(0, 5, &mtr); + buf_page_s_lock(block, &mtr); + + page = buf_block_get_frame(block); + ut_a(page_validate(page, index)); + mtr_commit(&mtr); + + oldtm = ut_clock(); + + rnd = 677; + for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { + mtr_start(&mtr); + + block = buf_page_create(0, 5, &mtr); + buf_page_x_lock(block, &mtr); + + frame = buf_block_get_frame(block); + + page = page_create(frame, &mtr); + + for (j = 0; j < 250; j++) { + rnd = (rnd + 54841) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + } + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf( + "Wall time for %lu empty loops with page create %lu milliseconds\n", + i * j, tm - oldtm); + + oldtm = ut_clock(); + + for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { + + mtr_start(&mtr); + + block = buf_page_create(0, 5, &mtr); + buf_page_x_lock(block, &mtr); + + frame = buf_block_get_frame(block); + + page = page_create(frame, &mtr); + + rnd = 100; + for (j = 0; j < 250; j++) { + rnd = (rnd + 1) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + ut_a(rec); + } + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf( + "Wall time for sequential insertion of %lu recs %lu milliseconds\n", + i * j, tm - oldtm); + + + oldtm = ut_clock(); + + for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { + mtr_start(&mtr); + + block = buf_page_create(0, 5, &mtr); + buf_page_x_lock(block, &mtr); + + frame = buf_block_get_frame(block); + + page = page_create(frame, &mtr); + + rnd = 500; + for (j = 0; j < 250; j++) { + rnd = (rnd - 1) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + ut_a(rec); + } + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf( + "Wall time for descend. seq. insertion of %lu recs %lu milliseconds\n", + i * j, tm - oldtm); + + oldtm = ut_clock(); + + for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { + mtr_start(&mtr); + + block = buf_page_create(0, 5, &mtr); + buf_page_x_lock(block, &mtr); + + frame = buf_block_get_frame(block); + + page = page_create(frame, &mtr); + + rnd = 677; + + for (j = 0; j < 250; j++) { + rnd = (rnd + 54841) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + ut_a(rec); + } + + rnd = 677; + for (j = 0; j < 250; j++) { + rnd = (rnd + 54841) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + page_cur_delete_rec(&cursor, &mtr); + } + ut_a(page_get_n_recs(page) == 0); + + mtr_commit(&mtr); + } + + tm = ut_clock(); + printf("Wall time for insert and delete of %lu recs %lu milliseconds\n", + i * j, tm - oldtm); + + mtr_start(&mtr); + + block = buf_page_create(0, 5, &mtr); + buf_page_x_lock(block, &mtr); + + frame = buf_block_get_frame(block); + + page = page_create(frame, &mtr); + + rnd = 677; + + for (j = 0; j < 250; j++) { + rnd = (rnd + 54841) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + + rec = page_cur_insert_rec(&cursor, tuple, NULL, &mtr); + ut_a(rec); + } + ut_a(page_validate(page, index)); + mtr_print(&mtr); + + oldtm = ut_clock(); + + for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { + rnd = 677; + for (j = 0; j < 250; j++) { + rnd = (rnd + 54841) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + page_cur_search(page, tuple, PAGE_CUR_G, &cursor); + } + } + + tm = ut_clock(); + printf("Wall time for search of %lu recs %lu milliseconds\n", + i * j, tm - oldtm); + + oldtm = ut_clock(); + + for (i = 0; i < 4 * UNIV_DBC * UNIV_DBC; i++) { + rnd = 677; + for (j = 0; j < 250; j++) { + rnd = (rnd + 54841) % 1000; + dtuple_gen_test_tuple2(tuple, rnd, buf); + } + } + + tm = ut_clock(); + printf("Wall time for %lu empty loops %lu milliseconds\n", + i * j, tm - oldtm); + mtr_commit(&mtr); +} + +#endif + +/******************************************************************** +Main test function. */ + +void +main(void) +/*======*/ +{ + ulint tm, oldtm; + + sync_init(); + mem_init(); + os_aio_init(160, 5); + fil_init(25); + buf_pool_init(POOL_SIZE, POOL_SIZE); + dict_init(); + fsp_init(); + log_init(); + + create_files(); + + init_space(); + + oldtm = ut_clock(); + + ut_rnd_set_seed(19); + + test1(); + +/* mem_print_info(); */ + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} diff --git a/innobase/btr/ts/trash/tscli.c b/innobase/btr/ts/trash/tscli.c new file mode 100644 index 00000000000..622da894e02 --- /dev/null +++ b/innobase/btr/ts/trash/tscli.c @@ -0,0 +1,2263 @@ +/************************************************************************ +Test for the client + +(c) 1996-1997 Innobase Oy + +Created 2/16/1996 Heikki Tuuri +*************************************************************************/ + +#include "ib_odbc.h" + +/********************************************************************* +Test for TPC-C. */ + +ulint +test_c( +/*===*/ + void* arg) +{ + HSTMT* query; + HSTMT* commit_query; + HSTMT* new_order_query; + HSTMT* payment_query; + HSTMT* order_status_query; + HSTMT* delivery_query; + HSTMT* stock_level_query; + HSTMT* print_query; + ulint tm, oldtm; + char* str; + char* str1; + char* str2; + char* str3; + char* str4; + char* str5; + char* str6; + ulint i; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST. CREATE TABLES FOR TPC-C\n"); + + /*------------------------------------------------------*/ + + str1 = + +" PROCEDURE CREATE_TABLES () IS" +" BEGIN" +" CREATE TABLE WAREHOUSE (W_ID CHAR, W_NAME CHAR," +" W_STREET_1 CHAR, W_STREET_2 CHAR," +" W_CITY CHAR," +" W_STATE CHAR, W_ZIP CHAR," +" W_TAX INT," +" W_YTD_HIGH INT," +" W_YTD INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX W_IND ON WAREHOUSE (W_ID);" +"" +" CREATE TABLE DISTRICT (D_ID CHAR, D_W_ID CHAR," +" D_NAME CHAR," +" D_STREET_1 CHAR, D_STREET_2 CHAR," +" D_CITY CHAR," +" D_STATE CHAR, D_ZIP CHAR," +" D_TAX INT," +" D_YTD_HIGH INT," +" D_YTD INT," +" D_NEXT_O_ID INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX D_IND ON DISTRICT (D_W_ID, D_ID);" +"" +" CREATE TABLE CUSTOMER (C_ID CHAR, C_D_ID CHAR, C_W_ID CHAR," +" C_FIRST CHAR, C_MIDDLE CHAR," +" C_LAST CHAR," +" C_STREET_1 CHAR, C_STREET_2 CHAR," +" C_CITY CHAR," +" C_STATE CHAR, C_ZIP CHAR," +" C_PHONE CHAR," +" C_SINCE_TIME INT," +" C_SINCE INT," +" C_CREDIT CHAR," +" C_CREDIT_LIM_HIGH INT," +" C_CREDIT_LIM INT," +" C_DISCOUNT INT," +" C_BALANCE_HIGH INT," +" C_BALANCE INT," +" C_YTD_PAYMENT_HIGH INT," +" C_YTD_PAYMENT INT," +" C_PAYMENT_CNT INT," +" C_DELIVERY_CNT INT," +" C_DATA CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX C_IND ON CUSTOMER (C_W_ID, C_D_ID," +" C_ID);" +"" +" CREATE INDEX C_LAST_IND ON CUSTOMER (C_W_ID, C_D_ID, C_LAST," +" C_FIRST);" +"" +" CREATE TABLE HISTORY (H_C_ID CHAR, H_C_D_ID CHAR, H_C_W_ID CHAR," +" H_D_ID CHAR, H_W_ID CHAR," +" H_DATE INT," +" H_AMOUNT INT," +" H_DATA CHAR);" +"" +" CREATE CLUSTERED INDEX H_IND ON HISTORY (H_W_ID);" +"" +" CREATE TABLE NEW_ORDER (NO_O_ID INT," +" NO_D_ID CHAR," +" NO_W_ID CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX NO_IND ON NEW_ORDER (NO_W_ID, NO_D_ID," +" NO_O_ID);" + ; + + str2 = + +" CREATE TABLE ORDERS (O_ID INT, O_D_ID CHAR, O_W_ID CHAR," +" O_C_ID CHAR," +" O_ENTRY_D INT," +" O_CARRIER_ID INT," +" O_OL_CNT INT," +" O_ALL_LOCAL CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX O_IND ON ORDERS (O_W_ID, O_D_ID," +" O_ID);" +" CREATE INDEX O_C_IND ON ORDERS (O_W_ID, O_D_ID, O_C_ID);" +"" +" CREATE TABLE ORDER_LINE (OL_O_ID INT, OL_D_ID CHAR, OL_W_ID CHAR," +" OL_NUMBER CHAR," +" OL_I_ID CHAR," +" OL_SUPPLY_W_ID CHAR," +" OL_DELIVERY_D INT," +" OL_QUANTITY INT," +" OL_AMOUNT INT," +" OL_DIST_INFO CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX OL_IND ON ORDER_LINE" +" (OL_W_ID, OL_D_ID, OL_O_ID, OL_NUMBER);" +"" +" CREATE TABLE ITEM (I_ID CHAR, I_IM_ID CHAR, I_NAME CHAR," +" I_PRICE INT," +" I_DATA CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX I_IND ON ITEM (I_ID);" +"" +" CREATE TABLE STOCK (S_I_ID CHAR," +" S_W_ID CHAR," +" S_QUANTITY INT," +" S_DIST_01 CHAR," +" S_DIST_02 CHAR," +" S_DIST_03 CHAR," +" S_DIST_04 CHAR," +" S_DIST_05 CHAR," +" S_DIST_06 CHAR," +" S_DIST_07 CHAR," +" S_DIST_08 CHAR," +" S_DIST_09 CHAR," +" S_DIST_10 CHAR," +" S_YTD INT," +" S_ORDER_CNT INT," +" S_REMOTE_CNT INT," +" S_DATA CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX S_IND ON STOCK (S_W_ID, S_I_ID);" +" END;" + ; + + str = ut_str_catenate(str1, str2); + + query = pars_sql(str); + + mem_free(str); + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + + /*-----------------------------------------------------------*/ + printf("\n\nPopulate TPC-C tables\n\n"); + + str1 = + +" PROCEDURE POPULATE_TABLES () IS" +"" +" i INT;" +" j INT;" +" k INT;" +" t INT;" +" string CHAR;" +" rnd1 INT;" +" rnd2 INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +"" +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 200;" +"" +" PRINTF('Starting to populate ITEMs');" +"" +" FOR i IN 1 .. n_items LOOP" +" rnd1 := RND(26, 50);" +" string := RND_STR(rnd1);" +"" +" IF (RND(0, 9) = 0) THEN" +" rnd2 := RND(0, rnd1 - 8);" +" REPLSTR(string, 'ORIGINAL', rnd2, 8);" +" COMMIT WORK;" +" END IF;" +"" +" INSERT INTO ITEM VALUES (TO_BINARY(i, 3)," +" TO_BINARY(RND(1, 10000), 3)," +" RND_STR(RND(14, 24))," +" RND(100, 10000)," +" string);" +" END LOOP;" +"" +" FOR i IN 1 .. n_warehouses LOOP" +" PRINTF('Starting to populate warehouse number ', i);" +" INSERT INTO WAREHOUSE VALUES (TO_BINARY(i, 2)," +" RND_STR(RND(6, 10))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(2)," +" CONCAT(SUBSTR(TO_CHAR(RND(0, 9999))," +" 6, 4)," +" '11111')," +" RND(0, 2000)," +" 0," +" 0);" +" FOR j IN 1 .. n_items LOOP" +"" +" rnd1 := RND(26, 50);" +" string := RND_STR(rnd1);" +"" +" IF (RND(0, 9) = 0) THEN" +" rnd2 := RND(0, rnd1 - 8);" +" REPLSTR(string, 'ORIGINAL', rnd2, 8);" +" COMMIT WORK;" +" END IF; " +"" +" INSERT INTO STOCK VALUES (TO_BINARY(j, 3)," +" TO_BINARY(i, 2)," +" RND(10, 100)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" 0, 0, 0," +" string);" +" END LOOP;" + ; + + str2 = +" FOR j IN 1 .. n_districts LOOP" +"" +" COMMIT WORK;" +" PRINTF('Starting to populate district number ', j);" +" INSERT INTO DISTRICT VALUES (TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" RND_STR(RND(6, 10))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(2)," +" CONCAT(SUBSTR(" +" TO_CHAR(RND(0, 9999))," +" 6, 4)," +" '11111')," +" RND(0, 2000)," +" 0," +" 0," +" 3001);" +"" +" FOR k IN 1 .. n_customers LOOP" +"" +" string := 'GC';" +"" +" IF (RND(0, 9) = 7) THEN" +" COMMIT WORK;" +" string := 'BC';" +" END IF;" +" " +" INSERT INTO CUSTOMER VALUES (" +" TO_BINARY(k, 3)," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" RND_STR(RND(8, 16))," +" 'OE'," +" CONCAT('NAME'," +" TO_CHAR(k / 3))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(2)," +" CONCAT(SUBSTR(" +" TO_CHAR(RND(0, 9999))," +" 6, 4)," +" '11111')," +" RND_STR(16)," +" SYSDATE(), 0," +" string," +" 0, 5000000," +" RND(0, 5000)," +" 0, 0, 0, 0, 0, 0," +" RND_STR(RND(300, 500)));" + ; + + str3 = +" INSERT INTO HISTORY VALUES (" +" TO_BINARY(k, 3)," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" SYSDATE()," +" 1000," +" RND_STR(RND(12, 24)));" +"" +" rnd1 := RND(5, 15);" +"" +" INSERT INTO ORDERS VALUES (" +" k," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" TO_BINARY(k, 3)," +" SYSDATE()," +" RND(1, 10)," +" rnd1," +" '1');" +"" +" FOR t IN 1 .. rnd1 LOOP" +" INSERT INTO ORDER_LINE VALUES (" +" k," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" TO_BINARY(t, 1)," +" TO_BINARY(" +" RND(0, n_items - 1)," +" 3)," +" TO_BINARY(i, 2)," +" SYSDATE()," +" RND(0, 99)," +" RND(0, 9999)," +" RND_STR(24));" +" END LOOP;" +" END LOOP;" +" " +" FOR k IN (2 * n_customers) / 3 .. n_customers LOOP" +" " +" INSERT INTO NEW_ORDER VALUES (" +" k," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2));" +" END LOOP;" +" END LOOP;" +" END LOOP; " +" " +" COMMIT WORK;" +" END;" + ; + + str4 = ut_str_catenate(str1, str2); + str = ut_str_catenate(str4, str3); + + query = pars_sql(str); + + mem_free(str); + mem_free(str4); + + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE PRINT_TABLES () IS" +" BEGIN" +"" +" /* PRINTF('Printing ITEM table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM ITEM;" +"" +" PRINTF('Printing WAREHOUSE table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM WAREHOUSE;" +"" +" PRINTF('Printing STOCK table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM STOCK;" +"" +" PRINTF('Printing DISTRICT table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM DISTRICT;" +"" +" PRINTF('Printing CUSTOMER table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM CUSTOMER;" +"" +" PRINTF('Printing HISTORY table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM HISTORY;" +"" +" PRINTF('Printing ORDERS table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM ORDERS;" +"" +" PRINTF('Printing ORDER_LINE table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM ORDER_LINE" +" WHERE OL_O_ID >= 3000; */" +"" +" PRINTF('Printing NEW_ORDER table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM NEW_ORDER;" +"" +" COMMIT WORK;" +" END;" + ; + + print_query = pars_sql(str); + + /*-----------------------------------------------------------*/ + commit_query = pars_sql( + +" PROCEDURE COMMIT_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ); + + + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE NEW_ORDER () IS" +"" +" i INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" w_tax INT;" +" c_w_id CHAR;" +" c_d_id CHAR;" +" c_id CHAR;" +" c_discount INT;" +" c_last CHAR;" +" c_credit CHAR;" +" d_tax INT;" +" o_id INT;" +" o_ol_cnt INT;" +" ol_i_id CHAR;" +" o_entry_d INT;" +" o_all_local CHAR;" +" i_price INT;" +" i_name CHAR;" +" i_data CHAR;" +" s_quantity INT;" +" s_data CHAR;" +" s_dist_01 CHAR;" +" s_dist_02 CHAR;" +" s_dist_03 CHAR;" +" s_dist_04 CHAR;" +" s_dist_05 CHAR;" +" s_dist_06 CHAR;" +" s_dist_07 CHAR;" +" s_dist_08 CHAR;" +" s_dist_09 CHAR;" +" s_dist_10 CHAR;" +" bg CHAR;" +" ol_quantity INT;" +" ol_amount INT;" +" ol_supply_w_id CHAR;" +" ol_dist_info CHAR;" +" total INT;" +"" +" DECLARE CURSOR district_cursor IS" +" SELECT D_NEXT_O_ID, D_TAX" +" FROM DISTRICT" +" WHERE D_ID = c_d_id AND D_W_ID = c_w_id" +" FOR UPDATE;" +"" +" DECLARE CURSOR stock_cursor IS" +" SELECT S_QUANTITY, S_DATA," +" S_DIST_01, S_DIST_02, S_DIST_03, S_DIST_04," +" S_DIST_05, S_DIST_06, S_DIST_07, S_DIST_08," +" S_DIST_09, S_DIST_10" +" FROM STOCK" +" WHERE S_W_ID = ol_supply_w_id AND S_I_ID = ol_i_id" +" FOR UPDATE;" + ; + str2 = + +" BEGIN" +" " +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 200;" +" " +" c_w_id := TO_BINARY(RND(1, n_warehouses), 2);" +" c_d_id := TO_BINARY(RND(1, n_districts) + 47, 1);" +" c_id := TO_BINARY(RND(1, n_customers), 3);" +"" +" o_ol_cnt := RND(5, 15);" +" o_all_local := '1';" +" bg := 'GGGGGGGGGGGGGGG';" +" total := 0;" +" " +" SELECT W_TAX INTO w_tax" +" FROM WAREHOUSE" +" WHERE W_ID = c_w_id;" +"" +" OPEN district_cursor;" +"" +" FETCH district_cursor INTO o_id, d_tax;" +"" +" /* PRINTF('C-warehouse id ', BINARY_TO_NUMBER(c_w_id)," +" ' C-district id ', c_d_id," +" ' order id ', o_id, ' linecount ', o_ol_cnt); */" +"" +" UPDATE DISTRICT SET D_NEXT_O_ID = o_id + 1" +" WHERE CURRENT OF district_cursor;" +"" +" CLOSE district_cursor;" +"" +" SELECT C_DISCOUNT, C_LAST, C_CREDIT INTO c_discount, c_last, c_credit" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id AND C_ID = c_id;" +"" + ; + str3 = + +" FOR i IN 1 .. o_ol_cnt LOOP" +"" +" ol_i_id := TO_BINARY(RND(1, n_items), 3);" +"" +" ol_supply_w_id := c_w_id;" +"" +" ol_quantity := RND(1, 10);" +"" +" SELECT I_PRICE, I_NAME, I_DATA INTO i_price, i_name, i_data" +" FROM ITEM" +" WHERE I_ID = ol_i_id;" +"" +" IF (SQL % NOTFOUND) THEN" +" PRINTF('Rolling back');" +" ROLLBACK WORK;" +"" +" RETURN;" +" END IF;" +"" +" OPEN stock_cursor;" +"" +" FETCH stock_cursor INTO s_quantity, s_data," +" s_dist_01, s_dist_02, s_dist_03," +" s_dist_04, s_dist_05, s_dist_06," +" s_dist_07, s_dist_08, s_dist_09," +" s_dist_10;" +"" +" IF (s_quantity >= ol_quantity + 10) THEN" +" s_quantity := s_quantity - ol_quantity;" +" ELSE" +" s_quantity := (s_quantity + 91) - ol_quantity;" +" END IF;" +"" +" UPDATE STOCK SET S_QUANTITY = s_quantity," +" S_YTD = S_YTD + ol_quantity," +" S_ORDER_CNT = S_ORDER_CNT + 1" +" WHERE CURRENT OF stock_cursor;" +"" +" IF (ol_supply_w_id <> c_w_id) THEN" +"" +" o_all_local := '0';" +" PRINTF('Remote order '," +" BINARY_TO_NUMBER(ol_supply_w_id), ' '," +" BINARY_TO_NUMBER(c_w_id));" +"" +" UPDATE STOCK SET S_REMOTE_CNT = S_REMOTE_CNT + 1" +" WHERE CURRENT OF stock_cursor;" +" END IF;" +"" +" CLOSE stock_cursor;" +"" +" IF ((INSTR(i_data, 'ORIGINAL') > 0)" +" OR (INSTR(s_data, 'ORIGINAL') > 0)) THEN" +" REPLSTR(bg, 'B', i - 1, 1);" +" END IF;" +"" +" ol_amount := ol_quantity * i_price;" +"" +" total := total + ol_amount;" + ; + str4 = +" IF (c_d_id = '0') THEN" +" ol_dist_info := s_dist_01;" +" ELSIF (c_d_id = '1') THEN" +" ol_dist_info := s_dist_02;" +" ELSIF (c_d_id = '2') THEN" +" ol_dist_info := s_dist_03;" +" ELSIF (c_d_id = '3') THEN" +" ol_dist_info := s_dist_04;" +" ELSIF (c_d_id = '4') THEN" +" ol_dist_info := s_dist_05;" +" ELSIF (c_d_id = '5') THEN" +" ol_dist_info := s_dist_06;" +" ELSIF (c_d_id = '6') THEN" +" ol_dist_info := s_dist_07;" +" ELSIF (c_d_id = '7') THEN" +" ol_dist_info := s_dist_08;" +" ELSIF (c_d_id = '8') THEN" +" ol_dist_info := s_dist_09;" +" ELSIF (c_d_id = '9') THEN" +" ol_dist_info := s_dist_10;" +" END IF;" +"" +" INSERT INTO ORDER_LINE VALUES (o_id, c_d_id, c_w_id," +" TO_BINARY(i, 1), ol_i_id," +" ol_supply_w_id, NULL, ol_quantity," +" ol_amount, ol_dist_info); " +" END LOOP;" +"" +" total := (((total * (10000 + w_tax + d_tax)) / 10000)" +" * (10000 - c_discount)) / 10000;" +"" +" o_entry_d := SYSDATE();" +"" +" INSERT INTO ORDERS VALUES (o_id, c_d_id, c_w_id, c_id, o_entry_d," +" NULL, o_ol_cnt, o_all_local);" +" INSERT INTO NEW_ORDER VALUES (o_id, c_d_id, c_w_id);" +"" +" /* PRINTF('Inserted order lines:');" +" ROW_PRINTF" +" SELECT * FROM ORDER_LINE WHERE OL_O_ID = o_id AND" +" OL_D_ID = c_d_id" +" AND OL_W_ID = c_w_id; */" +" /* COMMIT WORK; */" +" END;" + ; + + str5 = ut_str_catenate(str1, str2); + str6 = ut_str_catenate(str3, str4); + + str = ut_str_catenate(str5, str6); + + new_order_query = pars_sql(str); + + mem_free(str); + mem_free(str5); + mem_free(str6); + + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE PAYMENT () IS" +"" +" i INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" w_id CHAR;" +" w_street_1 CHAR;" +" w_street_2 CHAR;" +" w_city CHAR;" +" w_state CHAR;" +" w_zip CHAR;" +" w_name CHAR;" +" d_id CHAR;" +" d_street_1 CHAR;" +" d_street_2 CHAR;" +" d_city CHAR;" +" d_state CHAR;" +" d_zip CHAR;" +" d_name CHAR;" +" c_w_id CHAR;" +" c_d_id CHAR;" +" c_street_1 CHAR;" +" c_street_2 CHAR;" +" c_city CHAR;" +" c_state CHAR;" +" c_zip CHAR;" +" c_id CHAR;" +" c_last CHAR;" +" c_first CHAR;" +" c_middle CHAR;" +" c_phone CHAR;" +" c_credit CHAR;" +" c_credit_lim INT;" +" c_discount INT;" +" c_balance INT;" +" c_since INT;" +" c_data CHAR;" +" byname INT;" +" namecnt INT;" +" amount INT;" +" h_data CHAR;" +" h_date INT;" +" c_more_data CHAR;" +" more_len INT;" +" data_len INT;" +"" +" DECLARE CURSOR warehouse_cursor IS" +" SELECT W_STREET_1, W_STREET_2, W_CITY, W_STATE, W_ZIP, W_NAME" +" FROM WAREHOUSE" +" WHERE W_ID = w_id" +" FOR UPDATE;" +"" +" DECLARE CURSOR district_cursor IS" +" SELECT D_STREET_1, D_STREET_2, D_CITY, D_STATE, D_ZIP, D_NAME" +" FROM DISTRICT" +" WHERE D_W_ID = w_id AND D_ID = d_id" +" FOR UPDATE;" +"" +" DECLARE CURSOR customer_by_name_cursor IS" +" SELECT C_ID" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last" +" ORDER BY C_FIRST ASC;" +"" +" DECLARE CURSOR customer_cursor IS" +" SELECT C_FIRST, C_MIDDLE, C_LAST, C_STREET_1, C_STREET_2," +" C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT," +" C_CREDIT_LIM, C_DISCOUNT, C_BALANCE," +" C_SINCE" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_ID = c_id" +" FOR UPDATE;" + ; + + str2 = + +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 200;" +"" +" byname := RND(1, 100);" +" amount := RND(1, 1000);" +" h_date := SYSDATE();" +" w_id := TO_BINARY(RND(1, n_warehouses), 2);" +" d_id := TO_BINARY(47 + RND(1, n_districts), 1);" +" c_w_id := TO_BINARY(RND(1, n_warehouses), 2);" +" c_d_id := TO_BINARY(47 + RND(1, n_districts), 1);" +"" +" OPEN warehouse_cursor;" +"" +" FETCH warehouse_cursor INTO w_street_1, w_street_2, w_city, w_state," +" w_zip, w_name;" +" UPDATE WAREHOUSE SET W_YTD = W_YTD + amount" +" WHERE CURRENT OF warehouse_cursor;" +"" +" CLOSE warehouse_cursor;" +"" +" OPEN district_cursor;" +"" +" FETCH district_cursor INTO d_street_1, d_street_2, d_city, d_state," +" d_zip, d_name;" +" UPDATE DISTRICT SET D_YTD = D_YTD + amount" +" WHERE CURRENT OF district_cursor;" +"" +" CLOSE district_cursor;" +"" +" IF (byname <= 60) THEN" +" c_last := CONCAT('NAME', TO_CHAR(RND(1, n_customers) / 3));" +"" +" SELECT COUNT(*) INTO namecnt" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last;" +" /* PRINTF('Payment trx: Customer name ', c_last," +" ' namecount ', namecnt); */" +" OPEN customer_by_name_cursor;" +"" +" FOR i IN 1 .. (namecnt + 1) / 2 LOOP" +" FETCH customer_by_name_cursor INTO c_id;" +" END LOOP;" +" /* ASSERT(NOT (customer_by_name_cursor % NOTFOUND)); */" +" " +" CLOSE customer_by_name_cursor;" +" ELSE" +" c_id := TO_BINARY(RND(1, n_customers), 3);" +" END IF;" + + ; + str3 = +"" +" /* PRINTF('Payment for customer ', BINARY_TO_NUMBER(c_w_id), ' '," +" c_d_id, ' ', BINARY_TO_NUMBER(c_id)); */" +" OPEN customer_cursor;" +"" +" FETCH customer_cursor INTO c_first, c_middle, c_last, c_street_1," +" c_street_2, c_city, c_state, c_zip," +" c_phone, c_credit, c_credit_lim," +" c_discount, c_balance, c_since;" +" c_balance := c_balance - amount;" +"" +" h_data := CONCAT(w_name, ' ', d_name);" +" " +" IF (c_credit = 'BC') THEN" +" /* PRINTF('Bad customer pays'); */" +"" +" SELECT C_DATA INTO c_data" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_ID = c_id;" +" c_more_data := CONCAT(" +" ' ', TO_CHAR(BINARY_TO_NUMBER(c_id))," +" ' ', c_d_id," +" ' ', TO_CHAR(BINARY_TO_NUMBER(c_w_id))," +" ' ', d_id," +" ' ', TO_CHAR(BINARY_TO_NUMBER(w_id))," +" TO_CHAR(amount)," +" TO_CHAR(h_date)," +" ' ', h_data);" +"" +" more_len := LENGTH(c_more_data);" +" data_len := LENGTH(c_data);" +" " +" IF (more_len + data_len > 500) THEN" +" data_len := 500 - more_len;" +" END IF;" +" " +" c_data := CONCAT(c_more_data, SUBSTR(c_data, 0, data_len));" +" " +" UPDATE CUSTOMER SET C_BALANCE = c_balance," +" C_PAYMENT_CNT = C_PAYMENT_CNT + 1," +" C_YTD_PAYMENT = C_YTD_PAYMENT + amount," +" C_DATA = c_data" +" WHERE CURRENT OF customer_cursor;" +" ELSE" +" UPDATE CUSTOMER SET C_BALANCE = c_balance," +" C_PAYMENT_CNT = C_PAYMENT_CNT + 1," +" C_YTD_PAYMENT = C_YTD_PAYMENT + amount" +" WHERE CURRENT OF customer_cursor;" +" END IF;" +"" +" CLOSE customer_cursor;" +" " +" INSERT INTO HISTORY VALUES (c_d_id, c_w_id, c_id, d_id, w_id," +" h_date, amount, h_data);" +" /* COMMIT WORK; */" +"" +" END;" + + ; + + str4 = ut_str_catenate(str1, str2); + str = ut_str_catenate(str4, str3); + + payment_query = pars_sql(str); + + mem_free(str); + mem_free(str4); + + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE ORDER_STATUS () IS" +"" +" i INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" d_id CHAR;" +" namecnt INT;" +" c_w_id CHAR;" +" c_d_id CHAR;" +" c_id CHAR;" +" c_last CHAR;" +" c_first CHAR;" +" c_middle CHAR;" +" c_balance INT;" +" byname INT;" +" o_id INT;" +" o_carrier_id CHAR;" +" o_entry_d INT;" +" ol_i_id CHAR;" +" ol_supply_w_id CHAR;" +" ol_quantity INT;" +" ol_amount INT;" +" ol_delivery_d INT;" +"" +" DECLARE CURSOR orders_cursor IS" +" SELECT O_ID, O_CARRIER_ID, O_ENTRY_D" +" FROM ORDERS" +" WHERE O_W_ID = c_w_id AND O_D_ID = c_d_id" +" AND O_C_ID = c_id" +" ORDER BY O_ID DESC;" +"" +" DECLARE CURSOR order_line_cursor IS" +" SELECT OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT," +" OL_DELIVERY_D" +" FROM ORDER_LINE" +" WHERE OL_W_ID = c_w_id AND OL_D_ID = c_d_id" +" AND OL_O_ID = o_id;" +" DECLARE CURSOR customer_by_name_cursor IS" +" SELECT C_ID" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last" +" ORDER BY C_FIRST ASC;" +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 200;" +"" +" c_w_id := TO_BINARY(RND(1, n_warehouses), 2);" +" byname := RND(1, 100);" +"" + ; + + str2 = + +" IF (byname <= 60) THEN" +" d_id := TO_BINARY(47 + RND(1, n_districts), 1); " +"" +" c_d_id := d_id;" +"" +" c_last := CONCAT('NAME', TO_CHAR(RND(1, n_customers) / 3));" +"" +" SELECT COUNT(*) INTO namecnt" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last;" +" OPEN customer_by_name_cursor;" +"" +" /* PRINTF('Order status trx: Customer name ', c_last," +" ' namecount ', namecnt); */" +" FOR i IN 1 .. (namecnt + 1) / 2 LOOP" +" FETCH customer_by_name_cursor INTO c_id;" +" END LOOP;" +" /* ASSERT(NOT (customer_by_name_cursor % NOTFOUND)); */" +"" +" CLOSE customer_by_name_cursor;" +" ELSE" +" c_d_id := TO_BINARY(47 + RND(1, n_districts), 1);" +" c_id := TO_BINARY(RND(1, n_customers), 3);" +" END IF;" +"" +" SELECT C_BALANCE, C_FIRST, C_MIDDLE, C_LAST INTO c_balance, c_first," +" c_middle, c_last" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id AND C_ID = c_id;" +"" +" OPEN orders_cursor;" +"" +" FETCH orders_cursor INTO o_id, o_carrier_id, o_entry_d;" +"" +" IF (orders_cursor % NOTFOUND) THEN" +" PRINTF('Order status trx: customer has no order');" +" CLOSE orders_cursor;" +"" +" /* COMMIT WORK; */" +"" +" RETURN;" +" END IF;" +"" +" CLOSE orders_cursor;" +"" +" OPEN order_line_cursor;" +"" +" FOR i IN 0 .. 15 LOOP" +" FETCH order_line_cursor INTO ol_i_id, ol_supply_w_id," +" ol_quantity, ol_amount," +" ol_delivery_d;" +"" +" IF (order_line_cursor % NOTFOUND) THEN" +" CLOSE order_line_cursor;" +"" +" /* COMMIT WORK; */" +"" +" RETURN;" +" END IF;" +" END LOOP;" +" ASSERT(0 = 1);" +" " +" END;" + ; + + str = ut_str_catenate(str1, str2); + + order_status_query = pars_sql(str); + + mem_free(str); + + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE DELIVERY () IS" +"" +" i INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" d_id CHAR;" +" w_id CHAR;" +" c_id CHAR;" +" o_id INT;" +" o_carrier_id INT;" +" ol_delivery_d INT;" +" ol_total INT;" +"" +" DECLARE CURSOR new_order_cursor IS" +" SELECT NO_O_ID" +" FROM NEW_ORDER" +" WHERE NO_W_ID = w_id AND NO_D_ID = d_id" +" ORDER BY NO_O_ID ASC;" +"" +" DECLARE CURSOR orders_cursor IS" +" SELECT O_C_ID" +" FROM ORDERS" +" WHERE O_W_ID = w_id AND O_D_ID = d_id" +" AND O_ID = o_id" +" FOR UPDATE;" +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 200;" +"" +" w_id := TO_BINARY(RND(1, n_warehouses), 2);" +" o_carrier_id := RND(1, 10);" +" ol_delivery_d := SYSDATE();" + + ; + + str2 = + +" FOR i IN 1 .. n_districts LOOP" +"" +" d_id := TO_BINARY(47 + i, 1);" +"" +" OPEN new_order_cursor;" +"" +" FETCH new_order_cursor INTO o_id;" +"" +" IF (new_order_cursor % NOTFOUND) THEN" +" /* PRINTF('No order to deliver'); */" +"" +" CLOSE new_order_cursor;" +" ELSE" +" CLOSE new_order_cursor;" +" /* PRINTF('Order to deliver'); */" +"" +" DELETE FROM NEW_ORDER" +" WHERE NO_W_ID = w_id AND NO_D_ID = d_id" +" AND NO_O_ID = o_id;" +" OPEN orders_cursor;" +"" +" FETCH orders_cursor INTO c_id;" +"" +" UPDATE ORDERS SET O_CARRIER_ID = o_carrier_id" +" WHERE CURRENT OF orders_cursor;" +"" +" CLOSE orders_cursor;" +"" +" UPDATE ORDER_LINE SET OL_DELIVERY_D = ol_delivery_d" +" WHERE OL_W_ID = w_id AND OL_D_ID = d_id" +" AND OL_O_ID = o_id;" +"" +" SELECT SUM(OL_AMOUNT) INTO ol_total" +" FROM ORDER_LINE" +" WHERE OL_W_ID = w_id AND OL_D_ID = d_id" +" AND OL_O_ID = o_id;" +"" +" UPDATE CUSTOMER SET C_BALANCE = C_BALANCE - ol_total" +" WHERE C_W_ID = w_id AND C_D_ID = d_id" +" AND C_ID = c_id;" +" END IF;" +" END LOOP;" +"" +" /* COMMIT WORK; */" +" " +" END;" + ; + + str = ut_str_catenate(str1, str2); + + delivery_query = pars_sql(str); + + mem_free(str); + + /*-----------------------------------------------------------*/ + + /* NOTE: COUNT(DISTINCT ...) not implemented yet */ + + str = + +" PROCEDURE STOCK_LEVEL () IS" +"" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" d_id CHAR;" +" w_id CHAR;" +" o_id INT;" +" stock_count INT;" +" threshold INT;" +"" +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 200;" +"" +" w_id := TO_BINARY(RND(1, n_warehouses), 2);" +" d_id := TO_BINARY(47 + 4, 1);" +"" +" threshold := RND(10, 20);" +"" +" SELECT D_NEXT_O_ID INTO o_id" +" FROM DISTRICT" +" WHERE D_W_ID = w_id AND D_ID = d_id;" +"" +" SELECT COUNT(*) INTO stock_count" +" FROM ORDER_LINE, STOCK" +" WHERE OL_W_ID = w_id AND OL_D_ID = d_id" +" AND OL_O_ID >= o_id - 20 AND OL_O_ID < o_id" +" AND S_W_ID = w_id AND S_I_ID = OL_I_ID" +" AND S_QUANTITY < threshold;" +" /* PRINTF(stock_count, ' items under threshold ', threshold); */" +" /* COMMIT WORK; */" +"" +" END;" + ; + + stock_level_query = pars_sql(str); + /*-----------------------------------------------------------*/ + + oldtm = ut_clock(); + + for (i = 0; i < 10; i++) { + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(new_order_query, + SESS_COMM_EXECUTE, 0); + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(payment_query, + SESS_COMM_EXECUTE, 0); + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + if (i % 10 == 3) { + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(order_status_query, + SESS_COMM_EXECUTE, 0); + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + if ((i % 10 == 6) || (i % 100 == 60)) { + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(delivery_query, + SESS_COMM_EXECUTE, 0); + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + if (i % 10 == 9) { + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(stock_level_query, + SESS_COMM_EXECUTE, 0); + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + + if ((i > 0) && (i % 200 == 0)) { + mutex_enter(&kernel_mutex); + + thr = que_fork_start_command(commit_query, + SESS_COMM_EXECUTE, 0); + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } + } + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + + return(0); +} + +#ifdef notdefined + +/********************************************************************* +General test. */ + +ulint +test1( +/*==*/ + void* arg) +{ + sess_t* sess; + sess_t* sess2; + com_endpoint_t* com_endpoint; + mem_heap_t* heap; + que_fork_t* query; + que_thr_t* thr; + trx_t* trx; + trx_t* trx2; + ulint tm, oldtm; + ulint j; + + UT_NOT_USED(arg); + + printf("-------------------------------------------------\n"); + printf("TEST 1. GENERAL TEST\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); + sess2 = sess_open(ut_dulint_zero, com_endpoint, (byte*)"user2", 6); + + trx = sess->trx; + trx2 = sess2->trx; + + mutex_exit(&kernel_mutex); + + /*------------------------------------------------------*/ + query = pars_sql( +" PROCEDURE CREATE_TABLE () IS" +" BEGIN" +" CREATE TABLE TS_TABLE1 (COL1 CHAR, COL2 CHAR, COL3 CHAR);" +" CREATE TABLE TS_TABLE2 (COL21 INT, COL22 INT, COL23 CHAR);" +" CREATE TABLE TS_TABLE3 (COL31 INT, COL32 INT, COL33 CHAR);" +" CREATE TABLE TS_TABLE4 (COL41 INT, COL42 INT, COL43 CHAR);" +" CREATE UNIQUE CLUSTERED INDEX IND1 ON TS_TABLE1 (COL1);" +" CREATE UNIQUE CLUSTERED INDEX IND21 ON TS_TABLE2 (COL21);" +" CREATE UNIQUE CLUSTERED INDEX IND31 ON TS_TABLE3 (COL31);" +" CREATE CLUSTERED INDEX IND41 ON TS_TABLE4 (COL41);" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + + printf("Will start insert test\n"); + + query = pars_sql( + +" PROCEDURE INSERT_SPEED_TEST () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" int2 := 0;" +" int1 := 0;" +" WHILE int1 < 40 LOOP" +" INSERT INTO TS_TABLE2 VALUES (int1, int1 - 100 * (int1 / 100)," +" '123456789012345678901234567890');" +" int1 := int1 + 1;" +" " +" END LOOP;" +" " +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for insert test %lu milliseconds\n", tm - oldtm); + + + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE COMMIT_SPEED_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, 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_TABLE2"); */ + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + printf("Will start insert test2\n"); + + query = pars_sql( + +" PROCEDURE INSERT_SPEED_TEST2 () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" INSERT INTO TS_TABLE3 SELECT * FROM TS_TABLE2;" +" " +" " +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for insert test2 %lu milliseconds\n", tm - oldtm); + + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE COMMIT_SPEED_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, 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_TABLE2"); */ + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ +/* os_thread_sleep(1000000); */ + +/* btr_search_table_print_info("TS_TABLE3"); */ + + query = pars_sql( + +" PROCEDURE JOIN_SPEED_TEST () IS" +" int1 INT;" +" " +" BEGIN" +" SELECT COUNT(*) INTO int1" +" FROM TS_TABLE2, TS_TABLE3" +" WHERE COL21 = COL31" +" CONSISTENT READ;" +" PRINTF(int1);" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + for (j = 0; j < 20; j++) { + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, + 0)); + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + + printf("Wall time for join test %lu milliseconds\n", + tm - oldtm); + } + +/* btr_search_table_print_info("TS_TABLE3"); */ + + /*------------------------------------------------------*/ + printf("Will start update test\n"); + + os_thread_sleep(2000000); + + query = pars_sql( + +" PROCEDURE UPDATE_SPEED_TEST () IS" +" int1 INT;" +" BEGIN" +" UPDATE TS_TABLE2 SET COL22 = COL22 + 1;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for update test %lu milliseconds\n", tm - oldtm); + + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE COMMIT_SPEED_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, 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_TABLE2"); */ + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + printf("Will start TPC-A\n"); + os_thread_sleep(2000000); + + query = pars_sql( +" PROCEDURE TPC_A_SPEED_TEST () IS" +" int1 INT;" +" " +" BEGIN" +" int1 := 0;" +" WHILE int1 < 1000 LOOP" +" INSERT INTO TS_TABLE4 VALUES (int1, int1," +" '123456789012345678901234567890');" +" UPDATE TS_TABLE2 SET COL22 = COL22 + 1" +" WHERE COL21 = int1;" +" UPDATE TS_TABLE2 SET COL22 = COL22 + 1" +" WHERE COL21 = int1 + 1;" +" UPDATE TS_TABLE2 SET COL22 = COL22 + 1" +" WHERE COL21 = int1 + 2;" +" int1 := int1 + 1;" +" END LOOP;" +" " +" END;" + ); + +/*" SELECT COUNT(*) INTO int1 FROM TS_TABLE2 WHERE COL22 = COL21 + 4;" +" PRINTF(int1);" +" SELECT COUNT(*) INTO int1 FROM TS_TABLE4;" +" PRINTF(int1);" +*/ + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for TPC-A test %lu milliseconds\n", tm - oldtm); + + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE COMMIT_SPEED_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, 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); + + /*------------------------------------------------------*/ + printf("Will start insert test\n"); + + os_thread_sleep(2000000); + + query = pars_sql( + +" PROCEDURE INSERT_SPEED_TEST () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" int2 := 0;" +" int1 := 0;" +" WHILE int1 < 1000 LOOP" +" INSERT INTO TS_TABLE2 VALUES (int1, int1," +" '123456789012345678901234567890');" +" int1 := int1 + 1;" +" " +" END LOOP;" +" SELECT COUNT(*) INTO int2" +" FROM TS_TABLE2;" +" ASSERT(int1 = int2);" +" " +" COMMIT WORK;" +" " +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for insert test %lu milliseconds\n", tm - oldtm); + + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE DELETE_SPEED_TEST () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" SELECT COUNT(*), SUM(COL22) INTO int1, int2" +" FROM TS_TABLE2" +" CONSISTENT READ;" +" ASSERT(int1 = 1000);" +" ASSERT(int2 = 999 * 500);" +" DELETE FROM TS_TABLE2;" +" " +" SELECT COUNT(*), SUM(COL22) INTO int1, int2" +" FROM TS_TABLE2" +" CONSISTENT READ;" +" ASSERT(int1 = 0);" +" ASSERT(int2 = 0);" +" " +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for delete test %lu milliseconds\n", tm - oldtm); + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + os_thread_sleep(2000000); + + query = pars_sql( + +" PROCEDURE CONSISTENT_READ_TEST () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" SELECT COUNT(*), SUM(COL22) INTO int1, int2" +" FROM TS_TABLE2" +" CONSISTENT READ;" +" ASSERT(int2 = 999 * 500);" +" ASSERT(int1 = 1000);" +" " +" " +" END;" + ); + + query->trx = trx2; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for consistent read test %lu milliseconds\n", + tm - oldtm); + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE ROLLBACK_SPEED_TEST () IS" +" " +" BEGIN" +" ROLLBACK WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for rollback %lu milliseconds\n", tm - oldtm); + + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE UPDATE_SPEED_TEST () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" UPDATE TS_TABLE2 SET COL21 = COL21 + 1000, COL22 = COL22 + 1" +" WHERE COL21 < 1000;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" UPDATE TS_TABLE2 SET COL21 = COL21, COL22 = COL22;" +" " +" SELECT SUM(COL21), SUM(COL22) INTO int1, int2" +" FROM TS_TABLE2" +" CONSISTENT READ;" +" ASSERT(int2 = 1000 + 999 * 500);" +" ASSERT(int1 = 1000000 + 999 * 500);" +" UPDATE TS_TABLE2 SET COL21 = COL21 + 1000, COL22 = COL22 + 1" +" WHERE COL21 < 2000;" +" UPDATE TS_TABLE2 SET COL21 = COL21 + 1000, COL22 = COL22 + 1" +" WHERE COL21 < 3000;" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for update test %lu milliseconds\n", tm - oldtm); + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + os_thread_sleep(2000000); + + query = pars_sql( + +" PROCEDURE CONSISTENT_READ_TEST () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" SELECT COUNT(*), SUM(COL22) INTO int1, int2" +" FROM TS_TABLE2" +" CONSISTENT READ;" +" ASSERT(int1 = 1000);" +" ASSERT(int2 = 999 * 500);" +" " +" " +" END;" + ); + + query->trx = trx2; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for consistent read test %lu milliseconds\n", + tm - oldtm); + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE COMMIT_SPEED_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, 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_TABLE2"); */ + /*------------------------------------------------------*/ + /*------------------------------------------------------*/ + os_thread_sleep(2000000); + + query = pars_sql( + +" PROCEDURE CONSISTENT_READ_TEST () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" SELECT COUNT(*), SUM(COL22) INTO int1, int2" +" FROM TS_TABLE2" +" CONSISTENT READ;" +" ASSERT(int1 = 1000);" +" ASSERT(int2 = 999 * 500);" +" " +" " +" END;" + ); + + query->trx = trx2; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for consistent read test %lu milliseconds\n", + tm - oldtm); + /*------------------------------------------------------*/ + printf("Will start insert test2\n"); + os_thread_sleep(2000000); + + query = pars_sql( + +" PROCEDURE INSERT_SPEED_TEST2 () IS" +" int1 INT;" +" int2 INT;" +" " +" BEGIN" +" INSERT INTO TS_TABLE3 SELECT * FROM TS_TABLE2;" +" " +" SELECT COUNT(*) INTO int1" +" FROM TS_TABLE2;" +" SELECT COUNT(*) INTO int2" +" FROM TS_TABLE3;" +" ASSERT(int1 = int2);" +" " +" COMMIT WORK;" +" " +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for insert test2 %lu milliseconds\n", tm - oldtm); + +/* sync_print(); */ + + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE COMMIT_SPEED_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, 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); + + /*------------------------------------------------------*/ + + query = pars_sql( + +" PROCEDURE JOIN_SPEED_TEST () IS" +" int1 INT;" +" " +" BEGIN" +" SELECT COUNT(*) INTO int1" +" FROM TS_TABLE2, TS_TABLE3" +" WHERE COL21 = COL31;" +" ASSERT(int1 = 1000);" +" " +" COMMIT WORK;" +" " +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + oldtm = ut_clock(); + + que_run_threads(thr); + + tm = ut_clock(); + printf("Wall time for join test %lu milliseconds\n", tm - oldtm); + + /*------------------------------------------------------*/ + + dict_table_print_by_name("TS_TABLE1"); + dict_table_print_by_name("TS_TABLE2"); + +/* + dict_table_print_by_name("SYS_TABLES"); + dict_table_print_by_name("SYS_COLUMNS"); + dict_table_print_by_name("SYS_INDEXES"); + dict_table_print_by_name("SYS_FIELDS"); +*/ + query = pars_sql( + +" PROCEDURE INSERT_TEST () IS" +" var1 CHAR;" +" var2 CHAR;" +" int1 INT;" +" int2 INT;" +" sum1 INT;" +" finished INT;" +" rnd_var1 INT;" +" rnd_var2 INT;" +" " +" DECLARE CURSOR cursor2" +" IS SELECT COL21, COL22" +" FROM TS_TABLE2" +" WHERE COL21 > 5;" +" " +" BEGIN" +" int1 := 0;" +" WHILE int1 < 10 LOOP" +" rnd_var1 := int1;" +" PRINTF('Round '); PRINTF(int1);" +" INSERT INTO TS_TABLE2 VALUES (int1, rnd_var1," +" '123456789012345678901234567890');" +" SELECT COL22 INTO rnd_var2 FROM TS_TABLE2" +" WHERE COL21 = int1;" +" ASSERT(rnd_var1 = rnd_var2);" +" int1 := int1 + 1;" +" END LOOP;" +" " +" PRINTF('First explicit cursor loop:');" +" OPEN cursor2;" +" finished := 0;" +" " +" WHILE finished = 0 LOOP" +" FETCH cursor2 INTO int1, int2;" +" IF cursor2 % NOTFOUND THEN" +" finished := 1;" +" PRINTF('Loop now finished');" +" ELSE" +" PRINTF('Row fetched, values:');" +" PRINTF(int1); PRINTF(int2);" +" ASSERT(int1 = int2);" +" UPDATE TS_TABLE2 SET COL22 = COL22 + 100" +" WHERE CURRENT OF cursor2;" +" END IF;" +" END LOOP;" +" CLOSE cursor2;" +" " +" PRINTF('Second explicit cursor loop:');" +" OPEN cursor2;" +" finished := 0;" +" " +" WHILE finished = 0 LOOP" +" FETCH cursor2 INTO int1, int2;" +" IF cursor2 % NOTFOUND THEN" +" finished := 1;" +" ELSE" +" PRINTF('Row fetched, values:');" +" PRINTF(int1); PRINTF(int2);" +" ASSERT(int1 + 100 = int2);" +" UPDATE TS_TABLE2 SET COL22 = int2 + 100" +" WHERE CURRENT OF cursor2;" +" END IF;" +" END LOOP;" +" CLOSE cursor2;" +" " +" SELECT COUNT(*), SUM(COL22) INTO int1, sum1" +" FROM TS_TABLE2;" +" PRINTF('Now table 2 has this many rows: '); PRINTF(int1);" +" PRINTF('and the sum of COL22: '); PRINTF(sum1);" +" " +" INSERT INTO TS_TABLE3" +" SELECT COL21, COL22 + 10, COL23 FROM TS_TABLE2;" +" " +" SELECT COUNT(*), SUM(COL32) INTO int1, sum1" +" FROM TS_TABLE2, TS_TABLE3" +" WHERE COL21 + 2 = COL31;" +" PRINTF('Join table has this many rows: '); PRINTF(int1);" +" PRINTF('and the sum of COL32: '); PRINTF(sum1);" +" " +" ROLLBACK WORK;" +" " +" SELECT COUNT(*), SUM(COL21) INTO int1, sum1 FROM TS_TABLE2;" +" PRINTF('Now table 2 has this many rows: '); PRINTF(int1);" +" PRINTF('and the sum of COL21: '); PRINTF(sum1);" +" " +" " +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + dict_table_print_by_name("TS_TABLE1"); + dict_table_print_by_name("TS_TABLE2"); + + query = pars_sql( + +" PROCEDURE DELETE_TEST () IS" +" int1 INT;" +" sum1 INT;" +" finished INT;" +" " +" DECLARE CURSOR cursor2" +" IS SELECT" +" FROM TS_TABLE2" +" WHERE COL21 < 10;" +" " +" BEGIN" +" int1 := 0;" +" WHILE int1 < 10 LOOP" +" PRINTF('Round '); PRINTF(int1);" +" INSERT INTO TS_TABLE2 VALUES (int1, int1, TO_CHAR(int1));" +" int1 := int1 + 1;" +" END LOOP;" +" COMMIT WORK;" +" PRINTF('Delete all the rows:');" +" OPEN cursor2;" +" finished := 0;" +" " +" WHILE finished = 0 LOOP" +" FETCH cursor2 INTO;" +" IF cursor2 % NOTFOUND THEN" +" finished := 1;" +" PRINTF('Loop now finished: all rows deleted');" +" ELSE" +" DELETE FROM TS_TABLE2" +" WHERE CURRENT OF cursor2;" +" END IF;" +" END LOOP;" +" CLOSE cursor2;" +" " +" SELECT COUNT(*), SUM(COL22) INTO int1, sum1" +" FROM TS_TABLE2;" +" PRINTF('Now table 2 has this many rows, and their sum is: ');" +" PRINTF(int1); PRINTF(sum1);" +" ASSERT((int1 = 0) AND (sum1 = 0));" +" " +" ROLLBACK WORK;" +" " +" SELECT COUNT(*), SUM(COL22) INTO int1, sum1" +" FROM TS_TABLE2;" +" " +" PRINTF(int1); PRINTF(sum1);" +" ASSERT((int1 = 10) AND (sum1 = 45));" +" COMMIT WORK;" +" DELETE FROM TS_TABLE2 WHERE COL22 = 5;" +" SELECT COUNT(*), SUM(COL22) INTO int1, sum1" +" FROM TS_TABLE2;" +" PRINTF(int1); PRINTF(sum1);" +" ASSERT((int1 = 9) AND (sum1 = 40));" +" DELETE FROM TS_TABLE2 WHERE COL23 = TO_CHAR(6);" +" SELECT COUNT(*), SUM(COL22) INTO int1, sum1" +" FROM TS_TABLE2;" +" PRINTF(int1);" +" PRINTF(sum1);" +" ASSERT((int1 = 8) AND (sum1 = 34));" +" DELETE FROM TS_TABLE2 WHERE COL23 = TO_CHAR(6);" +" SELECT COUNT(*), SUM(COL22) INTO int1, sum1" +" FROM TS_TABLE2;" +" PRINTF(int1);" +" PRINTF(sum1);" +" ASSERT((int1 = 8) AND (sum1 = 34));" +" COMMIT WORK;" +" END;" + ); + + query->trx = trx; + + thr = UT_LIST_GET_FIRST(query->thrs); + + mutex_enter(&kernel_mutex); + + ut_a(thr == que_fork_start_command(query, SESS_COMM_EXECUTE, 0)); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + + return(0); +} + +#endif + +/******************************************************************** +Main test function. */ + +void +main(void) +/*======*/ +{ + ulint tm, oldtm; + + oldtm = ut_clock(); + + test_c(NULL); + + tm = ut_clock(); + + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} + diff --git a/innobase/btr/ts/tsbtr97.c b/innobase/btr/ts/tsbtr97.c new file mode 100644 index 00000000000..633fb7f22ae --- /dev/null +++ b/innobase/btr/ts/tsbtr97.c @@ -0,0 +1,5080 @@ +/************************************************************************ +Test for the B-tree + +(c) 1996-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 "buf0flu.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 "log0recv.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 +#define N_FILES 1 +#define FILE_SIZE 512 /* must be > 512 */ +#define POOL_SIZE 500 +#define COUNTER_OFFSET 1500 + +#define N_LOG_GROUPS 2 +#define N_LOG_FILES 3 +#define LOG_FILE_SIZE 500 + +#define LOOP_SIZE 150 +#define N_THREADS 5 + +#define COUNT 1 + +ulint zero = 0; + +buf_block_t* bl_arr[POOL_SIZE]; + +ulint dummy = 0; + +byte rnd_buf[256 * 256]; + +/************************************************************************ +Io-handler thread function. */ + +ulint +handler_thread( +/*===========*/ + void* arg) +{ + ulint segment; + ulint i; + + 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 or opens the log files. */ + +void +create_log_files(void) +/*==================*/ +{ + bool ret; + ulint i, k; + char name[20]; + + printf("--------------------------------------------------------\n"); + printf("Create or open log files\n"); + + strcpy(name, "logfile00"); + + for (k = 0; k < N_LOG_GROUPS; k++) { + for (i = 0; i < N_LOG_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_AIO, + &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_AIO, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + 8192 * LOG_FILE_SIZE, 0)); + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k + 100, FIL_LOG); + } + + ut_a(fil_validate()); + + fil_node_create(name, LOG_FILE_SIZE, k + 100); + } + + fil_space_create(name, k + 200, FIL_LOG); + + log_group_init(k, N_LOG_FILES, LOG_FILE_SIZE * UNIV_PAGE_SIZE, + k + 100, k + 200); + } +} + +/************************************************************************* +Creates the files for the file system test and inserts them to the file +system. */ + +void +create_files(void) +/*==============*/ +{ + bool ret; + ulint i, k, j, c; + 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 < 2 * N_SPACES; k += 2) { + 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_NORMAL, &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_NORMAL, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + UNIV_PAGE_SIZE * FILE_SIZE, 0)); + /* Initialize the file contents to a random value */ + + for (j = 0; j < FILE_SIZE; j++) { + for (c = 0; c < UNIV_PAGE_SIZE; c++) { + rnd_buf[c] = 0xFF; + /*(byte) + (ut_rnd_gen_ulint() % 256); */ + } + + os_file_write(files[i], rnd_buf, + UNIV_PAGE_SIZE * j, 0, + UNIV_PAGE_SIZE); + } + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k, FIL_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 2. */ + +void +init_spaces(void) +/*=============*/ +{ + mtr_t mtr; + + mtr_start(&mtr); + + fsp_header_init(0, FILE_SIZE * N_FILES, &mtr); + fsp_header_init(2, FILE_SIZE * N_FILES, &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"); */ + + /* 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); + + 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 % 100 == 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 < 1 /* *((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); */ + +#ifdef notdefined + /*-------------------------------------*/ + /* 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"); */ + /*-------------------------------------*/ + + /* 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; +/* buf_frame_t* frame_table[2000]; + 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; + + rnd = 0; + + 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(); + + 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) { + + /* fsp_print(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"); + + /*-------------------------------------*/ + /* ROLLBACK */ + +/* btr_validate_tree(tree); */ + + for (i = 0; i < POOL_SIZE - 1; i++) { + frame_table[i] = buf_frame_alloc(FALSE); + } + + for (i = 0; i < POOL_SIZE - 1; i++) { + buf_frame_free(frame_table[i]); + } + + 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); +#endif +#ifdef notdefined + 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_RND3500, 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) { + printf("*******Inserted %lu rows\n", i); +/* buf_print(); */ + ibuf_print(); + } + + rnd = (rnd + 7857641) % 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); + + 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; + + 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, 1); + dfield_copy(dtuple_get_nth_field(entry, 0), + dtuple_get_nth_field(row, 0)); + + 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); + + ut_a(DB_SUCCESS == lock_table(0, table, LOCK_IX, thr)); + + ut_a(DB_SUCCESS == lock_clust_rec_read_check_and_lock(0, + btr_pcur_get_rec(&pcur), + index, LOCK_X, thr)); + 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 */ + + 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); +#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 + 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 < 999; 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("%lu: thread %lu to update row %lu\n", i, 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 % 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); + + } /* 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); + + if ((count == 1) && (thr_no != 4)) { + + return(0); + } + + /*-------------------------------------*/ + /* 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(7000000); + + 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; + char buf[100]; + +/* buf_debug_prints = TRUE; */ + log_do_write = TRUE; + btr_search_use_hash = TRUE; + log_debug_writes = TRUE; + + 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(); + create_log_files(); + + init_spaces(); + + sess_sys_init_at_db_start(); + + trx_sys_create(); + + dict_create(); + + log_make_checkpoint_at(ut_dulint_max); +/* log_debug_writes = TRUE; */ + +/* 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(); */ + + log_make_checkpoint_at(ut_dulint_max); + + n2 = 100; + +/* test2_1(&n2); + + log_flush_up_to(ut_dulint_max, LOG_WAIT_ALL_GROUPS); */ + +/* sync_print(); + + test9A(&n2); + + sync_print(); + + log_print(); + + test9(&n2); + + log_print(); + + sync_print(); */ +/* test6(&n2); */ + +/* test2_2(&n2); */ + +/* test3(&n2); */ + +/* mem_print_info(); */ + + log_archive_stop(); + log_archive_start(); + + ut_a(DB_SUCCESS == log_switch_backup_state_on()); + + printf("Type: kukkuu<enter>\n"); + scanf("%s", buf); + + ut_a(DB_SUCCESS == log_switch_backup_state_off()); + + for (i = 0; i < 2; i++) { + + n1000[i] = 500 + 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 = 5000; + +/* fsp_print(0); */ + + test2_1(&n2); + + for (i = 0; i < 20; i++) { + log_archive_stop(); + log_archive_start(); + } + +/* test2(&n2); + test2(&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 = 100; + + 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); + + log_archive_stop(); + log_archive_start(); + + test4mt(&n2); +*/ +/* test4_2(); */ +/* + lock_print_info(); +*/ +/* test7(&n2); */ + +/* os_thread_sleep(25000000); */ + +/* ut_a(DB_SUCCESS == log_switch_backup_state_off()); */ + +/* recv_compare_spaces(0, 1, 100); */ + + log_flush_up_to(ut_dulint_max, LOG_WAIT_ALL_GROUPS); + + printf("Type: kukkuu<enter>\n"); + scanf("%s", buf); + + buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, ut_dulint_max); + buf_flush_wait_batch_end(BUF_FLUSH_LIST); + +/* log_make_checkpoint_at(ut_dulint_max); */ + +/* dict_table_print_by_name("TS_TABLE1"); */ + +/* buf_print(); */ + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} 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"); +} diff --git a/innobase/btr/ts/tsbtrins.c b/innobase/btr/ts/tsbtrins.c new file mode 100644 index 00000000000..85eedd292b1 --- /dev/null +++ b/innobase/btr/ts/tsbtrins.c @@ -0,0 +1,802 @@ +/************************************************************************ +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; + +#define N_SPACES 2 /* must be >= 2 */ +#define N_FILES 1 +#define FILE_SIZE 8096 /* must be > 512 */ +#define POOL_SIZE 1024 +#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; + +byte test_buf[8000]; + +/************************************************************************ +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++) { + ret = fil_aio_wait(segment, &mess); + ut_a(ret); + + buf_page_io_complete((buf_block_t*)mess); + + 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 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_index_t* index; +/* dict_tree_t* tree; + 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; + + log_print(); + + 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); + + log_print(); + +/* dict_table_print_by_name("TS_TABLE1"); */ + +/* ibuf_print(); */ + + index = index; + + index = dict_table_get_first_index(table); + + if (zero) { + btr_search_index_print_info(index); + } + + btr_validate_tree(dict_index_get_tree(index)); + +#ifdef notdefined + index = dict_table_get_next_index(index); + + if (zero) { + 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 + /*-------------------------------------*/ + /* ROLLBACK */ + +#ifdef notdefined +/* 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); + +/* dict_table_print_by_name("TS_TABLE1"); */ + + 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); +} + +/******************************************************************** +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 = TRUE; + + 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); + +/* 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"); */ + + log_flush_up_to(ut_dulint_zero); + + os_thread_sleep(500000); + + n2 = 10000; + + test2_1(&n2); + +/* test9A(&n2); + test9(&n2); */ + +/* 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"); +} diff --git a/innobase/btr/ts/tscli.c b/innobase/btr/ts/tscli.c new file mode 100644 index 00000000000..6c42a83cdbe --- /dev/null +++ b/innobase/btr/ts/tscli.c @@ -0,0 +1,3380 @@ +/************************************************************************ +Tests for the client, TPC-C, and TPC-D Query 5 + +(c) 1996-1998 Innobase Oy + +Created 2/16/1996 Heikki Tuuri +*************************************************************************/ + +#include "univ.i" +#include "ib_odbc.h" +#include "mem0mem.h" +#include "sync0sync.h" +#include "os0thread.h" +#include "os0proc.h" +#include "os0sync.h" +#include "srv0srv.h" + +ulint n_exited = 0; + +/* Disk wait simulation array */ +typedef struct srv_sim_disk_struct srv_sim_disk_t; +struct srv_sim_disk_struct{ + os_event_t event; /* OS event to wait */ + bool event_set;/* TRUE if the event is in the set state */ + bool empty; /* TRUE if this cell not reserved */ +}; + +#define SRV_N_SIM_DISK_ARRAY 150 + +srv_sim_disk_t srv_sim_disk[SRV_N_SIM_DISK_ARRAY]; + +/* Random counter used in disk wait simulation */ +ulint srv_disk_rnd = 982364761; +ulint srv_disk_n_active_threads = 0; + +char cli_srv_endpoint_name[100]; +char cli_user_name[100]; + +ulint n_warehouses = ULINT_MAX; +ulint n_customers_d = ULINT_MAX; +bool is_tpc_d = FALSE; +ulint n_rounds = ULINT_MAX; +ulint n_users = ULINT_MAX; +ulint startdate = 0; +ulint enddate = 0; +bool own_warehouse = FALSE; + +ulint mem_pool_size = ULINT_MAX; + +/********************************************************************* +Test for TPC-C. */ + +ulint +test_init( +/*======*/ + void* arg) +{ + HENV env; + HDBC conn; + RETCODE ret; + HSTMT stat; + HSTMT create_query; + HSTMT populate_query; + char* str; + char* str1; + char* str2; + char* str3; + char* str4; + char* str5; + char* str6; + char* create_str; + char* populate_str; + char* commit_str; + char* new_order_str; + char* payment_str; + char* order_status_str; + char* delivery_str; + char* stock_level_str; + char* consistency_str; + char* query_5_str; + char* print_str; + char* lock_wait_str; + char* join_test_str; + char* test_errors_str; + char* test_group_commit_str; + char* test_single_row_select_str; + char* rollback_str; + char* ibuf_test_str; + SDWORD n_warehouses_buf; + SDWORD n_warehouses_len; + SDWORD n_customers_d_buf; + SDWORD n_customers_d_len; + + UT_NOT_USED(arg); + + /*------------------------------------------------------*/ + + str1 = + +" PROCEDURE CREATE_TABLES () IS" +" BEGIN" +" CREATE TABLE WAREHOUSE (W_ID CHAR, W_NAME CHAR," +" W_STREET_1 CHAR, W_STREET_2 CHAR," +" W_CITY CHAR," +" W_STATE CHAR, W_ZIP CHAR," +" W_TAX INT," +" W_YTD_HIGH INT," +" W_YTD INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX W_IND ON WAREHOUSE (W_ID);" +"" +" CREATE TABLE DISTRICT (D_ID CHAR, D_W_ID CHAR," +" D_NAME CHAR," +" D_STREET_1 CHAR, D_STREET_2 CHAR," +" D_CITY CHAR," +" D_STATE CHAR, D_ZIP CHAR," +" D_TAX INT," +" D_YTD_HIGH INT," +" D_YTD INT," +" D_NEXT_O_ID INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX D_IND ON DISTRICT (D_W_ID, D_ID);" +"" +" CREATE TABLE CUSTOMER (C_ID CHAR, C_D_ID CHAR, C_W_ID CHAR," +" C_FIRST CHAR, C_MIDDLE CHAR," +" C_LAST CHAR," +" C_STREET_1 CHAR, C_STREET_2 CHAR," +" C_CITY CHAR," +" C_STATE CHAR, C_ZIP CHAR," +" C_PHONE CHAR," +" C_SINCE_TIME INT," +" C_SINCE INT," +" C_CREDIT CHAR," +" C_CREDIT_LIM_HIGH INT," +" C_CREDIT_LIM INT," +" C_DISCOUNT INT," +" C_BALANCE_HIGH INT," +" C_BALANCE INT," +" C_YTD_PAYMENT_HIGH INT," +" C_YTD_PAYMENT INT," +" C_PAYMENT_CNT INT," +" C_DELIVERY_CNT INT," +" C_DATA CHAR) /*DOES_NOT_FIT_IN_MEMORY*/;" +"" +" CREATE UNIQUE CLUSTERED INDEX C_IND ON CUSTOMER (C_W_ID, C_D_ID," +" C_ID);" +"" +" CREATE INDEX C_LAST_IND ON CUSTOMER (C_W_ID, C_D_ID, C_LAST," +" C_FIRST);" +"" +" CREATE TABLE HISTORY (H_C_ID CHAR, H_C_D_ID CHAR, H_C_W_ID CHAR," +" H_D_ID CHAR, H_W_ID CHAR," +" H_DATE INT," +" H_AMOUNT INT," +" H_DATA CHAR);" +"" +" CREATE CLUSTERED INDEX H_IND ON HISTORY (H_W_ID);" +"" +" CREATE TABLE NEW_ORDER (NO_O_ID INT," +" NO_D_ID CHAR," +" NO_W_ID CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX NO_IND ON NEW_ORDER (NO_W_ID, NO_D_ID," +" NO_O_ID);" + ; + + str2 = + +" CREATE TABLE ORDERS (O_ID INT, O_D_ID CHAR, O_W_ID CHAR," +" O_C_ID CHAR," +" O_ENTRY_D INT," +" O_CARRIER_ID INT," +" O_OL_CNT INT," +" O_ALL_LOCAL CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX O_IND ON ORDERS (O_W_ID, O_D_ID," +" O_ID);" +" CREATE INDEX O_C_IND ON ORDERS (O_W_ID, O_D_ID, O_C_ID);" +"" +" CREATE TABLE ORDER_LINE (OL_O_ID INT, OL_D_ID CHAR, OL_W_ID CHAR," +" OL_NUMBER CHAR," +" OL_I_ID CHAR," +" OL_SUPPLY_W_ID CHAR," +" OL_DELIVERY_D INT," +" OL_QUANTITY INT," +" OL_AMOUNT INT," +" OL_DIST_INFO CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX OL_IND ON ORDER_LINE" +" (OL_W_ID, OL_D_ID, OL_O_ID, OL_NUMBER);" +"" +" CREATE TABLE ITEM (I_ID CHAR, I_IM_ID CHAR, I_NAME CHAR," +" I_PRICE INT," +" I_DATA CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX I_IND ON ITEM (I_ID);" +"" +" CREATE TABLE STOCK (S_I_ID CHAR," +" S_W_ID CHAR," +" S_QUANTITY INT," +" S_DIST_01 CHAR," +" S_DIST_02 CHAR," +" S_DIST_03 CHAR," +" S_DIST_04 CHAR," +" S_DIST_05 CHAR," +" S_DIST_06 CHAR," +" S_DIST_07 CHAR," +" S_DIST_08 CHAR," +" S_DIST_09 CHAR," +" S_DIST_10 CHAR," +" S_YTD INT," +" S_ORDER_CNT INT," +" S_REMOTE_CNT INT," +" S_DATA CHAR) /*DOES_NOT_FIT_IN_MEMORY*/;" +"" +" CREATE UNIQUE CLUSTERED INDEX S_IND ON STOCK (S_W_ID, S_I_ID);" +"" +"" +" CREATE TABLE REGION (R_REGIONKEY INT, R_NAME CHAR, R_COMMENT CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX R_IND ON REGION (R_REGIONKEY);" +"" +" CREATE TABLE NATION (N_NATIONKEY INT, N_NAME CHAR, N_REGIONKEY INT," +" N_COMMENT CHAR);" +" CREATE UNIQUE CLUSTERED INDEX N_IND ON NATION (N_NATIONKEY);" +"" +" CREATE TABLE NATION_2 (N2_NATIONKEY INT, N2_NAME CHAR," +" N2_REGIONKEY INT, N2_COMMENT CHAR);" +" CREATE UNIQUE CLUSTERED INDEX N2_IND ON NATION_2 (N2_NAME);" +"" +" CREATE TABLE SUPPLIER (S_SUPPKEY INT, S_NAME CHAR, S_ADDRESS CHAR," +" S_NATIONKEY INT, S_PHONE CHAR," +" S_ACCTBAL INT, S_COMMENT CHAR);" +" CREATE UNIQUE CLUSTERED INDEX SU_IND ON SUPPLIER (S_SUPPKEY);" +"" +" CREATE TABLE CUSTOMER_D (C_CUSTKEY INT, C_NAME CHAR, C_ADDRESS CHAR," +" C_NATIONKEY INT, C_PHONE CHAR," +" C_ACCTBAL INT, C_MKTSEGMENT CHAR," +" C_COMMENT CHAR);" +" CREATE UNIQUE CLUSTERED INDEX CU_IND ON CUSTOMER_D (C_CUSTKEY);" +"" +" CREATE TABLE ORDERS_D (O_ORDERKEY INT, O_CUSTKEY INT," +" O_ORDERSTATUS CHAR, O_TOTALPRICE INT," +" O_ORDERDATE INT," +" O_ORDERPRIORITY CHAR," +" O_CLERK CHAR, O_SHIPPRIORITY INT," +" O_COMMENT CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX OR_IND ON ORDERS_D (O_ORDERKEY);" +"" +" CREATE INDEX OR_D_IND ON ORDERS_D (O_ORDERDATE, O_ORDERKEY," +" O_CUSTKEY);" +"" +" CREATE TABLE LINEITEM (L_ORDERKEY INT, L_PARTKEY INT, L_SUPPKEY INT," +" L_LINENUMBER INT, L_QUANTITY INT," +" L_EXTENDEDPRICE INT," +" L_DISCOUNT INT, L_TAX INT," +" L_RETURNFLAG CHAR," +" L_LINESTATUS CHAR," +" L_SHIPDATE INT, L_COMMITDATE INT," +" L_RECEIPTDATE INT," +" L_SHIPINSTRUCT CHAR," +" L_SHIPMODE CHAR, L_COMMENT CHAR);" +"" +" CREATE UNIQUE CLUSTERED INDEX L_IND ON LINEITEM (L_ORDERKEY," +" L_LINENUMBER);" +"" +" CREATE TABLE ACCOUNTA (A_NUM INT, A_BAL INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX ACCOUNTA_IND ON ACCOUNTA (A_NUM);" +"" +" CREATE TABLE TELLERA (T_NUM INT, T_BAL INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX TELLERA_IND ON TELLERA (T_NUM);" +"" +" CREATE TABLE BRANCHA (B_NUM INT, B_BAL INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX BRANCHA_IND ON BRANCHA (B_NUM);" +"" +" CREATE TABLE HISTORYA (H_NUM INT, H_TEXT CHAR);" +"" +" CREATE CLUSTERED INDEX HISTORYA_IND ON HISTORYA (H_NUM);" +"" +" CREATE TABLE JTEST1 (JT1_A INT, JT1_B INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX JT_IND1 ON JTEST1 (JT1_A);" +"" +" CREATE TABLE JTEST2 (JT2_A INT, JT2_B INT);" +"" +" CREATE UNIQUE CLUSTERED INDEX JT_IND2 ON JTEST2 (JT2_A);" +"" +" CREATE TABLE IBUF_TEST (IB_A INT, IB_B CHAR) DOES_NOT_FIT_IN_MEMORY;" +"" +" CREATE UNIQUE CLUSTERED INDEX IBUF_IND ON IBUF_TEST (IB_A);" +" END;" + ; + + create_str = ut_str_catenate(str1, str2); + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE POPULATE_TABLES (n_warehouses IN INT, n_customers_d" +" IN INT) IS" +"" +" i INT;" +" j INT;" +" k INT;" +" t INT;" +" string CHAR;" +" rnd1 INT;" +" rnd2 INT;" +" rnd INT;" +" n_items INT;" +" n_districts INT;" +" n_customers INT;" +"" +" BEGIN" +"" +"/**********************************************************/" +" PRINTF('Starting Mikko-test');" +"" +" FOR i IN 1 .. 5 LOOP" +" INSERT INTO IBUF_TEST VALUES (i, 'Mikko');" +" END LOOP;" +"" +" /* PRINTF('Printing rows from Mikko-test:');" +"" +" ROW_PRINTF SELECT * FROM IBUF_TEST; */" +"" +" SELECT SUM(IB_A) INTO t FROM IBUF_TEST;" +"" +" PRINTF('Sum of 1 to ', i, ' is ', t);" +" ASSERT(t = (i * (i + 1)) / 2);" +"" +" ROLLBACK WORK;" +"" +" PRINTF('Printing rows from Mikko-test after rollback:');" +"" +" ROW_PRINTF SELECT * FROM IBUF_TEST;" +"" +"/**********************************************************/" +" FOR i IN 0 .. 100 LOOP" +" INSERT INTO ACCOUNTA VALUES (i, i);" +" INSERT INTO TELLERA VALUES (i, i);" +" INSERT INTO BRANCHA VALUES (i, i);" +" INSERT INTO HISTORYA VALUES (i, '12345678901234567890');" +" END LOOP;" +"" +" COMMIT WORK;" +"/**********************************************************/" +"/* PRINTF('Populating ibuf test tables');" +" FOR i IN 1 .. 1000 LOOP" +" INSERT INTO IBUF_TEST VALUES (i, RND_STR(RND(1, 2000)));" +" END LOOP;" +" PRINTF('Ibuf test tables populated');" +" COMMIT WORK; */" +"" +" n_items := 200;" +" n_districts := 10;" +" n_customers := 20;" +"" +" PRINTF('Starting to populate ITEMs');" +"" +" FOR i IN 1 .. n_items LOOP" +" rnd1 := RND(26, 50);" +" string := RND_STR(rnd1);" +"" +" IF (RND(0, 99) < 10) THEN" +" rnd2 := RND(0, rnd1 - 8);" +" REPLSTR(string, 'ORIGINAL', rnd2, 8);" +" END IF;" +"" +" INSERT INTO ITEM VALUES (TO_BINARY(i, 3)," +" TO_BINARY(RND(1, 10000), 3)," +" RND_STR(RND(14, 24))," +" RND(100, 10000)," +" string);" +" END LOOP;" +" COMMIT WORK;" +"" +" FOR i IN 1 .. n_warehouses LOOP" +" COMMIT WORK;" +" PRINTF('Starting to populate warehouse number ', i);" +" INSERT INTO WAREHOUSE VALUES (TO_BINARY(i, 2)," +" RND_STR(RND(6, 10))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(2)," +" CONCAT(SUBSTR(TO_CHAR(RND(0, 9999))," +" 6, 4)," +" '11111')," +" RND(0, 2000)," +" 0," +" 0);" +" FOR j IN 1 .. n_items LOOP" +"" +" rnd1 := RND(26, 50);" +" string := RND_STR(rnd1);" +"" +" IF (RND(0, 99) < 10) THEN" +" rnd2 := RND(0, rnd1 - 8);" +" REPLSTR(string, 'ORIGINAL', rnd2, 8);" +" END IF; " +"" +" INSERT INTO STOCK VALUES (TO_BINARY(j, 3)," +" TO_BINARY(i, 2)," +" 91," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" RND_STR(24)," +" 0, 0, 0," +" string);" +" END LOOP;" + ; + + str2 = +" FOR j IN 1 .. n_districts LOOP" +"" +" /* PRINTF('Starting to populate district number ', j); */" +" INSERT INTO DISTRICT VALUES (TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" RND_STR(RND(6, 10))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(2)," +" CONCAT(SUBSTR(" +" TO_CHAR(RND(0, 9999))," +" 6, 4)," +" '11111')," +" RND(0, 2000)," +" 0," +" 0," +" 3001);" +"" +" FOR k IN 1 .. n_customers LOOP" +"" +" string := 'GC';" +"" +" IF (RND(0, 99) < 10) THEN" +" string := 'BC';" +" END IF;" +" " +" INSERT INTO CUSTOMER VALUES (" +" TO_BINARY(k, 3)," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" RND_STR(RND(8, 16))," +" 'OE'," +" CONCAT('NAME'," +" TO_CHAR(k / 3))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(RND(10, 20))," +" RND_STR(2)," +" CONCAT(SUBSTR(" +" TO_CHAR(RND(0, 9999))," +" 6, 4)," +" '11111')," +" RND_STR(16)," +" SYSDATE(), 0," +" string," +" 0, 5000000," +" RND(0, 5000)," +" 0, 0, 0, 0, 0, 0," +" RND_STR(RND(300, 500)));" + ; + + str3 = +" INSERT INTO HISTORY VALUES (" +" TO_BINARY(k, 3)," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" SYSDATE()," +" 1000," +" RND_STR(RND(12, 24)));" +"" +" rnd1 := RND(5, 15);" +"" +" INSERT INTO ORDERS VALUES (" +" k," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" TO_BINARY(k, 3)," +" SYSDATE()," +" RND(1, 10)," +" rnd1," +" '1');" +"" +" FOR t IN 1 .. rnd1 LOOP" +" INSERT INTO ORDER_LINE VALUES (" +" k," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2)," +" TO_BINARY(t, 1)," +" TO_BINARY(" +" RND(1, n_items)," +" 3)," +" TO_BINARY(i, 2)," +" NULL," +" 91," +" RND(0, 9999)," +" RND_STR(24));" +" END LOOP;" +" END LOOP;" +" " +" FOR k IN 1 /* + (2 * n_customers) / 3 */" +" .. n_customers LOOP" +" " +" INSERT INTO NEW_ORDER VALUES (" +" k," +" TO_BINARY(j + 47, 1)," +" TO_BINARY(i, 2));" +" END LOOP;" +" END LOOP;" +" END LOOP;" +"" +" COMMIT WORK;" +"" +" PRINTF('Populating TPC-D tables');" +"" +" FOR i IN 0 .. 4 LOOP" +" /* We set the last columns to a long character string, to" +" reduce latch contention on region and nation database pages." +" A similar effect could be achieved by setting the page" +" fillfactor in these tables low. */" +"" +" INSERT INTO REGION VALUES (i, CONCAT('Region', TO_CHAR(i)," +" ' ')," +" RND_STR(1500 + RND(1, 152)));" +" FOR j IN i * 5 .. i * 5 + 4 LOOP" +" INSERT INTO NATION VALUES (j," +" CONCAT('Nation', TO_CHAR(j)," +" ' ')," +" i, RND_STR(1500 + RND(1, 152)));" +" INSERT INTO NATION_2 VALUES (j," +" CONCAT('Nation', TO_CHAR(j)," +" ' ')," +" i, RND_STR(1500 + RND(1, 152)));" +" END LOOP;" +" END LOOP;" +"" +" COMMIT WORK;" +"" +" FOR i IN 0 .. n_customers_d / 15 LOOP" +" INSERT INTO SUPPLIER VALUES (i," +" CONCAT('Supplier', TO_CHAR(i))," +" RND_STR(RND(20, 30))," +" RND(0, 24)," +" RND_STR(15)," +" RND(1, 1000)," +" RND_STR(RND(40, 80)));" +" END LOOP;" +"" +" COMMIT WORK;" +"" +" FOR i IN 0 .. n_customers_d - 1 LOOP" +" IF ((i / 100) * 100 = i) THEN" +" COMMIT WORK;" +" PRINTF('Populating customer ', i);" +" END IF;" +"" +" INSERT INTO CUSTOMER_D VALUES (i," +" CONCAT('Customer', TO_CHAR(i))," +" RND_STR(RND(20, 30))," +" RND(0, 24)," +" RND_STR(15)," +" RND(1, 1000)," +" RND_STR(10)," +" RND_STR(RND(50, 100)));" +"" +" FOR j IN i * 10 .. i * 10 + 9 LOOP" +"" +" rnd := (j * 2400) / (10 * n_customers_d);" +"" +" INSERT INTO ORDERS_D VALUES (j," +" 3 * RND(0, (n_customers_d / 3) - 1)" +" + RND(1, 2)," +" 'F', 1000," +" rnd," +" RND_STR(10)," +" CONCAT('Clerk', TO_CHAR(RND(0, 1000)))," +" 0, RND_STR(RND(3, 7)));" +"" +" FOR k IN 0 .. RND(0, 6) LOOP" +" INSERT INTO LINEITEM VALUES (j," +" RND(1, 1000)," +" RND(0, n_customers_d / 15)," +" k," +" RND(1, 50)," +" 100," +" 5," +" RND(0, 8)," +" 'N'," +" 'F'," +" rnd + RND(1, 100)," +" rnd + RND(1, 100)," +" rnd + RND(1, 100)," +" RND_STR(1)," +" RND_STR(1)," +" RND_STR(RND(1, 3)));" +" END LOOP;" +" END LOOP;" +"" +" END LOOP;" +"" +" COMMIT WORK;" +" PRINTF('TPC-D tables populated');" +"" +" PRINTF('Populating join test tables');" +" FOR i IN 1 .. 1 LOOP" +" INSERT INTO JTEST1 VALUES (i, i);" +" INSERT INTO JTEST2 VALUES (i, i);" +" END LOOP;" +" PRINTF('Join test tables populated');" +"" +" COMMIT WORK;" +" END;" + ; + + str4 = ut_str_catenate(str1, str2); + populate_str = ut_str_catenate(str4, str3); + + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE PRINT_TABLES () IS" +" i INT;" +" BEGIN" +"" +" /* PRINTF('Printing ITEM table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM ITEM;" +"" +" PRINTF('Printing WAREHOUSE table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM WAREHOUSE;" +"" +" PRINTF('Printing STOCK table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM STOCK;" +"" +" PRINTF('Printing DISTRICT table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM DISTRICT;" +"" +" PRINTF('Printing CUSTOMER table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM CUSTOMER;" +"" +" PRINTF('Printing HISTORY table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM HISTORY;" +"" +" PRINTF('Printing ORDERS table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM ORDERS;" +"" +" PRINTF('Printing ORDER_LINE table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM ORDER_LINE" +" WHERE OL_O_ID >= 3000; */" +"" +" PRINTF('Printing NEW_ORDER table:');" +"" +" ROW_PRINTF" +" SELECT *" +" FROM NEW_ORDER;" +"" +" COMMIT WORK;" +" END;" + ; + + print_str = str; + /*-----------------------------------------------------------*/ + commit_str = + +" PROCEDURE COMMIT_TEST () IS" +" " +" BEGIN" +" COMMIT WORK;" +" END;" + ; + + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE NEW_ORDER (c_w_id IN CHAR," +" c_d_id IN CHAR," +" c_id IN CHAR," +" ol_supply_w_ids IN CHAR," +" ol_i_ids IN CHAR," +" ol_quantities IN CHAR," +" c_last OUT CHAR," +" c_credit OUT CHAR," +" c_discount OUT INT," +" w_tax OUT INT," +" d_tax OUT INT," +" o_ol_count OUT INT," +" o_id OUT INT," +" o_entry_d OUT INT," +" total OUT INT," +" i_names OUT CHAR," +" s_quantities OUT CHAR," +" bg OUT CHAR," +" i_prices OUT CHAR," +" ol_amounts OUT CHAR) IS" +"" +" i INT;" +" j INT;" +" o_all_local CHAR;" +" i_price INT;" +" i_name CHAR;" +" i_data CHAR;" +" s_quantity INT;" +" s_data CHAR;" +" s_dist_01 CHAR;" +" s_dist_02 CHAR;" +" s_dist_03 CHAR;" +" s_dist_04 CHAR;" +" s_dist_05 CHAR;" +" s_dist_06 CHAR;" +" s_dist_07 CHAR;" +" s_dist_08 CHAR;" +" s_dist_09 CHAR;" +" s_dist_10 CHAR;" +" ol_i_id CHAR;" +" ol_quantity INT;" +" ol_amount INT;" +" ol_supply_w_id CHAR;" +" ol_dist_info CHAR;" +"" +" DECLARE CURSOR district_cursor IS" +" SELECT D_NEXT_O_ID, D_TAX" +" FROM DISTRICT" +" WHERE D_ID = c_d_id AND D_W_ID = c_w_id" +" FOR UPDATE;" +"" +" DECLARE CURSOR stock_cursor IS" +" SELECT S_QUANTITY, S_DATA," +" S_DIST_01, S_DIST_02, S_DIST_03, S_DIST_04," +" S_DIST_05, S_DIST_06, S_DIST_07, S_DIST_08," +" S_DIST_09, S_DIST_10" +" FROM STOCK" +" WHERE S_W_ID = ol_supply_w_id AND S_I_ID = ol_i_id" +" FOR UPDATE;" + ; + str2 = + +" BEGIN" +" FOR j IN 1 .. 1 LOOP" +"" +" /* PRINTF('Warehouse ', BINARY_TO_NUMBER(c_w_id)); */" +" o_all_local := '1';" +" i_names := '12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "1234567890';" +" s_quantities := '12345678901234567890123456789012345678901234567890" + "1234567890';" +" i_prices := '12345678901234567890123456789012345678901234567890" + "1234567890';" +" ol_amounts := '12345678901234567890123456789012345678901234567890" + "1234567890';" +" bg := 'GGGGGGGGGGGGGGG';" +" total := 0;" +"" +" SELECT C_DISCOUNT, C_LAST, C_CREDIT INTO c_discount, c_last, c_credit" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id AND C_ID = c_id;" +"" +" OPEN district_cursor;" +"" +" FETCH district_cursor INTO o_id, d_tax;" +"" +" UPDATE DISTRICT SET D_NEXT_O_ID = o_id + 1" +" WHERE CURRENT OF district_cursor;" +"" +" CLOSE district_cursor;" +"" +"" + ; + str3 = + +" o_ol_count := LENGTH(ol_quantities);" +"" +" /* PRINTF('C-WAREHOUSE id ', BINARY_TO_NUMBER(c_w_id)," +" ' C-district id ', c_d_id," +" ' order id ', o_id, ' linecount ', o_ol_count); */" +"" +" FOR i IN 0 .. (o_ol_count - 1) LOOP" +"" +" ol_i_id := SUBSTR(ol_i_ids, 3 * i, 3);" +" ol_supply_w_id := SUBSTR(ol_supply_w_ids, 2 * i, 2);" +" ol_quantity := BINARY_TO_NUMBER(SUBSTR(ol_quantities, i, 1));" +"" +" /* PRINTF('ol_i_id ', BINARY_TO_NUMBER(ol_i_id)," +" ' ol_supply_w_id ', BINARY_TO_NUMBER(ol_supply_w_id)," +" ' ol_quantity ', ol_quantity); */" +"" +" SELECT I_PRICE, I_NAME, I_DATA INTO i_price, i_name, i_data" +" FROM ITEM" +" WHERE I_ID = ol_i_id" +" CONSISTENT READ;" +"" +" IF (SQL % NOTFOUND) THEN" +" /* PRINTF('Rolling back; item not found: '," +" BINARY_TO_NUMBER(ol_i_id)); */" +" ROLLBACK WORK;" +" o_ol_count := 0;" +"" +" RETURN;" +" END IF;" +"" +" OPEN stock_cursor;" +"" +" FETCH stock_cursor INTO s_quantity, s_data," +" s_dist_01, s_dist_02, s_dist_03," +" s_dist_04, s_dist_05, s_dist_06," +" s_dist_07, s_dist_08, s_dist_09," +" s_dist_10;" +"" +" /* PRINTF('Stock quantity ', s_quantity); */" +"" +" IF (s_quantity >= ol_quantity + 10) THEN" +" s_quantity := s_quantity - ol_quantity;" +" ELSE" +" s_quantity := (s_quantity + 91) - ol_quantity;" +" END IF;" +"" +" UPDATE STOCK SET S_QUANTITY = s_quantity," +" S_YTD = S_YTD + ol_quantity," +" S_ORDER_CNT = S_ORDER_CNT + 1" + " WHERE CURRENT OF stock_cursor;" +"" +" IF (ol_supply_w_id <> c_w_id) THEN" +"" +" o_all_local := '0';" +" PRINTF('Remote order '," +" BINARY_TO_NUMBER(ol_supply_w_id), ' '," +" BINARY_TO_NUMBER(c_w_id));" +"" +" UPDATE STOCK SET S_REMOTE_CNT = S_REMOTE_CNT + 1" +" WHERE CURRENT OF stock_cursor;" +" END IF;" +"" +" CLOSE stock_cursor;" +"" +" IF ((INSTR(i_data, 'ORIGINAL') > 0)" +" OR (INSTR(s_data, 'ORIGINAL') > 0)) THEN" +" REPLSTR(bg, 'B', i, 1);" +" END IF;" +"" +" ol_amount := ol_quantity * i_price;" +"" +" total := total + ol_amount;" + ; + str4 = +" IF (c_d_id = '0') THEN" +" ol_dist_info := s_dist_01;" +" ELSIF (c_d_id = '1') THEN" +" ol_dist_info := s_dist_02;" +" ELSIF (c_d_id = '2') THEN" +" ol_dist_info := s_dist_03;" +" ELSIF (c_d_id = '3') THEN" +" ol_dist_info := s_dist_04;" +" ELSIF (c_d_id = '4') THEN" +" ol_dist_info := s_dist_05;" +" ELSIF (c_d_id = '5') THEN" +" ol_dist_info := s_dist_06;" +" ELSIF (c_d_id = '6') THEN" +" ol_dist_info := s_dist_07;" +" ELSIF (c_d_id = '7') THEN" +" ol_dist_info := s_dist_08;" +" ELSIF (c_d_id = '8') THEN" +" ol_dist_info := s_dist_09;" +" ELSIF (c_d_id = '9') THEN" +" ol_dist_info := s_dist_10;" +" END IF;" +"" +" INSERT INTO ORDER_LINE VALUES (o_id, c_d_id, c_w_id," +" TO_BINARY(i + 1, 1), ol_i_id," +" ol_supply_w_id, NULL, ol_quantity," +" ol_amount, ol_dist_info);" +"" +" REPLSTR(i_names, i_name, i * 24, LENGTH(i_name));" +" REPLSTR(s_quantities, TO_BINARY(s_quantity, 4), i * 4, 4);" +" REPLSTR(i_prices, TO_BINARY(i_price, 4), i * 4, 4);" +" REPLSTR(ol_amounts, TO_BINARY(ol_amount, 4), i * 4, 4);" +"" +" /* PRINTF('i_name ', i_name, ' s_quantity ', s_quantity," +" ' i_price ', i_price, ' ol_amount ', ol_amount); */" +" END LOOP;" +"" +" SELECT W_TAX INTO w_tax" +" FROM WAREHOUSE" +" WHERE W_ID = c_w_id;" +"" +" total := (((total * (10000 + w_tax + d_tax)) / 10000)" +" * (10000 - c_discount)) / 10000;" +"" +" o_entry_d := SYSDATE();" +"" +" INSERT INTO ORDERS VALUES (o_id, c_d_id, c_w_id, c_id, o_entry_d," +" NULL, o_ol_count, o_all_local);" +" INSERT INTO NEW_ORDER VALUES (o_id, c_d_id, c_w_id);" +"" +" /* PRINTF('Inserted order lines:');" +" ROW_PRINTF" +" SELECT * FROM ORDER_LINE WHERE OL_O_ID = o_id AND" +" OL_D_ID = c_d_id" +" AND OL_W_ID = c_w_id; */" +" COMMIT WORK;" +" END LOOP;" +" END;" + ; + + str5 = ut_str_catenate(str1, str2); + str6 = ut_str_catenate(str3, str4); + + new_order_str = ut_str_catenate(str5, str6); + + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE PAYMENT (c_w_id IN CHAR) IS" +"" +" i INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" w_id CHAR;" +" w_street_1 CHAR;" +" w_street_2 CHAR;" +" w_city CHAR;" +" w_state CHAR;" +" w_zip CHAR;" +" w_name CHAR;" +" d_id CHAR;" +" d_street_1 CHAR;" +" d_street_2 CHAR;" +" d_city CHAR;" +" d_state CHAR;" +" d_zip CHAR;" +" d_name CHAR;" +" c_d_id CHAR;" +" c_street_1 CHAR;" +" c_street_2 CHAR;" +" c_city CHAR;" +" c_state CHAR;" +" c_zip CHAR;" +" c_id CHAR;" +" c_last CHAR;" +" c_first CHAR;" +" c_middle CHAR;" +" c_phone CHAR;" +" c_credit CHAR;" +" c_credit_lim INT;" +" c_discount INT;" +" c_balance INT;" +" c_since INT;" +" c_data CHAR;" +" byname INT;" +" namecnt INT;" +" amount INT;" +" h_data CHAR;" +" h_date INT;" +" c_more_data CHAR;" +" more_len INT;" +" data_len INT;" +"" +" DECLARE CURSOR warehouse_cursor IS" +" SELECT W_STREET_1, W_STREET_2, W_CITY, W_STATE, W_ZIP, W_NAME" +" FROM WAREHOUSE" +" WHERE W_ID = w_id" +" FOR UPDATE;" +"" +" DECLARE CURSOR district_cursor IS" +" SELECT D_STREET_1, D_STREET_2, D_CITY, D_STATE, D_ZIP, D_NAME" +" FROM DISTRICT" +" WHERE D_W_ID = w_id AND D_ID = d_id" +" FOR UPDATE;" +"" +" DECLARE CURSOR customer_by_name_cursor IS" +" SELECT C_ID" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last" +" ORDER BY C_FIRST ASC;" +"" +" DECLARE CURSOR customer_cursor IS" +" SELECT C_FIRST, C_MIDDLE, C_LAST, C_STREET_1, C_STREET_2," +" C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT," +" C_CREDIT_LIM, C_DISCOUNT, C_BALANCE," +" C_SINCE" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_ID = c_id" +" FOR UPDATE;" + ; + + str2 = + +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 20;" +"" +" byname := RND(1, 100);" +" amount := RND(1, 1000);" +" h_date := SYSDATE();" +" w_id := c_w_id;" +" d_id := TO_BINARY(47 + RND(1, n_districts), 1);" +" c_d_id := TO_BINARY(47 + RND(1, n_districts), 1);" +"" +" IF (byname <= 60) THEN" +" c_last := CONCAT('NAME', TO_CHAR(RND(1, n_customers) / 3));" +"" +" SELECT COUNT(*) INTO namecnt" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last;" +" /* PRINTF('Payment trx: Customer name ', c_last," +" ' namecount ', namecnt); */" +" OPEN customer_by_name_cursor;" +"" +" FOR i IN 1 .. (namecnt + 1) / 2 LOOP" +" FETCH customer_by_name_cursor INTO c_id;" +" END LOOP;" +" /* ASSERT(NOT (customer_by_name_cursor % NOTFOUND)); */" +" " +" CLOSE customer_by_name_cursor;" +" ELSE" +" c_id := TO_BINARY(RND(1, n_customers), 3);" +" END IF;" + + ; + str3 = +"" +" /* PRINTF('Payment for customer ', BINARY_TO_NUMBER(c_w_id), ' '," +" c_d_id, ' ', BINARY_TO_NUMBER(c_id)); */" +" OPEN customer_cursor;" +"" +" FETCH customer_cursor INTO c_first, c_middle, c_last, c_street_1," +" c_street_2, c_city, c_state, c_zip," +" c_phone, c_credit, c_credit_lim," +" c_discount, c_balance, c_since;" +" c_balance := c_balance - amount;" +"" +" OPEN district_cursor;" +"" +" FETCH district_cursor INTO d_street_1, d_street_2, d_city, d_state," +" d_zip, d_name;" +" UPDATE DISTRICT SET D_YTD = D_YTD + amount" +" WHERE CURRENT OF district_cursor;" +"" +" CLOSE district_cursor;" +"" +" OPEN warehouse_cursor;" +"" +" FETCH warehouse_cursor INTO w_street_1, w_street_2, w_city, w_state," +" w_zip, w_name;" +" UPDATE WAREHOUSE SET W_YTD = W_YTD + amount" +" WHERE CURRENT OF warehouse_cursor;" +"" +" CLOSE warehouse_cursor;" +"" +" h_data := CONCAT(w_name, ' ', d_name);" +" " +" IF (c_credit = 'BC') THEN" +" /* PRINTF('Bad customer pays'); */" +"" +" SELECT C_DATA INTO c_data" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_ID = c_id;" +" c_more_data := CONCAT(" +" ' ', TO_CHAR(BINARY_TO_NUMBER(c_id))," +" ' ', c_d_id," +" ' ', TO_CHAR(BINARY_TO_NUMBER(c_w_id))," +" ' ', d_id," +" ' ', TO_CHAR(BINARY_TO_NUMBER(w_id))," +" TO_CHAR(amount)," +" TO_CHAR(h_date)," +" ' ', h_data);" +"" +" more_len := LENGTH(c_more_data);" +" data_len := LENGTH(c_data);" +" " +" IF (more_len + data_len > 500) THEN" +" data_len := 500 - more_len;" +" END IF;" +" " +" c_data := CONCAT(c_more_data, SUBSTR(c_data, 0, data_len));" +" " +" UPDATE CUSTOMER SET C_BALANCE = c_balance," +" C_PAYMENT_CNT = C_PAYMENT_CNT + 1," +" C_YTD_PAYMENT = C_YTD_PAYMENT + amount," +" C_DATA = c_data" +" WHERE CURRENT OF customer_cursor;" +" ELSE" +" UPDATE CUSTOMER SET C_BALANCE = c_balance," +" C_PAYMENT_CNT = C_PAYMENT_CNT + 1," +" C_YTD_PAYMENT = C_YTD_PAYMENT + amount" +" WHERE CURRENT OF customer_cursor;" +" END IF;" +"" +" CLOSE customer_cursor;" +" " +" INSERT INTO HISTORY VALUES (c_d_id, c_w_id, c_id, d_id, w_id," +" h_date, amount, h_data);" +" COMMIT WORK;" +"" +" END;" + + ; + + str4 = ut_str_catenate(str1, str2); + payment_str = ut_str_catenate(str4, str3); + + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE ORDER_STATUS (c_w_id IN CHAR) IS" +"" +" i INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" d_id CHAR;" +" namecnt INT;" +" c_d_id CHAR;" +" c_id CHAR;" +" c_last CHAR;" +" c_first CHAR;" +" c_middle CHAR;" +" c_balance INT;" +" byname INT;" +" o_id INT;" +" o_carrier_id CHAR;" +" o_entry_d INT;" +" ol_i_id CHAR;" +" ol_supply_w_id CHAR;" +" ol_quantity INT;" +" ol_amount INT;" +" ol_delivery_d INT;" +"" +" DECLARE CURSOR orders_cursor IS" +" SELECT O_ID, O_CARRIER_ID, O_ENTRY_D" +" FROM ORDERS" +" WHERE O_W_ID = c_w_id AND O_D_ID = c_d_id" +" AND O_C_ID = c_id" +" ORDER BY O_ID DESC;" +"" +" DECLARE CURSOR order_line_cursor IS" +" SELECT OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT," +" OL_DELIVERY_D" +" FROM ORDER_LINE" +" WHERE OL_W_ID = c_w_id AND OL_D_ID = c_d_id" +" AND OL_O_ID = o_id;" +" DECLARE CURSOR customer_by_name_cursor IS" +" SELECT C_ID" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last" +" ORDER BY C_FIRST ASC;" +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 20;" +"" +" byname := RND(1, 100);" +"" + ; + + str2 = + +" IF (byname <= 60) THEN" +" d_id := TO_BINARY(47 + RND(1, n_districts), 1); " +"" +" c_d_id := d_id;" +"" +" c_last := CONCAT('NAME', TO_CHAR(RND(1, n_customers) / 3));" +"" +" SELECT COUNT(*) INTO namecnt" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id" +" AND C_LAST = c_last;" +" OPEN customer_by_name_cursor;" +"" +" /* PRINTF('Order status trx: Customer name ', c_last," +" ' namecount ', namecnt); */" +" FOR i IN 1 .. (namecnt + 1) / 2 LOOP" +" FETCH customer_by_name_cursor INTO c_id;" +" END LOOP;" +" /* ASSERT(NOT (customer_by_name_cursor % NOTFOUND)); */" +"" +" CLOSE customer_by_name_cursor;" +" ELSE" +" c_d_id := TO_BINARY(47 + RND(1, n_districts), 1);" +" c_id := TO_BINARY(RND(1, n_customers), 3);" +" END IF;" +"" +" SELECT C_BALANCE, C_FIRST, C_MIDDLE, C_LAST INTO c_balance, c_first," +" c_middle, c_last" +" FROM CUSTOMER" +" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id AND C_ID = c_id;" +"" +" OPEN orders_cursor;" +"" +" FETCH orders_cursor INTO o_id, o_carrier_id, o_entry_d;" +"" +" IF (orders_cursor % NOTFOUND) THEN" +" PRINTF('Order status trx: customer has no order');" +" CLOSE orders_cursor;" +"" +" COMMIT WORK;" +"" +" RETURN;" +" END IF;" +"" +" CLOSE orders_cursor;" +"" +" OPEN order_line_cursor;" +"" +" FOR i IN 0 .. 15 LOOP" +" FETCH order_line_cursor INTO ol_i_id, ol_supply_w_id," +" ol_quantity, ol_amount," +" ol_delivery_d;" +"" +" IF (order_line_cursor % NOTFOUND) THEN" +" CLOSE order_line_cursor;" +"" +" COMMIT WORK;" +"" +" RETURN;" +" END IF;" +" END LOOP;" +" ASSERT(0 = 1);" +" " +" END;" + ; + + order_status_str = ut_str_catenate(str1, str2); + /*-----------------------------------------------------------*/ + + str1 = + +" PROCEDURE DELIVERY (w_id IN CHAR) IS" +"" +" i INT;" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" d_id CHAR;" +" c_id CHAR;" +" o_id INT;" +" o_carrier_id INT;" +" ol_delivery_d INT;" +" ol_total INT;" +"" +" DECLARE CURSOR new_order_cursor IS" +" SELECT NO_O_ID" +" FROM NEW_ORDER" +" WHERE NO_W_ID = w_id AND NO_D_ID = d_id" +" ORDER BY NO_O_ID ASC;" +"" +" DECLARE CURSOR orders_cursor IS" +" SELECT O_C_ID" +" FROM ORDERS" +" WHERE O_W_ID = w_id AND O_D_ID = d_id" +" AND O_ID = o_id" +" FOR UPDATE;" +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 20;" +"" +" o_carrier_id := RND(1, 10);" +" ol_delivery_d := SYSDATE();" + + ; + + str2 = + +" FOR i IN 1 .. n_districts LOOP" +"" +" d_id := TO_BINARY(47 + i, 1);" +"" +" OPEN new_order_cursor;" +"" +" FETCH new_order_cursor INTO o_id;" +"" +" IF (new_order_cursor % NOTFOUND) THEN" +" /* PRINTF('No order to deliver'); */" +"" +" CLOSE new_order_cursor;" +" ELSE" +" CLOSE new_order_cursor;" +"" +" DELETE FROM NEW_ORDER" +" WHERE NO_W_ID = w_id AND NO_D_ID = d_id" +" AND NO_O_ID = o_id;" +" OPEN orders_cursor;" +"" +" FETCH orders_cursor INTO c_id;" +"" +" UPDATE ORDERS SET O_CARRIER_ID = o_carrier_id" +" WHERE CURRENT OF orders_cursor;" +"" +" CLOSE orders_cursor;" +"" +" UPDATE ORDER_LINE SET OL_DELIVERY_D = ol_delivery_d" +" WHERE OL_W_ID = w_id AND OL_D_ID = d_id" +" AND OL_O_ID = o_id;" +"" +" SELECT SUM(OL_AMOUNT) INTO ol_total" +" FROM ORDER_LINE" +" WHERE OL_W_ID = w_id AND OL_D_ID = d_id" +" AND OL_O_ID = o_id;" +"" +" UPDATE CUSTOMER SET C_BALANCE = C_BALANCE - ol_total" +" WHERE C_W_ID = w_id AND C_D_ID = d_id" +" AND C_ID = c_id;" +" END IF;" +" END LOOP;" +" COMMIT WORK;" +"" +" " +" END;" + ; + + delivery_str = ut_str_catenate(str1, str2); + + /*-----------------------------------------------------------*/ + + str = + +" PROCEDURE STOCK_LEVEL (w_id IN CHAR) IS" +"" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" d_id CHAR;" +" o_id INT;" +" stock_count INT;" +" threshold INT;" +"" +" BEGIN" +"" +" n_items := 200;" +" n_warehouses := 1;" +" n_districts := 10;" +" n_customers := 20;" +"" +" d_id := TO_BINARY(47 + 4, 1);" +"" +" threshold := RND(10, 20);" +"" +" SELECT D_NEXT_O_ID INTO o_id" +" FROM DISTRICT" +" WHERE D_W_ID = w_id AND D_ID = d_id;" +"" +" /* NOTE: COUNT(DISTINCT ...) not implemented yet: if we used a hash" +" table, the DISTINCT operation should take at most 15 % more time */" +"" +" SELECT COUNT(*) INTO stock_count" +" FROM ORDER_LINE, STOCK" +" WHERE OL_W_ID = w_id AND OL_D_ID = d_id" +" AND OL_O_ID >= o_id - 10 AND OL_O_ID < o_id" +" AND S_W_ID = w_id AND S_I_ID = OL_I_ID" +" AND S_QUANTITY < threshold" +" CONSISTENT READ;" +" /* PRINTF(stock_count, ' items under threshold ', threshold); */" +" COMMIT WORK;" +"" +" END;" + ; + + stock_level_str = str; + + /*-----------------------------------------------------------*/ + + str = + +" PROCEDURE TPC_CONSISTENCY () IS" +"" +" n_items INT;" +" n_warehouses INT;" +" n_districts INT;" +" n_customers INT;" +" n_orders INT;" +" n_new_orders INT;" +" n_order_lines INT;" +" n_history INT;" +" sum_order_quant INT;" +" sum_stock_quant INT;" +" n_delivered INT;" +" n INT;" +" n_new_order_lines INT;" +" n_customers_d INT;" +" n_regions INT;" +" n_nations INT;" +" n_suppliers INT;" +" n_orders_d INT;" +" n_lineitems INT;" +"" +" BEGIN" +"" +" PRINTF('TPC-C consistency check begins');" +"" +" SELECT COUNT(*) INTO n_warehouses" +" FROM WAREHOUSE;" +" SELECT COUNT(*) INTO n_items" +" FROM ITEM;" +" SELECT COUNT(*) INTO n_customers" +" FROM CUSTOMER;" +" SELECT COUNT(*) INTO n_districts" +" FROM DISTRICT;" +" SELECT COUNT(*) INTO n_orders" +" FROM ORDERS;" +" SELECT COUNT(*) INTO n_new_orders" +" FROM NEW_ORDER;" +" SELECT COUNT(*) INTO n_order_lines" +" FROM ORDER_LINE;" +" SELECT COUNT(*) INTO n_history" +" FROM HISTORY;" +"" +" PRINTF('N warehouses ', n_warehouses);" +"" +" PRINTF('N items ', n_items, ' : ', n_items / n_warehouses," +" ' per warehouse');" +" PRINTF('N districts ', n_districts, ' : ', n_districts / n_warehouses," +" ' per warehouse');" +" PRINTF('N customers ', n_customers, ' : ', n_customers / n_districts," +" ' per district');" +" PRINTF('N orders ', n_orders, ' : ', n_orders / n_customers," +" ' per customer');" +" PRINTF('N new orders ', n_new_orders, ' : '," +" n_new_orders / n_customers, ' per customer');" +" PRINTF('N order lines ', n_order_lines, ' : '," +" n_order_lines / n_orders, ' per order');" +" PRINTF('N history ', n_history, ' : '," +" n_history / n_customers, ' per customer');" +" SELECT COUNT(*) INTO n_delivered" +" FROM ORDER_LINE" +" WHERE OL_DELIVERY_D < NULL;" +"" +" PRINTF('N delivered order lines ', n_delivered);" +"" +" SELECT COUNT(*) INTO n_new_order_lines" +" FROM NEW_ORDER, ORDER_LINE" +" WHERE NO_O_ID = OL_O_ID AND NO_D_ID = OL_D_ID" +" AND NO_W_ID = OL_W_ID;" +" PRINTF('N new order lines ', n_new_order_lines);" +"" +" SELECT COUNT(*) INTO n" +" FROM NEW_ORDER, ORDER_LINE" +" WHERE NO_O_ID = OL_O_ID AND NO_D_ID = OL_D_ID" +" AND NO_W_ID = OL_W_ID AND OL_DELIVERY_D < NULL;" +" PRINTF('Assertion 1');" +" ASSERT(n = 0);" +"" +" SELECT COUNT(*) INTO n" +" FROM NEW_ORDER, ORDER_LINE" +" WHERE NO_O_ID = OL_O_ID AND NO_D_ID = OL_D_ID" +" AND NO_W_ID = OL_W_ID AND OL_DELIVERY_D = NULL;" +"" +" PRINTF('Assertion 2');" +" ASSERT(n = n_new_order_lines);" +" PRINTF('Assertion 2B');" +" ASSERT(n_delivered + n_new_order_lines = n_order_lines);" +"" +" PRINTF('Assertion 3');" +" /* ASSERT(n_orders <= n_history); */" +" PRINTF('Assertion 4');" +" ASSERT(n_order_lines <= 15 * n_orders);" +" PRINTF('Assertion 5');" +" ASSERT(n_order_lines >= 5 * n_orders);" +" PRINTF('Assertion 6');" +" ASSERT(n_new_orders <= n_orders);" +"" +" SELECT SUM(OL_QUANTITY) INTO sum_order_quant" +" FROM ORDER_LINE;" +" SELECT SUM(S_QUANTITY) INTO sum_stock_quant" +" FROM STOCK;" +" PRINTF('Sum order quant ', sum_order_quant, ' sum stock quant '," +" sum_stock_quant);" +"" +" PRINTF('Assertion 7');" +" ASSERT(((sum_stock_quant + sum_order_quant) / 91) * 91" +" = sum_stock_quant + sum_order_quant);" +" COMMIT WORK;" +" PRINTF('TPC-C consistency check passed');" +"" +" PRINTF('TPC-D consistency check begins');" +"" +" SELECT COUNT(*) INTO n_customers_d" +" FROM CUSTOMER_D" +" CONSISTENT READ;" +" SELECT COUNT(*) INTO n_nations" +" FROM NATION" +" CONSISTENT READ;" +" SELECT COUNT(*) INTO n_regions" +" FROM REGION" +" CONSISTENT READ;" +" SELECT COUNT(*) INTO n_suppliers" +" FROM SUPPLIER" +" CONSISTENT READ;" +" SELECT COUNT(*) INTO n_orders_d" +" FROM ORDERS_D" +" CONSISTENT READ;" +" SELECT COUNT(*) INTO n_lineitems" +" FROM LINEITEM" +" CONSISTENT READ;" +"" +" PRINTF('N customers TPC-D ', n_customers_d);" +"" +" PRINTF('N nations ', n_nations);" +" PRINTF('N regions ', n_regions);" +"" +" PRINTF('N suppliers ', n_suppliers);" +" PRINTF('N orders TPC-D ', n_orders_d);" +"" +" PRINTF('N lineitems ', n_lineitems, ' : '," +" n_lineitems / n_orders_d, ' per order');" +" SELECT COUNT(*) INTO n" +" FROM NATION, NATION_2" +" WHERE N_NAME = N2_NAME" +" CONSISTENT READ;" +"" +" PRINTF('Assertion D1');" +" ASSERT(n = n_nations);" +"" +" SELECT COUNT(*) INTO n" +" FROM NATION, REGION" +" WHERE N_REGIONKEY = R_REGIONKEY" +" CONSISTENT READ;" +"" +" PRINTF('Assertion D2');" +" ASSERT(n = n_nations);" +"" +" SELECT COUNT(*) INTO n" +" FROM ORDERS_D, CUSTOMER_D" +" WHERE O_CUSTKEY = C_CUSTKEY" +" CONSISTENT READ;" +"" +" PRINTF('Assertion D3');" +" ASSERT(n = n_orders_d);" +"" +" SELECT COUNT(*) INTO n" +" FROM LINEITEM, SUPPLIER" +" WHERE L_SUPPKEY = S_SUPPKEY" +" CONSISTENT READ;" +"" +" PRINTF('Assertion D4');" +" ASSERT(n = n_lineitems);" +"" +" SELECT COUNT(*) INTO n" +" FROM ORDERS_D" +" WHERE O_ORDERDATE >= 0" +" AND O_ORDERDATE <= 2500" +" CONSISTENT READ;" +"" +" PRINTF('Assertion D5');" +" ASSERT(n = n_orders_d);" +"" +" COMMIT WORK;" +" PRINTF('TPC-D consistency check passed');" +"" +" END;" + ; + + consistency_str = str; + + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE TPC_D_QUERY_5 (startday IN INT, endday IN INT) IS" +"" +" revenue INT;" +" r_name CHAR;" +"" +" BEGIN" +"" +" r_name := CONCAT('Region', TO_CHAR(3), ' ');" +"" +" /* The last join to NATION_2 corresponds to calculating" +" GROUP BY N_NAME in the original TPC-D query. It should take" +" approximately the same amount of CPU time as GROUP BY. */" +"" +" SELECT SUM((L_EXTENDEDPRICE * (100 - L_DISCOUNT)) / 100)" +" INTO revenue" +" FROM REGION, ORDERS_D, CUSTOMER_D, NATION," +" LINEITEM, SUPPLIER, NATION_2" +" WHERE R_NAME = r_name" +" AND O_ORDERDATE >= startday" +" AND O_ORDERDATE < endday" +" AND O_CUSTKEY = C_CUSTKEY" +" AND C_NATIONKEY = N_NATIONKEY" +" AND N_REGIONKEY = R_REGIONKEY" +" AND O_ORDERKEY = L_ORDERKEY" +" AND L_SUPPKEY = S_SUPPKEY" +" AND S_NATIONKEY = C_NATIONKEY" +" AND N_NAME = N2_NAME" +" CONSISTENT READ;" +"" +" PRINTF('Startdate ', startday, '; enddate ', endday," +" ': revenue ', revenue);" +" COMMIT WORK;" +"" +" END;" + ; + + query_5_str = str; + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE ROLLBACK_QUERY () IS" +"" +" BEGIN" +"" +" ROLLBACK WORK;" +"" +" END;" + ; + + rollback_str = str; + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE TEST_LOCK_WAIT () IS" +"" +" w_id CHAR;" +" BEGIN" +"" +" w_id := TO_BINARY(1, 2);" +" UPDATE WAREHOUSE SET W_YTD = W_YTD + 1 WHERE W_ID = w_id;" +"" +" END;" + ; + + lock_wait_str = str; + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE TEST_IBUF () IS" +"" +" i INT;" +" rnd INT;" +" j INT;" +" found INT;" +"" +" DECLARE CURSOR desc_cursor IS" +" SELECT IB_A" +" FROM IBUF_TEST" +" WHERE IB_A >= rnd AND IB_A < rnd + 50" +" ORDER BY IB_A DESC;" +"" +" BEGIN" +"" +" PRINTF('Ibuf QUERY starts!!!!!!');" +" rnd := RND(1, 1000);" +"" +" FOR i IN 1 .. 50 LOOP" +" INSERT INTO IBUF_TEST VALUES (rnd + i," +" RND_STR(RND(1, 2000)));" +" END LOOP;" +" IF (RND(1, 100) < 30) THEN" +" PRINTF('Ibuf rolling back ---!!!');" +" ROLLBACK WORK;" +" END IF;" +"" +"" +" IF (RND(1, 100) < 101) THEN" +" rnd := RND(1, 1000);" +" DELETE FROM IBUF_TEST WHERE IB_A >= rnd " +" AND IB_A <= rnd + 50;" +" END IF;" +"" +" rnd := RND(1, 1000);" +" SELECT COUNT(*) INTO j" +" FROM IBUF_TEST" +" WHERE IB_A >= rnd AND IB_A < rnd + 50;" +"" +" PRINTF('Count: ', j);" +"" +" rnd := RND(1, 1000);" +" UPDATE IBUF_TEST" +" SET IB_B = RND_STR(RND(1, 2000))" +" WHERE IB_A >= rnd AND IB_A < rnd + 50;" +"" +" OPEN desc_cursor;" +"" +" rnd := RND(1, 1000);" +" found := 1;" +" WHILE (found > 0) LOOP" +"" +" FETCH desc_cursor INTO j;" +"" +" IF (desc_cursor % NOTFOUND) THEN" +" found := 0;" +" END IF;" +" END LOOP;" +"" +" CLOSE desc_cursor;" +"" +" IF (RND(1, 100) < 30) THEN" +" PRINTF('Ibuf rolling back!!!');" +" ROLLBACK WORK;" +" ELSE" +" COMMIT WORK;" +" END IF;" +"" +" PRINTF('Ibuf QUERY ends!!!!!!');" +" END;" + ; + + ibuf_test_str = str; + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE TEST_GROUP_COMMIT (w_id IN CHAR) IS" +"" +" i INT;" +"" +" BEGIN" +"" +" FOR i IN 1 .. 200 LOOP" +" UPDATE WAREHOUSE SET W_YTD = W_YTD + 1 WHERE W_ID = w_id;" +" COMMIT WORK;" +" END LOOP;" +" END;" + ; + + test_group_commit_str = str; + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE TEST_SINGLE_ROW_SELECT (" +" i_id IN CHAR," +" i_name OUT CHAR) IS" +" BEGIN" +" SELECT I_NAME INTO i_name" +" FROM ITEM" +" WHERE I_ID = i_id" +" CONSISTENT READ;" +" END;" + ; + + test_single_row_select_str = str; + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE JOIN_TEST () IS" +"" +" n_rows INT;" +" i INT;" +"" +" BEGIN" +"" +" FOR i IN 0 .. 0 LOOP" +" SELECT COUNT(*) INTO n_rows" +" FROM JTEST1, JTEST2" +" WHERE JT2_A = JT1_B" +" CONSISTENT READ;" +" PRINTF(n_rows);" +"" +" COMMIT WORK;" +" END LOOP;" +"" +" END;" + ; + + join_test_str = str; + + /*-----------------------------------------------------------*/ + str = + +" PROCEDURE TEST_ERRORS (switch IN CHAR) IS" +"" +" count INT;" +" val INT;" +"" +" BEGIN" +"" +" IF (switch = '01') THEN" +" /* Test duplicate key error: run this first */" +" ROW_PRINTF SELECT * FROM JTEST1;" +" PRINTF('To insert first');" +" INSERT INTO JTEST1 VALUES (1, 1);" +" PRINTF('To insert second');" +" INSERT INTO JTEST1 VALUES (2, 2);" +" END IF;" +"" +" IF (switch = '02') THEN" +" /* Test duplicate key error: run this second */" +" ROW_PRINTF SELECT * FROM JTEST1;" +" PRINTF('To insert third');" +" INSERT INTO JTEST1 VALUES (3, 3);" +" ROW_PRINTF SELECT * FROM JTEST1;" +" PRINTF('To insert fourth');" +" INSERT INTO JTEST1 VALUES (1, 1);" +" END IF;" +"" +" IF (switch = '03') THEN" +" /* Test duplicate key error: run this third */" +" ROW_PRINTF SELECT * FROM JTEST1;" +" PRINTF('Testing assert');" +" SELECT COUNT(*) INTO count FROM JTEST1;" +" ASSERT(count = 2);" +" END IF;" +"" +" IF (switch = '04') THEN" +" /* Test duplicate key error: run this fourth */" +" ROW_PRINTF SELECT * FROM JTEST1;" +" PRINTF('Testing update');" +" UPDATE JTEST1 SET JT1_A = 3 WHERE JT1_A = 2;" +" PRINTF('Testing update');" +" UPDATE JTEST1 SET JT1_A = 1 WHERE JT1_A = 3;" +" END IF;" +"" +" IF (switch = '05') THEN" +" /* Test deadlock error: run this fifth in thread 1 */" +" COMMIT WORK;" +" PRINTF('Testing update in thread 1');" +" UPDATE JTEST1 SET JT1_B = 3 WHERE JT1_A = 1;" +" END IF;" +"" +" IF (switch = '06') THEN" +" /* Test deadlock error: run this sixth in thread 2 */" +" PRINTF('Testing update in thread 2');" +" UPDATE JTEST1 SET JT1_B = 10 WHERE JT1_A = 2;" +" PRINTF('Testing update in thread 2');" +" UPDATE JTEST1 SET JT1_B = 11 WHERE JT1_A = 1;" +" PRINTF('Update in thread 2 completed');" +" SELECT JT1_B INTO val FROM JTEST1 WHERE JT1_A = 1;" +" ASSERT(val = 11);" +" SELECT JT1_B INTO val FROM JTEST1 WHERE JT1_A = 2;" +" ASSERT(val = 10);" +" COMMIT WORK;" +" END IF;" +"" +" IF (switch = '07') THEN" +" /* Test deadlock error: run this seventh in thread 1 */" +" PRINTF('Testing update in thread 1: deadlock');" +" UPDATE JTEST1 SET JT1_B = 4 WHERE JT1_A = 2;" +" END IF;" +"" +" IF (switch = '08') THEN" +" /* Test deadlock error: run this eighth in thread 1 */" +" PRINTF('Testing update in thread 1: commit');" +" SELECT JT1_B INTO val FROM JTEST1 WHERE JT1_A = 1;" +" ASSERT(val = 3);" +" COMMIT WORK;" +" END IF;" +"" +" END;" + ; + + test_errors_str = str; + /*-----------------------------------------------------------*/ + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &create_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &populate_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLConnect(conn, (UCHAR*)cli_srv_endpoint_name, + (SWORD)ut_strlen(cli_srv_endpoint_name), + (UCHAR*)"use21", 5, (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + /*-----------------------------------------------------------*/ + ret = SQLPrepare(stat, (UCHAR*)create_str, ut_strlen(create_str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + str = "{CREATE_TABLES()}"; + + ret = SQLPrepare(create_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(create_query); + + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + ret = SQLPrepare(stat, (UCHAR*)populate_str, ut_strlen(populate_str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)lock_wait_str, + ut_strlen(lock_wait_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)commit_str, + ut_strlen(commit_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)print_str, + ut_strlen(print_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)new_order_str, + ut_strlen(new_order_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)payment_str, + ut_strlen(payment_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)order_status_str, + ut_strlen(order_status_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)delivery_str, + ut_strlen(delivery_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)stock_level_str, + ut_strlen(stock_level_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)query_5_str, + ut_strlen(query_5_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)consistency_str, + ut_strlen(consistency_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)rollback_str, ut_strlen(rollback_str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)join_test_str, + ut_strlen(join_test_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)test_errors_str, + ut_strlen(test_errors_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)test_single_row_select_str, + ut_strlen(test_single_row_select_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)test_group_commit_str, + ut_strlen(test_group_commit_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLPrepare(stat, (UCHAR*)ibuf_test_str, + ut_strlen(ibuf_test_str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(stat); + + ut_a(ret == SQL_SUCCESS); + + str = "{POPULATE_TABLES(?, ?)}"; + + ret = SQLPrepare(populate_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(populate_query, 1, SQL_PARAM_INPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&n_warehouses_buf, + 4, &n_warehouses_len); + ut_a(ret == SQL_SUCCESS); + + n_warehouses_buf = n_warehouses; + n_warehouses_len = 4; + + ret = SQLBindParameter(populate_query, 2, SQL_PARAM_INPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&n_customers_d_buf, + 4, &n_customers_d_len); + ut_a(ret == SQL_SUCCESS); + + n_customers_d_buf = n_customers_d; + n_customers_d_len = 4; + + ret = SQLExecute(populate_query); + + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + printf("TPC-C test database initialized\n"); + + return(0); +} + +/********************************************************************* +Iterates an SQL query until it returns SQL_SUCCESS. If it returns other +value, rolls back the trx, prints an error message, and tries again. */ + +void +execute_until_success( +/*==================*/ + HSTMT query, /* in: query */ + HSTMT rollback_query) /* in: trx rollback query to run if error */ +{ + RETCODE ret; + UCHAR sql_state[6]; + SDWORD native_error; + UCHAR error_msg[512]; + SWORD error_msg_max = 512; + SWORD error_msg_len; + + for (;;) { + ret = SQLExecute(query); + + if (ret != SQL_SUCCESS) { + ut_a(ret == SQL_ERROR); + + ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, query, + sql_state, &native_error, error_msg, + error_msg_max, &error_msg_len); + + ut_a(ret == SQL_SUCCESS); + + printf("%s\n", error_msg); + + /* Roll back to release trx locks, and try again */ + + ret = SQLExecute(rollback_query); + ut_a(ret == SQL_SUCCESS); + + os_thread_sleep(ut_rnd_gen_ulint() / 1000); + } else { + + return; + } + } +} + +/********************************************************************* +Test for TPC-C. */ + +ulint +test_client( +/*=========*/ + void* arg) /* in: user name as a null-terminated string */ +{ + ulint n_customers = 20; + ulint n_items = 200; + ulint n_lines; + bool put_invalid_item; + HENV env; + HDBC conn; + RETCODE ret; + HSTMT commit_query; + HSTMT new_order_query; + HSTMT payment_query; + HSTMT order_status_query; + HSTMT delivery_query; + HSTMT stock_level_query; + HSTMT print_query; + HSTMT lock_wait_query; + HSTMT join_test_query; + HSTMT test_group_commit_query; + HSTMT rollback_query; + HSTMT ibuf_query; + ulint tm, oldtm; + char* str; + byte c_w_id_buf[2]; + byte c_d_id_buf[1]; + byte c_id_buf[3]; + byte ol_supply_w_ids_buf[30]; + byte ol_i_ids_buf[45]; + byte ol_quantities_buf[15]; + byte c_last_buf[51]; + byte c_credit_buf[3]; + ulint c_discount_buf; + ulint w_tax_buf; + ulint d_tax_buf; + ulint o_ol_count_buf; + ulint o_id_buf; + ulint o_entry_d_buf; + ulint total_buf; + byte i_names_buf[361]; + byte s_quantities_buf[60]; + byte bg_buf[16]; + byte i_prices_buf[60]; + byte ol_amounts_buf[60]; + SDWORD c_w_id_len; + SDWORD c_d_id_len; + SDWORD c_id_len; + SDWORD ol_supply_w_ids_len; + SDWORD ol_i_ids_len; + SDWORD ol_quantities_len; + SDWORD c_last_len; + SDWORD c_credit_len; + SDWORD c_discount_len; + SDWORD w_tax_len; + SDWORD d_tax_len; + SDWORD o_ol_count_len; + SDWORD o_id_len; + SDWORD o_entry_d_len; + SDWORD total_len; + SDWORD i_names_len; + SDWORD s_quantities_len; + SDWORD bg_len; + SDWORD i_prices_len; + SDWORD ol_amounts_len; + ulint i; + ulint k; + ulint t; + + printf("Client thread %s\n", (UCHAR*)arg); + + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &new_order_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &payment_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &order_status_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &delivery_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &stock_level_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &print_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &commit_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &lock_wait_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &join_test_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &test_group_commit_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &rollback_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &ibuf_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLConnect(conn, (UCHAR*)cli_srv_endpoint_name, + (SWORD)ut_strlen(cli_srv_endpoint_name), + (UCHAR*)arg, (SWORD)ut_strlen((char*)arg), + (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + /*-----------------------------------------------------------*/ + str = + "{NEW_ORDER(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," + " ?, ?, ?, ?)}"; + + ret = SQLPrepare(new_order_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf, + 2, &c_w_id_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 2, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_d_id_buf, + 1, &c_d_id_len); + ut_a(ret == SQL_SUCCESS); + + c_d_id_len = 1; + + ret = SQLBindParameter(new_order_query, 3, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_id_buf, + 3, &c_id_len); + ut_a(ret == SQL_SUCCESS); + + c_id_len = 3; + + ret = SQLBindParameter(new_order_query, 4, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, ol_supply_w_ids_buf, + 30, &ol_supply_w_ids_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 5, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, ol_i_ids_buf, + 45, &ol_i_ids_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 6, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, ol_quantities_buf, + 15, &ol_quantities_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 7, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_last_buf, + 50, &c_last_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 8, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, + (byte*)&c_credit_buf, + 2, &c_credit_len); + ut_a(ret == SQL_SUCCESS); + c_credit_buf[2] = '\0'; + + ret = SQLBindParameter(new_order_query, 9, SQL_PARAM_OUTPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&c_discount_buf, + 4, &c_discount_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 10, SQL_PARAM_OUTPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&w_tax_buf, + 4, &w_tax_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 11, SQL_PARAM_OUTPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&d_tax_buf, + 4, &d_tax_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 12, SQL_PARAM_OUTPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&o_ol_count_buf, + 4, &o_ol_count_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 13, SQL_PARAM_OUTPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&o_id_buf, + 4, &o_id_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 14, SQL_PARAM_OUTPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&o_entry_d_buf, + 4, &o_entry_d_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 15, SQL_PARAM_OUTPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)&total_buf, + 4, &total_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 16, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, i_names_buf, + 360, &i_names_len); + ut_a(ret == SQL_SUCCESS); + i_names_buf[360] = '\0'; + + ret = SQLBindParameter(new_order_query, 17, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, s_quantities_buf, + 60, &s_quantities_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 18, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, bg_buf, + 15, &bg_len); + ut_a(ret == SQL_SUCCESS); + bg_buf[15] = '\0'; + + ret = SQLBindParameter(new_order_query, 19, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, i_prices_buf, + 60, &i_prices_len); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(new_order_query, 20, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, ol_amounts_buf, + 60, &ol_amounts_len); + ut_a(ret == SQL_SUCCESS); + + c_w_id_len = 2; + c_w_id_buf[1] = (byte)(2 * atoi((char*)arg + 4)); + c_w_id_buf[0] = (byte)(2 * (atoi((char*)arg + 4) / 256)); + + k = atoi((char*)arg + 4); + + printf("Client thread %lu starts\n", k); + + /*-----------------------------------------------------------*/ + str = "{PAYMENT(?)}"; + + ret = SQLPrepare(payment_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(payment_query, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf, + 2, &c_w_id_len); + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + str = "{ORDER_STATUS(?)}"; + + ret = SQLPrepare(order_status_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(order_status_query, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf, + 2, &c_w_id_len); + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + str = "{DELIVERY(?)}"; + + ret = SQLPrepare(delivery_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(delivery_query, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf, + 2, &c_w_id_len); + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + str = "{STOCK_LEVEL(?)}"; + + ret = SQLPrepare(stock_level_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(stock_level_query, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf, + 2, &c_w_id_len); + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + str = "{ROLLBACK_QUERY()}"; + + ret = SQLPrepare(rollback_query, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + /*-----------------------------------------------------------*/ + + oldtm = ut_clock(); + + for (i = k; i < k + n_rounds / n_users; i++) { + + /* execute_until_success(ibuf_query, rollback_query); */ + + if (i % 100 == 0) { + printf("User %s round %lu\n", (char*)arg, i); + } + + if (!own_warehouse) { + c_w_id_buf[1] = (byte)ut_rnd_interval(1, n_warehouses); + c_w_id_buf[0] = (byte)(ut_rnd_interval(1, n_warehouses) + / 256); + } + + mach_write_to_1(c_d_id_buf, (ut_rnd_interval(1, 10) + 47)); + mach_write_to_3(c_id_buf, ut_rnd_interval(1, n_customers)); + + n_lines = ut_rnd_interval(5, 15); + + if ((15 * k + i) % 100 == 0) { + put_invalid_item = TRUE; + + /* printf("Will put invalid item\n"); */ + } else { + put_invalid_item = FALSE; + } + + for (t = 0; t < n_lines; t++) { + mach_write_to_3(ol_i_ids_buf + 3 * t, + ut_rnd_interval(1, n_items)); + + if (put_invalid_item && (t + 1 == n_lines)) { + mach_write_to_3(ol_i_ids_buf + 3 * t, + n_items + 1); + } + + mach_write_to_1(ol_quantities_buf + t, + ut_rnd_interval(10, 20)); + ut_memcpy(ol_supply_w_ids_buf + 2 * t, c_w_id_buf, 2); + } + + ol_i_ids_len = 3 * n_lines; + ol_quantities_len = n_lines; + ol_supply_w_ids_len = 2 * n_lines; + + execute_until_success(new_order_query, rollback_query); + + if (put_invalid_item) { + + goto skip_prints; + } +/* + c_last_buf[c_last_len] = '\0'; + + printf( + "C_LAST %s, c_credit %s, c_discount, %lu, w_tax %lu, d_tax %lu\n", + c_last_buf, c_credit_buf, w_tax_buf, d_tax_buf); + + printf("o_ol_count %lu, o_id %lu, o_entry_d %lu, total %lu\n", + o_ol_count_buf, o_id_buf, o_entry_d_buf, + total_buf); + + ut_a(c_credit_len == 2); + ut_a(c_discount_len == 4); + ut_a(i_names_len == 360); + + printf("i_names %s, bg %s\n", i_names_buf, bg_buf); + + for (t = 0; t < n_lines; t++) { + printf("s_quantity %lu, i_price %lu, ol_amount %lu\n", + mach_read_from_4(s_quantities_buf + 4 * t), + mach_read_from_4(i_prices_buf + 4 * t), + mach_read_from_4(ol_amounts_buf + 4 * t)); + } +*/ + skip_prints: + ; + + execute_until_success(payment_query, rollback_query); + + if (i % 10 == 3) { + execute_until_success(order_status_query, + rollback_query); + } + + if ((i % 10 == 6) || (i % 100 == 60)) { + execute_until_success(delivery_query, rollback_query); + } + + if (i % 10 == 9) { + execute_until_success(stock_level_query, + rollback_query); + } + } + + tm = ut_clock(); + + printf("Wall time for %lu loops %lu milliseconds\n", + (i - k), tm - oldtm); + +/* execute_until_success(print_query, rollback_query); */ + + n_exited++; + + printf("Client thread %lu exits as the %luth\n", k, n_exited); + + return(0); +} + +/********************************************************************* +Test for single row select. */ + +ulint +test_single_row_select( +/*===================*/ + void* arg) /* in: user name as a null-terminated string */ +{ + ulint n_items = 200; + HENV env; + HDBC conn; + RETCODE ret; + HSTMT single_row_select_query; + ulint tm, oldtm; + char* str; + byte i_id_buf[3]; + byte i_name_buf[25]; + SDWORD i_id_len; + SDWORD i_name_len; + ulint i; + + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn, &single_row_select_query); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLConnect(conn, (UCHAR*)cli_srv_endpoint_name, + (SWORD)ut_strlen(cli_srv_endpoint_name), + (UCHAR*)arg, + (SWORD)ut_strlen((char*)arg), + (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + /*-----------------------------------------------------------*/ + str = + "{TEST_SINGLE_ROW_SELECT(?, ?)}"; + + ret = SQLPrepare(single_row_select_query, (UCHAR*)str, + ut_strlen(str)); + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(single_row_select_query, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, i_id_buf, + 3, &i_id_len); + ut_a(ret == SQL_SUCCESS); + i_id_len = 3; + + ret = SQLBindParameter(single_row_select_query, 2, SQL_PARAM_OUTPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, i_name_buf, + 24, &i_name_len); + ut_a(ret == SQL_SUCCESS); + i_name_buf[24] = '\0'; + + oldtm = ut_clock(); + + for (i = 0; i < 10000; i++) { + + mach_write_to_3(i_id_buf, ut_rnd_interval(1, n_items)); + + ret = SQLExecute(single_row_select_query); + + ut_a(ret == SQL_SUCCESS); + } + + tm = ut_clock(); + + printf("Wall time for %lu single row selects %lu milliseconds\n", + i, tm - oldtm); + return(0); +} + +/********************************************************************* +TPC-D query 5. */ + +ulint +test_tpc_d_client( +/*==============*/ + void* arg) /* in: pointer to an array of startdate and enddate */ +{ + char buf[20]; + HENV env; + HDBC conn1; + RETCODE ret; + HSTMT query5; + HSTMT join_test; + char* str; + SDWORD len1; + SDWORD len2; + ulint i; + ulint tm, oldtm; + + UT_NOT_USED(arg); + + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn1); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn1, &query5); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn1, &join_test); + + ut_a(ret == SQL_SUCCESS); + + sprintf(buf, "Use2%5lu", *((ulint*)arg)); + + ret = SQLConnect(conn1, (UCHAR*)cli_srv_endpoint_name, + (SWORD)ut_strlen(cli_srv_endpoint_name), + (UCHAR*)buf, + (SWORD)9, (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + /*-----------------------------------------------------------*/ + str = "{TPC_D_QUERY_5(?, ?)}"; + + ret = SQLPrepare(query5, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(query5, 1, SQL_PARAM_INPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)arg, + 4, &len1); + ut_a(ret == SQL_SUCCESS); + + len1 = 4; + + ret = SQLBindParameter(query5, 2, SQL_PARAM_INPUT, + SQL_C_LONG, SQL_INTEGER, 0, 0, + (byte*)arg + sizeof(ulint), + 4, &len2); + ut_a(ret == SQL_SUCCESS); + + len2 = 4; + + str = "{JOIN_TEST()}"; + + ret = SQLPrepare(join_test, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + for (i = 0; i < n_rounds; i++) { + + oldtm = ut_clock(); + + ret = SQLExecute(query5); + + /* ret = SQLExecute(join_test); */ + + ut_a(ret == SQL_SUCCESS); + + tm = ut_clock(); + + printf("Wall time %lu milliseconds\n", tm - oldtm); + } + + printf("%s exits\n", buf); + + return(0); +} + +/********************************************************************* +Checks consistency of the TPC databases. */ + +ulint +check_tpc_consistency( +/*==================*/ + void* arg) /* in: user name */ +{ + HENV env; + HDBC conn1; + RETCODE ret; + HSTMT consistency_query1; + char* str; + + UT_NOT_USED(arg); + + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn1); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn1, &consistency_query1); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLConnect(conn1, (UCHAR*)cli_srv_endpoint_name, + (SWORD)ut_strlen(cli_srv_endpoint_name), + (UCHAR*)arg, + (SWORD)ut_strlen((char*)arg), (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + /*-----------------------------------------------------------*/ + str = "{TPC_CONSISTENCY()}"; + + ret = SQLPrepare(consistency_query1, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLExecute(consistency_query1); + + ut_a(ret == SQL_SUCCESS); + + printf("Consistency checked\n"); + + return(0); +} + +/********************************************************************* +Test for errors. */ + +ulint +test_client_errors2( +/*================*/ + void* arg) /* in: ignored */ +{ + HENV env; + HDBC conn1; + RETCODE ret; + HSTMT error_test_query1; + char* str; + byte buf1[2]; + SDWORD len1; + UCHAR sql_state[6]; + SDWORD native_error; + UCHAR error_msg[512]; + SWORD error_msg_max = 512; + SWORD error_msg_len; + + UT_NOT_USED(arg); + + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn1); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn1, &error_test_query1); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLConnect(conn1, (UCHAR*)cli_srv_endpoint_name, + (SWORD)ut_strlen(cli_srv_endpoint_name), + (UCHAR*)"conn2", + (SWORD)5, (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + /*-----------------------------------------------------------*/ + str = "{TEST_ERRORS(?)}"; + + ret = SQLPrepare(error_test_query1, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(error_test_query1, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, buf1, + 2, &len1); + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + + printf("Thread 2 to do update\n"); + + ut_memcpy(buf1, "06", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_SUCCESS); + + printf("Thread 2 has done update\n"); + + ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1, + sql_state, &native_error, error_msg, error_msg_max, + &error_msg_len); + + ut_a(ret == SQL_NO_DATA_FOUND); + + return(0); +} + +/********************************************************************* +Test for errors. */ + +ulint +test_client_errors( +/*===============*/ + void* arg) /* in: ignored */ +{ + HENV env; + HDBC conn1; + RETCODE ret; + HSTMT error_test_query1; + char* str; + byte buf1[2]; + SDWORD len1; + UCHAR sql_state[6]; + SDWORD native_error; + UCHAR error_msg[512]; + SWORD error_msg_max = 512; + SWORD error_msg_len; + os_thread_id_t thread_id; + + UT_NOT_USED(arg); + + ret = SQLAllocEnv(&env); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocConnect(env, &conn1); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLAllocStmt(conn1, &error_test_query1); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLConnect(conn1, (UCHAR*)"innobase", 8, (UCHAR*)"conn1", + (SWORD)5, (UCHAR*)"password", 8); + ut_a(ret == SQL_SUCCESS); + + printf("Connection established\n"); + + /*-----------------------------------------------------------*/ + str = "{TEST_ERRORS(?)}"; + + ret = SQLPrepare(error_test_query1, (UCHAR*)str, ut_strlen(str)); + + ut_a(ret == SQL_SUCCESS); + + ret = SQLBindParameter(error_test_query1, 1, SQL_PARAM_INPUT, + SQL_C_CHAR, SQL_CHAR, 0, 0, buf1, + 2, &len1); + ut_a(ret == SQL_SUCCESS); + + /*-----------------------------------------------------------*/ + + ut_memcpy(buf1, "01", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_SUCCESS); + + ut_memcpy(buf1, "02", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_ERROR); + + ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1, + sql_state, &native_error, error_msg, error_msg_max, + &error_msg_len); + + ut_a(ret == SQL_SUCCESS); + + printf("%s\n", error_msg); + + ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1, + sql_state, &native_error, error_msg, error_msg_max, + &error_msg_len); + + ut_a(ret == SQL_NO_DATA_FOUND); + + ut_memcpy(buf1, "03", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_SUCCESS); + + ut_memcpy(buf1, "01", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_ERROR); + + ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1, + sql_state, &native_error, error_msg, error_msg_max, + &error_msg_len); + + ut_a(ret == SQL_SUCCESS); + + printf("%s\n", error_msg); + + ut_memcpy(buf1, "03", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_SUCCESS); + + ut_memcpy(buf1, "04", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_ERROR); + + ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1, + sql_state, &native_error, error_msg, error_msg_max, + &error_msg_len); + + ut_a(ret == SQL_SUCCESS); + + printf("%s\n", error_msg); + + ut_memcpy(buf1, "03", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_SUCCESS); + + ut_memcpy(buf1, "05", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_SUCCESS); + + os_thread_create(&test_client_errors2, "user000", &thread_id); + + os_thread_sleep(5000000); + + ut_memcpy(buf1, "07", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_ERROR); + + ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1, + sql_state, &native_error, error_msg, error_msg_max, + &error_msg_len); + + ut_a(ret == SQL_SUCCESS); + + printf("%s\n", error_msg); + + printf("Thread 1 to commit\n"); + + ut_memcpy(buf1, "08", 2); + len1 = 2; + ret = SQLExecute(error_test_query1); + ut_a(ret == SQL_SUCCESS); + + return(0); +} + +/************************************************************************* +Simulates disk waits: if there are at least two threads active, +puts the current thread to wait for an event. If there is just the current +thread active and another thread doing a simulated disk wait, puts the +current thread to wait and releases another thread from wait, otherwise does +nothing */ + +void +srv_simulate_disk_wait(void) +/*========================*/ +{ + os_event_t event; + ulint wait_i; + ulint count; + bool found; + ulint rnd; + ulint i; + ulint j; + + mutex_enter(&kernel_mutex); + + srv_disk_rnd += 98687241; + + count = 0; + found = FALSE; + + for (i = 0; i < SRV_N_SIM_DISK_ARRAY; i++) { + + if (!srv_sim_disk[i].empty) { + + count++; + } + + if (!found && srv_sim_disk[i].empty) { + + srv_sim_disk[i].empty = FALSE; + event = srv_sim_disk[i].event; + + os_event_reset(event); + srv_sim_disk[i].event_set = FALSE; + + wait_i = i; + + found = TRUE; + } + } + + ut_a(found); + + if (srv_disk_n_active_threads == count + 1) { + /* We have to release a thread from the disk wait array */; + + rnd = srv_disk_rnd; + + for (i = rnd; i < SRV_N_SIM_DISK_ARRAY + rnd; i++) { + + j = i % SRV_N_SIM_DISK_ARRAY; + + if (!srv_sim_disk[j].empty + && !srv_sim_disk[j].event_set) { + + srv_sim_disk[j].event_set = TRUE; + os_event_set(srv_sim_disk[j].event); + + break; + } + } + } + + mutex_exit(&kernel_mutex); + + os_event_wait(event); + + mutex_enter(&kernel_mutex); + + srv_sim_disk[wait_i].empty = TRUE; + + mutex_exit(&kernel_mutex); +} + +/************************************************************************* +Releases a thread from the simulated disk wait array if there is any to +release. */ + +void +srv_simulate_disk_wait_release(void) +/*================================*/ +{ + ulint rnd; + ulint i; + ulint j; + + mutex_enter(&kernel_mutex); + + srv_disk_rnd += 98687241; + rnd = srv_disk_rnd; + + for (i = rnd; i < SRV_N_SIM_DISK_ARRAY + rnd; i++) { + + j = i % SRV_N_SIM_DISK_ARRAY; + + if (!srv_sim_disk[j].empty + && !srv_sim_disk[j].event_set) { + + srv_sim_disk[j].event_set = TRUE; + os_event_set(srv_sim_disk[j].event); + + break; + } + } + + mutex_exit(&kernel_mutex); +} + +/********************************************************************* +Test for many threads and disk waits. */ + +ulint +test_disk_waits( +/*============*/ + void* arg) /* in: ignored */ +{ + ulint i; + ulint tm, oldtm; + + UT_NOT_USED(arg); + + n_exited++; + + printf("Client thread starts as the %luth\n", n_exited); + + oldtm = ut_clock(); + + mutex_enter(&kernel_mutex); + srv_disk_n_active_threads++; + mutex_exit(&kernel_mutex); + + for (i = 0; i < 133; i++) { + ut_delay(500); + +/* os_thread_yield(); */ + +/* os_thread_sleep(10000); */ + + srv_simulate_disk_wait(); + } + + mutex_enter(&kernel_mutex); + srv_disk_n_active_threads--; + mutex_exit(&kernel_mutex); + + srv_simulate_disk_wait_release(); + + tm = ut_clock(); + + printf("Wall time for %lu loops %lu milliseconds\n", i, tm - oldtm); + + n_exited++; + + printf("Client thread exits as the %luth\n", n_exited); + + return(0); +} + +/************************************************************************* +Reads a keywords and a values from an initfile. In case of an error, exits +from the process. */ + +void +cli_read_initfile( +/*==============*/ + FILE* initfile) /* in: file pointer */ +{ + char str_buf[10000]; + ulint ulint_val; + + srv_read_init_val(initfile, FALSE, "SRV_ENDPOINT_NAME", str_buf, + &ulint_val); + ut_a(ut_strlen(str_buf) < COM_MAX_ADDR_LEN); + + ut_memcpy(cli_srv_endpoint_name, str_buf, COM_MAX_ADDR_LEN); + + srv_read_init_val(initfile, FALSE, "USER_NAME", str_buf, + &ulint_val); + ut_a(ut_strlen(str_buf) < COM_MAX_ADDR_LEN); + + ut_memcpy(cli_user_name, str_buf, COM_MAX_ADDR_LEN); + + srv_read_init_val(initfile, TRUE, "MEM_POOL_SIZE", str_buf, + &mem_pool_size); + + srv_read_init_val(initfile, TRUE, "N_WAREHOUSES", str_buf, + &n_warehouses); + + srv_read_init_val(initfile, TRUE, "N_CUSTOMERS_D", str_buf, + &n_customers_d); + + srv_read_init_val(initfile, TRUE, "IS_TPC_D", str_buf, + &is_tpc_d); + + srv_read_init_val(initfile, TRUE, "N_ROUNDS", str_buf, + &n_rounds); + + srv_read_init_val(initfile, TRUE, "N_USERS", str_buf, + &n_users); + + srv_read_init_val(initfile, TRUE, "STARTDATE", str_buf, + &startdate); + + srv_read_init_val(initfile, TRUE, "ENDDATE", str_buf, + &enddate); + + srv_read_init_val(initfile, TRUE, "OWN_WAREHOUSE", str_buf, + &own_warehouse); +} + +/************************************************************************* +*/ +void +cli_boot( +/*=====*/ + char* name) /* in: the initialization file name */ +{ + FILE* initfile; + + initfile = fopen(name, "r"); + + if (initfile == NULL) { + printf( + "Error in client booting: could not open initfile whose name is %s!\n", + name); + os_process_exit(1); + } + + cli_read_initfile(initfile); + + fclose(initfile); +} + +/******************************************************************** +Main test function. */ + +void +main(void) +/*======*/ +{ + os_thread_t thread_handles[1000]; + os_thread_id_t thread_ids[1000]; + char user_names[1000]; + ulint tm, oldtm; + ulint i; + ulint dates[1000]; + + cli_boot("cli_init"); + + for (i = 1; i <= n_users; i++) { + dates[2 * i] = startdate + + ((enddate - startdate) / n_users) * (i - 1); + dates[2 * i + 1] = startdate + + ((enddate - startdate) / n_users) * i; + } + + sync_init(); + + mem_init(mem_pool_size); + + test_init(NULL); + + check_tpc_consistency("con21"); + +/* test_client_errors(NULL); */ + + os_thread_sleep(4000000); + + printf("Sleep ends\n"); + + oldtm = ut_clock(); + + for (i = 2; i <= n_users; i++) { + if (is_tpc_d) { + thread_handles[i] = os_thread_create(&test_tpc_d_client, + dates + 2 * i, thread_ids + i); + } else { + sprintf(user_names + i * 8, "use2%3lu", i); + + thread_handles[i] = os_thread_create(&test_client, + user_names + i * 8, thread_ids + i); + } + + ut_a(thread_handles[i]); + } + + if (is_tpc_d) { + test_tpc_d_client(dates + 2 * 1); + } else { + test_client("use2 1"); + } + + for (i = 2; i <= n_users; i++) { + os_thread_wait(thread_handles[i]); + + printf("Wait for thread %lu ends\n", i); + } + + tm = ut_clock(); + + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + + os_thread_sleep(4000000); + + printf("Sleep ends\n"); + + test_single_row_select("con99"); + + check_tpc_consistency("con22"); + + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} diff --git a/innobase/btr/ts/tsrecv.c b/innobase/btr/ts/tsrecv.c new file mode 100644 index 00000000000..0f30fcd94f1 --- /dev/null +++ b/innobase/btr/ts/tsrecv.c @@ -0,0 +1,4909 @@ +/************************************************************************ +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 "log0recv.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 3 /* must be >= 2 */ +#define N_FILES 1 +#define FILE_SIZE 512 /* must be > 512 */ +#define POOL_SIZE 1000 +#define IBUF_SIZE 200 +#define COUNTER_OFFSET 1500 + +#define N_LOG_GROUPS 2 +#define N_LOG_FILES 3 +#define LOG_FILE_SIZE 500 + +#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; + ulint i; + + 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 or opens the log files. */ + +void +create_log_files(void) +/*==================*/ +{ + bool ret; + ulint i, k; + char name[20]; + + printf("--------------------------------------------------------\n"); + printf("Create or open log files\n"); + + strcpy(name, "logfile00"); + + for (k = 0; k < N_LOG_GROUPS; k++) { + for (i = 0; i < N_LOG_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_AIO, + &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_AIO, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + 8192 * LOG_FILE_SIZE, 0)); + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k + 100, FIL_LOG); + } + + ut_a(fil_validate()); + + fil_node_create(name, LOG_FILE_SIZE, k + 100); + } + + fil_space_create(name, k + 200, FIL_LOG); + + log_group_init(k, N_LOG_FILES, LOG_FILE_SIZE * UNIV_PAGE_SIZE, + k + 100, k + 200); + } +} + +/************************************************************************* +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 < 2 * N_SPACES; k += 2) { + 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_AIO, &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_AIO, &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, FIL_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); + } +} + +/********************************************************************* +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"); */ + + /* 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); + + 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; + + rnd = 0; + + 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(); + + for (i = 0; i < *((ulint*)arg); i++) { + + dtuple_gen_test_tuple3(row, rnd, DTUPLE_TEST_RND3500, 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 < 5) { + 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; + ulint n5000 = 500; + ulint err; + + oldtm = ut_clock(); + +/* buf_debug_prints = TRUE; */ + log_do_write = TRUE; + log_debug_writes = 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(); + create_log_files(); + + sess_sys_init_at_db_start(); + + mem_validate(); + + /* Tests crash recovery: */ +/* + err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT, + ut_dulint_max); + ut_a(err == DB_SUCCESS); + + recv_compare_spaces_low(0, 4, 100); + + trx_sys_init_at_db_start(); + + dict_boot(); + + recv_recovery_from_checkpoint_finish(); +*/ + /* Tests archive recovery: */ + + err = recv_recovery_from_archive_start(ut_dulint_max, + "ib_arch_log_0_0000000000"); + ut_a(err == DB_SUCCESS); + + recv_compare_spaces_low(0, 4, 500); + + trx_sys_init_at_db_start(); + + dict_boot(); + + recv_recovery_from_archive_finish(); + +/* test4_2(); */ + + log_make_checkpoint_at(ut_dulint_max); + +/* dict_table_print_by_name("SYS_TABLES"); + + dict_table_print_by_name("SYS_COLUMNS"); + + dict_table_print_by_name("SYS_INDEXES"); */ + + dict_table_print_by_name("TS_TABLE1"); + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} diff --git a/innobase/btr/ts/tsrecv97.c b/innobase/btr/ts/tsrecv97.c new file mode 100644 index 00000000000..0f30fcd94f1 --- /dev/null +++ b/innobase/btr/ts/tsrecv97.c @@ -0,0 +1,4909 @@ +/************************************************************************ +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 "log0recv.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 3 /* must be >= 2 */ +#define N_FILES 1 +#define FILE_SIZE 512 /* must be > 512 */ +#define POOL_SIZE 1000 +#define IBUF_SIZE 200 +#define COUNTER_OFFSET 1500 + +#define N_LOG_GROUPS 2 +#define N_LOG_FILES 3 +#define LOG_FILE_SIZE 500 + +#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; + ulint i; + + 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 or opens the log files. */ + +void +create_log_files(void) +/*==================*/ +{ + bool ret; + ulint i, k; + char name[20]; + + printf("--------------------------------------------------------\n"); + printf("Create or open log files\n"); + + strcpy(name, "logfile00"); + + for (k = 0; k < N_LOG_GROUPS; k++) { + for (i = 0; i < N_LOG_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_AIO, + &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_AIO, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + 8192 * LOG_FILE_SIZE, 0)); + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k + 100, FIL_LOG); + } + + ut_a(fil_validate()); + + fil_node_create(name, LOG_FILE_SIZE, k + 100); + } + + fil_space_create(name, k + 200, FIL_LOG); + + log_group_init(k, N_LOG_FILES, LOG_FILE_SIZE * UNIV_PAGE_SIZE, + k + 100, k + 200); + } +} + +/************************************************************************* +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 < 2 * N_SPACES; k += 2) { + 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_AIO, &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_AIO, &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, FIL_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); + } +} + +/********************************************************************* +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"); */ + + /* 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); + + 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; + + rnd = 0; + + 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(); + + for (i = 0; i < *((ulint*)arg); i++) { + + dtuple_gen_test_tuple3(row, rnd, DTUPLE_TEST_RND3500, 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 < 5) { + 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; + ulint n5000 = 500; + ulint err; + + oldtm = ut_clock(); + +/* buf_debug_prints = TRUE; */ + log_do_write = TRUE; + log_debug_writes = 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(); + create_log_files(); + + sess_sys_init_at_db_start(); + + mem_validate(); + + /* Tests crash recovery: */ +/* + err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT, + ut_dulint_max); + ut_a(err == DB_SUCCESS); + + recv_compare_spaces_low(0, 4, 100); + + trx_sys_init_at_db_start(); + + dict_boot(); + + recv_recovery_from_checkpoint_finish(); +*/ + /* Tests archive recovery: */ + + err = recv_recovery_from_archive_start(ut_dulint_max, + "ib_arch_log_0_0000000000"); + ut_a(err == DB_SUCCESS); + + recv_compare_spaces_low(0, 4, 500); + + trx_sys_init_at_db_start(); + + dict_boot(); + + recv_recovery_from_archive_finish(); + +/* test4_2(); */ + + log_make_checkpoint_at(ut_dulint_max); + +/* dict_table_print_by_name("SYS_TABLES"); + + dict_table_print_by_name("SYS_COLUMNS"); + + dict_table_print_by_name("SYS_INDEXES"); */ + + dict_table_print_by_name("TS_TABLE1"); + + tm = ut_clock(); + printf("Wall time for test %lu milliseconds\n", tm - oldtm); + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} diff --git a/innobase/btr/ts/tss.c b/innobase/btr/ts/tss.c new file mode 100644 index 00000000000..4af3fda4415 --- /dev/null +++ b/innobase/btr/ts/tss.c @@ -0,0 +1,397 @@ +/************************************************************************ +Test for the server + +(c) 1996-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 "buf0flu.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 "log0recv.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 "row0sel.h" +#include "row0upd.h" +#include "row0row.h" +#include "lock0lock.h" +#include "ibuf0ibuf.h" +#include "pars0pars.h" +#include "btr0sea.h" + +bool measure_cont = FALSE; + +os_file_t files[1000]; + +mutex_t ios_mutex; +ulint ios; +ulint n[10]; + +mutex_t incs_mutex; +ulint incs; + +byte rnd_buf[67000]; + + +/************************************************************************ +Io-handler thread function. */ + +ulint +handler_thread( +/*===========*/ + void* arg) +{ + ulint segment; + ulint i; + + 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 or opens the log files. */ + +void +create_log_files(void) +/*==================*/ +{ + bool ret; + ulint i, k; + char name[20]; + + printf("--------------------------------------------------------\n"); + printf("Create or open log files\n"); + + strcpy(name, "logfile00"); + + for (k = 0; k < srv_n_log_groups; k++) { + + for (i = 0; i < srv_n_log_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_AIO, + &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_AIO, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + 8192 * srv_log_file_size, 0)); + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k + 100, FIL_LOG); + } + + ut_a(fil_validate()); + + fil_node_create(name, srv_log_file_size, k + 100); + } + + fil_space_create(name, k + 200, FIL_LOG); + + log_group_init(k, srv_n_log_files, + srv_log_file_size * UNIV_PAGE_SIZE, + k + 100, k + 200); + } +} + +/************************************************************************* +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 < 2 * srv_n_spaces; k += 2) { + for (i = 0; i < srv_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_NORMAL, &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_NORMAL, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + UNIV_PAGE_SIZE * srv_file_size, 0)); + /* Initialize the file contents to a random value */ + /* + for (j = 0; j < srv_file_size; j++) { + + for (c = 0; c < UNIV_PAGE_SIZE; c++) { + + rnd_buf[c] = 0xFF; + } + + os_file_write(files[i], rnd_buf, + UNIV_PAGE_SIZE * j, 0, + UNIV_PAGE_SIZE); + } + */ + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k, FIL_TABLESPACE); + } + + ut_a(fil_validate()); + + fil_node_create(name, srv_file_size, k); + } + } + + ios = 0; + + mutex_create(&ios_mutex); + mutex_set_level(&ios_mutex, SYNC_NO_ORDER_CHECK); + + /* Create i/o-handler threads: */ + + for (i = 0; i < 9; i++) { + n[i] = i; + + thr[i] = os_thread_create(handler_thread, n + i, id + i); + } +} + +/************************************************************************ +Inits space header of space. */ + +void +init_spaces(void) +/*=============*/ +{ + mtr_t mtr; + + mtr_start(&mtr); + + fsp_header_init(0, srv_file_size * srv_n_files, &mtr); + + mtr_commit(&mtr); +} + +/********************************************************************* +This thread is used to measure contention of latches. */ + +ulint +test_measure_cont( +/*==============*/ + void* arg) +{ + ulint i, j, k; + ulint count[8]; + ulint lcount[8]; + ulint lscount; + ulint lkcount; + ulint pcount, kcount, scount; + + UT_NOT_USED(arg); + + printf("Starting contention measurement\n"); + + for (i = 0; i < 1000; i++) { + + for (k = 0; k < 8; k++) { + count[k] = 0; + lcount[k] = 0; + } + + pcount = 0; + kcount = 0; + scount = 0; + lscount = 0; + lkcount = 0; + + for (j = 0; j < 100; j++) { + + if (srv_measure_by_spin) { + ut_delay(ut_rnd_interval(0, 20000)); + } else { + os_thread_sleep(20000); + } + + if (kernel_mutex.lock_word) { + kcount++; + } + + if (lock_kernel_reserved) { + lkcount++; + } + + if (buf_pool->mutex.lock_word) { + pcount++; + } + + if (btr_search_mutex.lock_word) { + scount++; + } + + for (k = 0; k < 8; k++) { + + if (btr_search_sys-> + hash_index->mutexes[k].lock_word) { + + count[k]++; + } + } + + for (k = 0; k < 2; k++) { + + if (lock_sys->rec_hash->mutexes[k].lock_word) { + + lcount[k]++; + } + } + + if (kernel_mutex.lock_word + || lock_sys->rec_hash->mutexes[0].lock_word + || lock_sys->rec_hash->mutexes[1].lock_word) { + + lscount++; + } + } + + printf( +"Mutex res. p %lu, k %lu %lu, %lu %lu %lu s %lu, %lu %lu %lu %lu %lu %lu %lu %lu of %lu\n", + pcount, kcount, lkcount, lcount[0], lcount[1], lscount, scount, + count[0], count[1], count[2], count[3], + count[4], count[5], count[6], count[7], j); + + sync_print_wait_info(); + + printf("N log i/os %lu, n non sea %lu, n sea succ %lu\n", + log_sys->n_log_ios, btr_cur_n_non_sea, + btr_search_n_succ); + } + + return(0); +} + +/******************************************************************** +Main test function. */ + +void +main(void) +/*======*/ +{ + os_thread_id_t thread_id; + + log_do_write = TRUE; +/* yydebug = TRUE; */ + + srv_boot("srv_init"); + + os_aio_init(576, 9, 100); + + fil_init(25); + + buf_pool_init(srv_pool_size, srv_pool_size); + + fsp_init(); + log_init(); + + lock_sys_create(srv_lock_table_size); + + create_files(); + create_log_files(); + + init_spaces(); + + sess_sys_init_at_db_start(); + + trx_sys_create(); + + dict_create(); + + log_make_checkpoint_at(ut_dulint_max); + + if (srv_measure_contention) { + os_thread_create(&test_measure_cont, NULL, &thread_id); + } + + if (!srv_log_archive_on) { + + ut_a(DB_SUCCESS == log_archive_noarchivelog()); + } + + srv_master_thread(); + + printf("TESTS COMPLETED SUCCESSFULLY!\n"); + + os_process_exit(0); +} diff --git a/innobase/btr/ts/tssrv.c b/innobase/btr/ts/tssrv.c new file mode 100644 index 00000000000..78d247968d5 --- /dev/null +++ b/innobase/btr/ts/tssrv.c @@ -0,0 +1,535 @@ +/************************************************************************ +Test for the server + +(c) 1996-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 "buf0flu.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 "log0recv.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 "row0sel.h" +#include "row0upd.h" +#include "row0row.h" +#include "lock0lock.h" +#include "ibuf0ibuf.h" +#include "pars0pars.h" +#include "btr0sea.h" + +bool measure_cont = FALSE; + +os_file_t files[1000]; + +mutex_t ios_mutex; +ulint ios; +ulint n[10]; + +mutex_t incs_mutex; +ulint incs; + +byte rnd_buf[67000]; + +ulint glob_var1 = 0; +ulint glob_var2 = 0; + +mutex_t mutex2; + +mutex_t test_mutex1; +mutex_t test_mutex2; + +mutex_t* volatile mutexes; + +bool always_false = FALSE; + +ulint* test_array; + +/************************************************************************ +Io-handler thread function. */ + +ulint +handler_thread( +/*===========*/ + void* arg) +{ + ulint segment; + ulint i; + + 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 or opens the log files. */ + +void +create_log_files(void) +/*==================*/ +{ + bool ret; + ulint i, k; + char name[20]; + + printf("--------------------------------------------------------\n"); + printf("Create or open log files\n"); + + strcpy(name, "logfile00"); + + for (k = 0; k < srv_n_log_groups; k++) { + + for (i = 0; i < srv_n_log_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_AIO, + &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_AIO, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + 8192 * srv_log_file_size, 0)); + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k + 100, FIL_LOG); + } + + ut_a(fil_validate()); + + fil_node_create(name, srv_log_file_size, k + 100); + } + + fil_space_create(name, k + 200, FIL_LOG); + + log_group_init(k, srv_n_log_files, + srv_log_file_size * UNIV_PAGE_SIZE, + k + 100, k + 200); + } +} + +/************************************************************************* +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 < 2 * srv_n_spaces; k += 2) { + for (i = 0; i < srv_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_NORMAL, &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_NORMAL, &ret); + ut_a(ret); + } else { + ut_a(os_file_set_size(files[i], + UNIV_PAGE_SIZE * srv_file_size, 0)); + /* Initialize the file contents to a random value */ + /* + for (j = 0; j < srv_file_size; j++) { + + for (c = 0; c < UNIV_PAGE_SIZE; c++) { + + rnd_buf[c] = 0xFF; + } + + os_file_write(files[i], rnd_buf, + UNIV_PAGE_SIZE * j, 0, + UNIV_PAGE_SIZE); + } + */ + } + + ret = os_file_close(files[i]); + ut_a(ret); + + if (i == 0) { + fil_space_create(name, k, FIL_TABLESPACE); + } + + ut_a(fil_validate()); + + fil_node_create(name, srv_file_size, k); + } + } + + ios = 0; + + mutex_create(&ios_mutex); + mutex_set_level(&ios_mutex, SYNC_NO_ORDER_CHECK); + + /* Create i/o-handler threads: */ + + for (i = 0; i < 9; i++) { + n[i] = i; + + thr[i] = os_thread_create(handler_thread, n + i, id + i); + } +} + +/************************************************************************ +Inits space header of space. */ + +void +init_spaces(void) +/*=============*/ +{ + mtr_t mtr; + + mtr_start(&mtr); + + fsp_header_init(0, srv_file_size * srv_n_files, &mtr); + + mtr_commit(&mtr); +} + +/********************************************************************* +This thread is used to measure contention of latches. */ + +ulint +test_measure_cont( +/*==============*/ + void* arg) +{ + ulint i, j; + ulint pcount, kcount, s_scount, s_xcount, s_mcount, lcount; + ulint t1count; + ulint t2count; + + UT_NOT_USED(arg); + + printf("Starting contention measurement\n"); + + for (i = 0; i < 1000; i++) { + + pcount = 0; + kcount = 0; + s_scount = 0; + s_xcount = 0; + s_mcount = 0; + lcount = 0; + t1count = 0; + t2count = 0; + + for (j = 0; j < 100; j++) { + + if (srv_measure_by_spin) { + ut_delay(ut_rnd_interval(0, 20000)); + } else { + os_thread_sleep(20000); + } + + if (kernel_mutex.lock_word) { + kcount++; + } + + if (buf_pool->mutex.lock_word) { + pcount++; + } + + if (log_sys->mutex.lock_word) { + lcount++; + } + + if (btr_search_latch.reader_count) { + s_scount++; + } + + if (btr_search_latch.writer != RW_LOCK_NOT_LOCKED) { + s_xcount++; + } + + if (btr_search_latch.mutex.lock_word) { + s_mcount++; + } + + if (test_mutex1.lock_word) { + t1count++; + } + + if (test_mutex2.lock_word) { + t2count++; + } + } + + printf( + "Mutex res. l %lu, p %lu, k %lu s x %lu s s %lu s mut %lu of %lu\n", + lcount, pcount, kcount, s_xcount, s_scount, s_mcount, j); + + sync_print_wait_info(); + + printf( + "log i/o %lu n non sea %lu n succ %lu n h fail %lu\n", + log_sys->n_log_ios, btr_cur_n_non_sea, + btr_search_n_succ, btr_search_n_hash_fail); + } + + return(0); +} + +/********************************************************************* +This thread is used to test contention of latches. */ + +ulint +test_sync( +/*======*/ + void* arg) +{ + ulint tm, oldtm; + ulint i, j; + ulint sum; + ulint rnd = ut_rnd_gen_ulint(); + ulint mut_ind; + byte* ptr; + + UT_NOT_USED(arg); + + printf("Starting mutex reservation test\n"); + + oldtm = ut_clock(); + + sum = 0; + rnd = 87354941; + + for (i = 0; i < srv_test_n_loops; i++) { + + for (j = 0; j < srv_test_n_free_rnds; j++) { + rnd += 423087123; + + sum += test_array[rnd % (256 * srv_test_array_size)]; + } + + rnd += 43605677; + + mut_ind = rnd % srv_test_n_mutexes; + + mutex_enter(mutexes + mut_ind); + + for (j = 0; j < srv_test_n_reserved_rnds; j++) { + rnd += 423087121; + + sum += test_array[rnd % (256 * srv_test_array_size)]; + } + + mutex_exit(mutexes + mut_ind); + + if (srv_test_cache_evict) { + ptr = (byte*)(mutexes + mut_ind); + + for (j = 0; j < 4; j++) { + ptr += 256 * 1024; + sum += *((ulint*)ptr); + } + } + } + + if (always_false) { + printf("%lu", sum); + } + + tm = ut_clock(); + + printf("Wall time for res. test %lu milliseconds\n", tm - oldtm); + + return(0); +} + +/******************************************************************** +Main test function. */ + +void +main(void) +/*======*/ +{ + os_thread_id_t thread_ids[1000]; + ulint tm, oldtm; + ulint rnd; + ulint i, sum; + byte* ptr; +/* mutex_t mutex; */ + + log_do_write = TRUE; +/* yydebug = TRUE; */ + + srv_boot("srv_init"); + + os_aio_init(576, 9, 100); + + fil_init(25); + + buf_pool_init(srv_pool_size, srv_pool_size); + + fsp_init(); + log_init(); + + lock_sys_create(srv_lock_table_size); + + create_files(); + create_log_files(); + + init_spaces(); + + sess_sys_init_at_db_start(); + + trx_sys_create(); + + dict_create(); + + log_make_checkpoint_at(ut_dulint_max); + + printf("Hotspot semaphore addresses k %lx, p %lx, l %lx, s %lx\n", + &kernel_mutex, &(buf_pool->mutex), + &(log_sys->mutex), &btr_search_latch); + + if (srv_measure_contention) { + os_thread_create(&test_measure_cont, NULL, thread_ids + 999); + } + + if (!srv_log_archive_on) { + + ut_a(DB_SUCCESS == log_archive_noarchivelog()); + } + +/* + mutex_create(&mutex); + + oldtm = ut_clock(); + + for (i = 0; i < 2000000; i++) { + + mutex_enter(&mutex); + + mutex_exit(&mutex); + } + + tm = ut_clock(); + + printf("Wall clock time for %lu mutex enter %lu milliseconds\n", + i, tm - oldtm); +*/ + if (srv_test_sync) { + if (srv_test_nocache) { + mutexes = os_mem_alloc_nocache(srv_test_n_mutexes + * sizeof(mutex_t)); + } else { + mutexes = mem_alloc(srv_test_n_mutexes + * sizeof(mutex_t)); + } + + sum = 0; + + rnd = 492314896; + + oldtm = ut_clock(); + + for (i = 0; i < 4000000; i++) { + + rnd += 85967944; + + ptr = ((byte*)(mutexes)) + (rnd % (srv_test_n_mutexes + * sizeof(mutex_t))); + sum += *((ulint*)ptr); + } + + tm = ut_clock(); + + printf( + "Wall clock time for %lu random access %lu milliseconds\n", + i, tm - oldtm); + if (always_false) { + printf("%lu", sum); + } + + test_array = mem_alloc(4 * 256 * srv_test_array_size); + + for (i = 0; i < srv_test_n_mutexes; i++) { + + mutex_create(mutexes + i); + } + + for (i = 0; i < srv_test_n_threads; i++) { + os_thread_create(&test_sync, NULL, thread_ids + i); + } + } + + srv_master_thread(NULL); + + printf("TESTS COMPLETED SUCCESSFULLY!\n"); + + os_process_exit(0); +} |