/************************************************************************
Test for the transaction system

(c) 1994-1997 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 "trx0trx.h"
#include "dict0boot.h"
#include "trx0sys.h"
#include "dict0crea.h"
#include "btr0btr.h"
#include "btr0pcur.h"
#include "rem0rec.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		1
#define FILE_SIZE	4000 	/* 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, "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);
		}

		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);
}

#ifdef notdefined

/*********************************************************************
Test for index page. */

void 
test1(void)
/*=======*/
{
	dtuple_t*	tuple;
	mem_heap_t*	heap;
	mem_heap_t*	heap2;
	ulint		rnd	= 0;
	dict_index_t*	index;	
	dict_table_t*	table;
	byte		buf[16];
	ulint		i, j;
	ulint		tm, oldtm;
	trx_t*		trx;
/*	dict_tree_t*	tree;*/
	btr_pcur_t	pcur;
	btr_pcur_t	pcur2;
	mtr_t		mtr;
	mtr_t		mtr2;
	byte*		field;
	ulint		len;
	dtuple_t*	search_tuple;
	dict_tree_t*	index_tree;
	rec_t*		rec;

	UT_NOT_USED(len);
	UT_NOT_USED(field);
	UT_NOT_USED(pcur2);
/*	
	printf("\n\n\nPress 2 x enter to start test\n");
	
	while (EOF == getchar()) {
		
	}

	getchar();
*/	
	printf("-------------------------------------------------\n");
	printf("TEST 1. CREATE TABLE WITH 3 COLUMNS AND WITH 3 INDEXES\n");

	heap = mem_heap_create(1024);
	heap2 = mem_heap_create(1024);

	trx = trx_start(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);

	ut_a(TRUE == dict_create_table(table, trx));

	index = dict_mem_index_create("TS_TABLE1", "IND1", 75046,
							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));
	
	ut_a(TRUE == dict_create_index(index, trx));

	trx_commit(trx);

	trx = trx_start(ULINT_UNDEFINED);	

	index = dict_mem_index_create("TS_TABLE1", "IND2", 0, DICT_UNIQUE, 1);

	dict_mem_index_add_field(index, "COL2", 0);

	ut_a(mem_heap_validate(index->heap));
	
	ut_a(TRUE == dict_create_index(index, trx));

	trx_commit(trx);

	trx = trx_start(ULINT_UNDEFINED);	

	index = dict_mem_index_create("TS_TABLE1", "IND3", 0, DICT_UNIQUE, 1);

	dict_mem_index_add_field(index, "COL2", 0);

	ut_a(mem_heap_validate(index->heap));
	
	ut_a(TRUE == dict_create_index(index, trx));

	trx_commit(trx);
/*
	tree = dict_index_get_tree(dict_table_get_first_index(table));

	btr_print_tree(tree, 10);
*/
	dict_table_print(table);

	/*---------------------------------------------------------*/
/*
	printf("\n\n\nPress 2 x enter to continue test\n");
	
	while (EOF == getchar()) {
		
	}
	getchar();
*/	
	printf("-------------------------------------------------\n");
	printf("TEST 2. INSERT 1 ROW TO THE TABLE\n");

	trx = trx_start(ULINT_UNDEFINED);
	
	tuple = dtuple_create(heap, 3);

	table = dict_table_get("TS_TABLE1", trx);

	dtuple_gen_test_tuple3(tuple, 0, buf);
	tcur_insert(tuple, table, heap2, trx);

	trx_commit(trx);
/*
	tree = dict_index_get_tree(dict_table_get_first_index(table));

	btr_print_tree(tree, 10);
*/
/*
	printf("\n\n\nPress 2 x enter to continue test\n");
	
	while (EOF == getchar()) {
		
	}
	getchar();
*/	
	printf("-------------------------------------------------\n");
	printf("TEST 3. INSERT MANY ROWS TO THE TABLE IN A SINGLE TRX\n");

	rnd = 0;
	oldtm = ut_clock();
	
	trx = trx_start(ULINT_UNDEFINED);
	for (i = 0; i < 300 * UNIV_DBC * UNIV_DBC; i++) {

		if (i % 5000 == 0) {
			/* dict_table_print(table);
			buf_print();
			buf_LRU_print();
			printf("%lu rows inserted\n", i); */
		}

		table = dict_table_get("TS_TABLE1", trx);
		
		if (i == 2180) {
			rnd = rnd % 200000;
		}

		rnd = (rnd + 1) % 200000;
		
		dtuple_gen_test_tuple3(tuple, rnd, buf);

		tcur_insert(tuple, table, heap2, trx);

		mem_heap_empty(heap2);

		if (i % 4 == 3) {
		}
	}
	trx_commit(trx);

	tm = ut_clock();
	printf("Wall time for test %lu milliseconds\n", tm - oldtm);
	printf("%lu rows inserted\n", i);
/*
	printf("\n\n\nPress 2 x enter to continue test\n");
	
	while (EOF == getchar()) {
		
	}
	getchar();
*/	
	printf("-------------------------------------------------\n");
	printf("TEST 4. PRINT PART OF CONTENTS OF EACH INDEX TREE\n");

/*
	mem_print_info();
*/

/*
	tree = dict_index_get_tree(dict_table_get_first_index(table));

	btr_print_tree(tree, 10);

	tree = dict_index_get_tree(dict_table_get_next_index(
				dict_table_get_first_index(table)));

	btr_print_tree(tree, 5);
*/	
/*
	printf("\n\n\nPress 2 x enter to continue test\n");

	while (EOF == getchar()) {
		
	}
	getchar();
*/
/*	mem_print_info(); */

	os_thread_sleep(5000000);

   for (j = 0; j < 5; j++) {
	printf("-------------------------------------------------\n");
	printf("TEST 5. CALCULATE THE JOIN OF THE TABLE WITH ITSELF\n");

	i = 0;

	oldtm = ut_clock();

	mtr_start(&mtr);

	index_tree = dict_index_get_tree(UT_LIST_GET_FIRST(table->indexes));

	search_tuple = dtuple_create(heap, 2);

	dtuple_gen_search_tuple3(search_tuple, i, buf);
	
	btr_pcur_open(index_tree, search_tuple, PAGE_CUR_GE,
						BTR_SEARCH_LEAF, &pcur, &mtr);

	ut_a(btr_pcur_move_to_next(&pcur, &mtr));

	while (!btr_pcur_is_after_last_in_tree(&pcur, &mtr)) {
	
		if (i % 20000 == 0) {
			printf("%lu rows joined\n", i);
		}

		index_tree = dict_index_get_tree(
					UT_LIST_GET_FIRST(table->indexes));

		rec = btr_pcur_get_rec(&pcur);

		rec_copy_prefix_to_dtuple(search_tuple, rec, 2, heap2);

		mtr_start(&mtr2);		

		btr_pcur_open(index_tree, search_tuple, PAGE_CUR_GE,
						BTR_SEARCH_LEAF, &pcur2, &mtr2);

		btr_pcur_move_to_next(&pcur2, &mtr2);

		rec = btr_pcur_get_rec(&pcur2);

		field = rec_get_nth_field(rec, 1, &len);

		ut_a(len == 8);

		ut_a(ut_memcmp(field, dfield_get_data(
					dtuple_get_nth_field(search_tuple, 1)),
				len) == 0);
				
		btr_pcur_close(&pcur2, &mtr);

		mem_heap_empty(heap2);

		mtr_commit(&mtr2);

		btr_pcur_store_position(&pcur, &mtr);
		mtr_commit(&mtr);

		mtr_start(&mtr);

		btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);

		btr_pcur_move_to_next(&pcur, &mtr);
		i++;
	}

	btr_pcur_close(&pcur, &mtr);
	mtr_commit(&mtr);

	tm = ut_clock();
	printf("Wall time for test %lu milliseconds\n", tm - oldtm);
	printf("%lu rows joined\n", i);
   }

	oldtm = ut_clock();

/*
	printf("\n\n\nPress 2 x enter to continue test\n");
	
	while (EOF == getchar()) {
		
	}
	getchar();
*/	
	printf("-------------------------------------------------\n");
	printf("TEST 6. INSERT MANY ROWS TO THE TABLE IN SEPARATE TRXS\n");

	rnd = 200000;
	
	for (i = 0; i < 350; i++) {

		if (i % 4 == 0) {
		}
		trx = trx_start(ULINT_UNDEFINED);

		table = dict_table_get("TS_TABLE1", trx);
		
		if (i == 2180) {
			rnd = rnd % 200000;
		}

		rnd = (rnd + 1) % 200000;
		
		dtuple_gen_test_tuple3(tuple, rnd, buf);

		tcur_insert(tuple, table, heap2, trx);

		trx_commit(trx);

		mem_heap_empty(heap2);
		if (i % 4 == 3) {
		}
	}

	tm = ut_clock();
	printf("Wall time for test %lu milliseconds\n", tm - oldtm);
	printf("%lu rows inserted in %lu transactions\n", i, i);
/*
	printf("\n\n\nPress 2 x enter to continue test\n");
	
	while (EOF == getchar()) {
		
	}
	getchar();
*/	
	printf("-------------------------------------------------\n");
	printf("TEST 7. PRINT MEMORY ALLOCATION INFO\n");

	mem_print_info();
/*
	printf("\n\n\nPress 2 x enter to continue test\n");
	
	while (EOF == getchar()) {
		
	}
	getchar();
*/	
	printf("-------------------------------------------------\n");
	printf("TEST 8. PRINT SEMAPHORE INFO\n");

	sync_print();

#endif	

#ifdef notdefined
	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); */

#endif
/*
	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;
	mtr_t	mtr;

	sync_init();
	mem_init();
	os_aio_init(160, 5);
	fil_init(25);
	buf_pool_init(POOL_SIZE, POOL_SIZE);
	fsp_init();
	log_init();

	create_files();
	init_space();

	mtr_start(&mtr);

	trx_sys_create(&mtr);
	dict_create(&mtr);

	mtr_commit(&mtr);

	
	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");
} 
