Пример #1
0
bool BTreeDriver::TestLargeWorkload()
{
	Status status;
	BTreeFile *btf;
	bool res;

	btf = new BTreeFile(status, "BTreeTest4");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "Starting Test 4..." << std::endl;
	std::cout << "BTreeIndex created successfully." << std::endl;

	res = InsertRange(btf, 1, 1000, 1, 5, true);
	res = res && TestNumEntries(btf, 1000);

	res = InsertRange(btf, 1, 1000, 2, 5, false);
	res = res && TestNumEntries(btf, 2000);

	res = InsertRange(btf, 501, 1500, 3, 5, false);
	res = res && TestNumEntries(btf, 3000);

	res = InsertRange(btf, 2001, 4000, 1, 5, false);
	res = res && TestNumEntries(btf, 5000);

	char low[MAX_KEY_LENGTH];
	char high[MAX_KEY_LENGTH];

	toString(1000, low, 5);
	toString(1000, high, 5);
	BTreeFileScan *scan = btf->OpenScan(low, high);
	res = res && TestScanCount(scan, 3);
	delete scan;

	toString(3000, low, 5);
	toString(3000, high, 5);
	scan = btf->OpenScan(low, high);
	res = res && TestScanCount(scan, 1);
	delete scan;

	res = res && TestAbsent(btf, 1700, 1, 5);

	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;

	return res;
}
Пример #2
0
HeapFile *SortFile(HeapFile *S, int len, int offset)
{
	Status s;

	Scan *scan;
	scan = S->OpenScan(s);
	if (s != OK)
	{
		cerr << "ERROR : cannot open scan on the heapfile to sort.\n";
	}

	//
	// Scan the HeapFile S, new a B+Tree and insert the records into B+Tree.
	// 

	BTreeFile *btree;
	btree = new BTreeFile (s, "BTree", ATTR_INT, sizeof(int));

	char *recPtr = new char[len];
	int recLen = len;
	RecordID rid;
	while (scan->GetNext(rid, recPtr, recLen) == OK)
	{
		btree->Insert(recPtr + offset, rid);
	}
	delete scan;

	HeapFile *sorted;
	sorted = new HeapFile(NULL, s); // create a temp HeapFile
	if (s != OK)
	{
	    	cerr << "Cannot create new file for sortedS\n";
	}

	//
	// Now scan the B+-Tree and insert the records into a 
	// new (sorted) HeapFile.
	//

	BTreeFileScan  *btreeScan;
	btreeScan = (BTreeFileScan *)btree->OpenScan(NULL, NULL);

	int key;

	while (btreeScan->GetNext(rid, &key) == OK)
	{
	    S->GetRecord (rid, recPtr, recLen);
	    sorted->InsertRecord (recPtr, recLen, rid);
	}
	btree->DestroyFile();

	delete btree;
	delete btreeScan;
	delete [] recPtr;

	return sorted;
}
Пример #3
0
void BTreeTest::test4() {


	Status status;
	BTreeFile *btf;
	IndexFileScan* scan;

	int key, lokey, hikey;
	RID rid;
	int num = 1000;
	int num_deletes = 400;
	int i;
	dummy values[num];

	cout << "\n---------test4()  key type is Integer--------------\n";


	// test create()
	// if index exists, open it else create
	btf = new BTreeFile(status, "BTreeIndex", attrInteger, sizeof(int));
	if (status != OK) {
		minibase_errors.show_errors();
		exit(1);
	}
	cout << "\nBTreeIndex created successfully." << endl << endl;


	cout << " Creating " << num << " random entries" << endl;

	for ( i = 0; i < num; i++) {
		values[i].key = i * 8 + (rand() % 8);
		values[i].r.pageNo = i;
		values[i].r.slotNo = i+1;
		values[i].sort_value1 = rand() % 1000000;
		values[i].sort_value2 = rand() % 1000000;

		/*cout << " key " << values[i].key
			<< " sort_value1 " << values[i].sort_value1
			<< " sort_value2 " << values[i].sort_value2 << endl;*/

	}

	// test insert()

	// put values in insertion order
	qsort( values, num, sizeof(dummy), eval1);

	cout << "\n------Start to insert " << num << "  records------" << endl;

	for (i=0; i < num; i++){
		//cout << " Inserting key " << values[i].key << " order " 
		//<< values[i].sort_value1 << endl;
		if (btf->insert(&(values[i].key), values[i].r) != OK) {
			minibase_errors.show_errors();
		}
	}
	cout << "\n------ End of insert------" << endl;



	// test delete()
	cout << "\n\n------ Delete the first " << num_deletes 
		<< " of the records-----" << endl;

	// place records in deletion order
	qsort(values, num, sizeof(dummy), eval2);

	for (i = 0; i < num_deletes; i++) {
		/*
		   cout << "Deleting record with key = " << values[i].key 
		   << "  [pageNo,slotNo] = ";
		   cout << "[" << values[i].r.pageNo<<","
		   << values[i].r.slotNo << "]" <<endl;
		   */
		if (btf->Delete(&values[i].key, values[i].r) != OK) {
			minibase_errors.show_errors();
		}
	}
	cout << "Deleted  " << i << "  records " << endl;
	cout << "\n------ End of delete ------" << endl;

	delete btf;

	btf = new BTreeFile(status, "BTreeIndex");

	// test scan and delete_current()
	cout << "\n\n------ Testing scans ------" << endl;
	lokey = 570;
	hikey = 690;
	i= 1000;
	while (i < 1020){
		rid.pageNo = i;
		rid.slotNo = i+ 1;
		if(i < 1010) 
			key = lokey;
		else 
			key = hikey;

		if(btf->insert(&key,rid) != OK)
			minibase_errors.show_errors();
		i++;
	}

	//AllScan
	scan = btf->new_scan(NULL,NULL);
	cout << "\n\n------Start AllScan------" << endl;

	test_scan(scan);
	delete scan;   

	cout << "\n------End of AllScan------" << endl;

	//MaxRangeScan
	scan = btf->new_scan(NULL, &hikey);
	cout << "\n\n------Start MaxRangeScan with hikey = "<<hikey<<"------\n";
	test_scan(scan);
	delete scan;

	cout << "\n------End of MaxRangeScan with hikey = "<<hikey<<"------\n";

	//MinRangeScan;
	scan = btf->new_scan(&lokey, NULL);
	cout << "\n\n------Start MinRangeScan with lokey = "<<lokey<<"------\n";
	test_scan(scan);
	delete scan;   

	cout << "\n------End of MinRangeScan with lokey = "<<lokey<<"------\n";

	//ExactMatch
	scan = btf->new_scan(&hikey, &hikey);
	cout << "\n\n------Start ExactMatch with key = " <<hikey <<"-------\n";
	test_scan(scan);
	delete scan;
	cout << "\n------End of ExactMatch with key = " <<hikey <<"-------\n";


	//MinMaxRangeScan with delete_current()
	scan = btf->new_scan(&lokey, &hikey);
	cout << "\n\n------Start MinMaxRangeScan with lokey = "<<lokey  << " hikey = "<<hikey<<"------\n";
	cout << "Will also perform delete_current()\n";

	int count = 0;
	status = OK;
	while (status == OK) {
		char* temp = new char[scan->keysize()];    // BK
		if ((status = scan->get_next(rid, temp)) == OK)  {
			count++;
			if ((status = scan->delete_current()) == OK) {
				cout << "Record with [pageNo,slotNo] = ";
				cout << "[" << rid.pageNo<<","<<rid.slotNo<<"] deleted"<<endl;
			} else {
				cout << "Failure to delete record...\n";
				minibase_errors.show_errors();
			}
			delete [] temp;  // BK
		}
	}

	if (status != DONE) {
		cout << "Something is wrong in test4\n";
		minibase_errors.show_errors();
	}

	cout << "Number of records scanned = " << count << endl;
	cout << "\n------End of MinMaxRangeScan -----------------------\n";
	delete scan;

	delete btf;

	// test destroyFile()
	cout << "\n\n-----------Destroying index----------\n";

	btf = new BTreeFile(status, "BTreeIndex");

	cout << "\n-------Start to destroy the index----------" << endl;
	status = btf->destroyFile();
	if (status != OK)
		minibase_errors.show_errors();

	delete btf;

	cout << "\n--------- End of destroying the index -----" <<endl;
	cout << "\n\n--------- End of test4   -------------" <<endl;
}
Пример #4
0
void BTreeTest::test3() {

	cout << "\n--------test3() key type is String---------\n";

	Status status;
	BTreeFile *btf;
	IndexFileScan* scan;

	int keysize = MAX_KEY_SIZE1;
	char*  key = new char[keysize];
	char*  lokey = new char[keysize];
	char*  hikey = new char[keysize];
	int	i = 0;
	RID rid, lorid;
	ifstream keysamples;

	keysamples.open("keys",ios::in);
	if (!keysamples) {
		cout << "keys not found.\n";
		cout << " there is a copy in $MINIBASE_HOME/programs/minibase "<< endl;
		return;
	}


	// test create()
	btf = new BTreeFile(status, "BTreeIndex", attrString, keysize);
	if (status != OK) {
		minibase_errors.show_errors();
		exit(1);
	}
	cout << "BTreeIndex created successfully." << endl;


	// test insert()
	cout << "\n------Start to insert records--------" << endl;

	keysamples.getline(key, keysize, '\n');
	while(!keysamples.eof()) {
		rid.pageNo = (int)(key[0]+key[1]+key[2]);
		rid.slotNo = rid.pageNo;
		if (btf->insert(key, rid) != OK) {
			minibase_errors.show_errors();
		}

		i++;
		if(i==20) strncpy(lokey,key,keysize);
		if(i==100) strncpy(hikey,key,keysize);
		keysamples.getline(key, keysize, '\n');
	}
	cout << "\nNumber of records inserted is " << i << endl;
	cout << "\n--------------End of insert----------------" << endl;

	// test delete()
	cout << "\n------Start to delete some records----------" << endl;

	// delete the lokey
	lorid.pageNo = (int)(lokey[0]+lokey[1]+lokey[2]);
	lorid.slotNo = lorid.pageNo;

	if (btf->Delete(lokey, lorid) != OK)
		minibase_errors.show_errors();
	else
		cout << "\nSuccessfully deleted record with key = " << lokey << endl;
	cout << "\n---------------End of delete----------------" << endl;

	delete btf;
	btf = new BTreeFile(status, "BTreeIndex");

	// test scan and delete_current
	//AllScan     
	scan = btf->new_scan(NULL,NULL);                                            
	cout << "\n---------------Start AllScan------------" << endl;
	test_scan(scan);                                                            
	delete scan;                                                                
	cout <<"\n------End of AllScan------" << endl;

	//MaxRangeScan                                                              
	scan = btf->new_scan(NULL, hikey);                                       
	cout << "\n\n------Start MaxRangeScan with hikey = "<<hikey<< "------\n";
	test_scan(scan);     
	delete scan;                                                                
	cout << "\n------End of MaxRangeScan with hikey = "<<hikey<< "------\n";


	//MinRangeScan;                                                        
	scan = btf->new_scan(lokey, NULL);                                         
	cout << "\n\n-----Start MinRangeScan with lokey = "<<lokey<< "------\n"; 
	test_scan(scan);                                                            
	delete scan;                                                                
	cout << "\n------End of MinRangeScan with lokey = "<<lokey<< "------\n"; 

	//ExactMatch                                                                
	scan = btf->new_scan(hikey, hikey);                                       
	cout << "\n\n------Start ExactMatch with key = " <<hikey << "------\n"; 
	test_scan(scan);                                                            
	delete scan;
	cout << "\n------End of ExactMatch with key = " <<hikey << "------\n"; 

	//MinMaxRangeScan
	scan = btf->new_scan(lokey, hikey);
	cout << "\n\n------Start MinMaxRangeScan------" << endl;
	if(scan == NULL) {
		cout << "Cannot open a scan." << endl;
	}

	cout << "\n------Start scan with lokey = "<<lokey << " hikey = "<<hikey << "-----" << endl;

	int count = 0;
	status = OK;
	while (status == OK) {
		char* temp = new char[scan->keysize()];   // BK
		if ((status = scan->get_next(rid, temp)) == OK)  {
			count++;
			if ((status = scan->delete_current()) == OK) {
				cout << "Record with [pageNo,slotNo] = ";
				cout << "[" << rid.pageNo<<","<<rid.slotNo<<"] deleted"<<endl;
			}
			else
				minibase_errors.show_errors();
		}
		delete [] temp;  // BK
	}

	if (status != DONE)
	{
		cout << "Problem...\n";
		minibase_errors.show_errors();
	}
	cout << "Number of records scanned = " << count << endl;
	cout << "\n-------End of MinMaxRangeScan------\n";
	delete scan;


	cout << "\n\n------Testing abnormal scans------\n";

	// test abnormal scans
	// lokey > hikey
	strcpy(lokey, "zabcd");
	strcpy(hikey, "abcde");
	scan = btf->new_scan(lokey, hikey);

	char *temp1 = new char[MAX_KEY_SIZE1];
	if ((status = scan->get_next(rid, temp1)) == OK) {
		cout << " Error: find next??? nothing to find!!" << endl;
		minibase_errors.show_errors();
		exit(1);
	}

	if (status != DONE)
		minibase_errors.show_errors();
	delete scan;

	cout << " Failed as expected: no records scanned " << endl;

	// lokey > the largest key 
	strcpy(lokey, "zabcd");
	strcpy(hikey, "zcdef");
	scan = btf->new_scan(lokey, hikey);
	if ((status = scan->get_next(rid, temp1)) == OK) {
		cout << " Error: find next??? nothing to find!!" << endl;
		minibase_errors.show_errors();
		exit(1);
	}

	if (status != DONE)
		minibase_errors.show_errors();
	delete scan;

	cout << " Failed as expected: no records scanned " << endl;

	// hikey < smallest key
	strcpy(lokey, "aaa");
	strcpy(hikey, "aaaaa");
	scan = btf->new_scan(lokey, hikey);
	cout << "\n----Start MinMaxRangeScan with lokey = " << lokey ;
	cout << " hikey = " << hikey << "-------\n" ;
	cout << " -------hikey is smaller than the smallest key" << endl;

	if ((status = scan->get_next(rid, temp1)) == OK) {
		cout << " Error: find next??? nothing to find!!" << endl;
		minibase_errors.show_errors();
		exit(1);
	}

	if (status != DONE)
		minibase_errors.show_errors();
	delete scan;

	cout << " Failed as expected: no records scanned " << endl;

	delete temp1; 
	delete btf;

	// test destroyFile()

	btf = new BTreeFile(status, "BTreeIndex");

	cout << "-------Start to destroy the index-----------" << endl;
	status = btf->destroyFile();
	if (status != OK)
		minibase_errors.show_errors();
	cout << "-------End to destroy the index-----------" << endl;

	delete btf;
	delete key;
	delete lokey;
	delete hikey;
	cout << "\n\n---------End of Test 3 ---------------------\n\n";
}
Пример #5
0
void BTreeTest::test2() {

	cout << "\n-------------test2()  key type is Integer------------\n";

	Status status;
	BTreeFile *btf;
	IndexFileScan* scan;

	int lokey, hikey;
	RID rid;

	// test open()

	btf = new BTreeFile(status, "BTreeIndex");
	if (status != OK) {
		minibase_errors.show_errors();
		cout << "You should run test1 first to create the index!\n";
		return;
	}
	cout << "BTreeIndex opened successfully." << endl;

	//test abnormal scans
	//lokey > hikey
	lokey = 1000;
	hikey = 100;
	scan = btf->new_scan(&lokey,&hikey);
	cout << "\n-----Start MinMaxRangeScan with lokey = " << lokey \
		<< " hikey = " << hikey << "-----\n";


	char* temp = new char[scan->keysize()];   // BK
	if ((status = scan->get_next(rid, temp)) == OK)  {
		cout << "Error: find next??? no way!" << endl;
		minibase_errors.show_errors();
		exit(1);
	}

	if(status != DONE)
		minibase_errors.show_errors();
	delete scan;

	cout << " Failed as expected " << endl;

	//lokey > largest key
	lokey = 10000;
	hikey = 10010;
	scan = btf->new_scan(&lokey,&hikey);
	cout << "\n-----Start MinMaxRangeScan with lokey = " << lokey \
		<< " hikey = " << hikey << "-----\n";

	if ((status = scan->get_next(rid, temp)) == OK)  {
		cout << "Error: find next??? no way!" << endl;
		minibase_errors.show_errors();
		exit(1);
	}


	if(status != DONE)
		minibase_errors.show_errors();
	delete scan;

	cout << " Failed as expected " << endl;

	//hikey < smallest key
	lokey = -100;
	hikey = -50;
	scan = btf->new_scan(&lokey,&hikey);
	cout << "\n-----Start MinMaxRangeScan with lokey = " << lokey \
		<< " hikey = " << hikey << "------\n";


	if ((status = scan->get_next(rid, temp)) == OK)  {
		cout << "Error: find next??? no way!" << endl;
		minibase_errors.show_errors();
		exit(1);
	}

	if(status != DONE)
		minibase_errors.show_errors();
	delete scan;

	cout << " Failed as expected " << endl;

	// test destroyFile()
	cout << "\n------Start to destroy the index------" << endl;

	status = btf->destroyFile();
	if (status != OK)
		minibase_errors.show_errors();
	cout << "\n------Destroyed the index without any errors---" << endl;

	delete [] temp;  
	delete btf;
	cout << "\n ----End of Test 2----------------------\n\n";
}
Пример #6
0
void BTreeTest::test1() {

	cout << "\n---------test1()  key type is Integer--random------\n";

	Status status;
	BTreeFile *btf;
	IndexFileScan* scan;

	int key, lokey, hikey,i;
	RID rid;
	int num;


	// test create()
	// if index exists, open it else create
	btf = new BTreeFile(status, "BTreeIndex", attrInteger, sizeof(int));
	if (status != OK) {
		minibase_errors.show_errors();
		exit(1);
	}
	cout << "BTreeIndex created successfully." << endl << endl;


	// test insert()
	num = 2000;

	struct dummy{
		RID r;
		int key;
	};

	cout << "\nstart BTreeIndex insertion" << endl << endl;
	dummy kill[410];
	for (i = 0; i < num; i++) {
		rid.pageNo = i; rid.slotNo = i+1;
		key = num - i; 

		if (i % 10 == 0) {
			kill[(i/10)].r.pageNo = rid.pageNo;
			kill[(i/10)].r.slotNo = rid.slotNo;
			kill[i/10].key = key;
		}

		if (btf->insert(&key, rid) != OK) {
			cout << "Inserting record with key = " << key << "  [pageNo,slotNo] = ";
			cout << "[" << rid.pageNo<<","<<rid.slotNo<<"] failed!!\n" <<endl;
			minibase_errors.show_errors();
		}
	}

	// test delete()

	cout << "\nstart BTreeIndex deletion" << endl << endl;
	int j = 0;
	for (i = 0; i < num; i++) {
		if (i % 10 == 0) {
			j++;
			if (btf->Delete(&kill[i/10].key, kill[(i/10)].r) != OK) {
				cout << " Deleting record with key = " << kill[i/10].key << "  [pageNo,slotNo] = ";
				cout << "[" << kill[i/10].r.pageNo<<","<<kill[i/10].r.slotNo<<"] failed !!"<<endl;
				minibase_errors.show_errors();
			}
		}
	}

	delete btf;

	btf = new BTreeFile(status, "BTreeIndex");
	if(status == OK)
		cout<<"\n BTreeIndex opened successfully." << endl << endl;

	// test scan and delete_current()
	cout << "\n----------- Testing scans -------------" << endl;
	lokey = 200;
	hikey = 400;

	//AllScan
	scan = btf->new_scan(NULL,NULL);
	test_scan(scan);
	delete scan;   


	//MaxRangeScan
	scan = btf->new_scan(NULL, &hikey);
	test_scan(scan);
	delete scan;



	//MinRangeScan;
	scan = btf->new_scan(&lokey, NULL);
	test_scan(scan);
	delete scan;   


	//ExactMatch
	scan = btf->new_scan(&hikey, &hikey);
	test_scan(scan);
	delete scan;



	//MinMaxRangeScan with delete_current()
	scan = btf->new_scan(&lokey, &hikey);
	int count = 0;
	int size = scan->keysize();
	char* temp = new char[size];
	int* ikey;
	char* ckey;

	status = OK;

	while (status == OK) {
		if ((status = scan->get_next(rid, temp)) == OK)  {
			count++;
			if ((status = scan->delete_current()) == OK) {
				cout << "Record with [pageNo,slotNo] = ";
				cout << "[" << rid.pageNo<<","<<rid.slotNo<<"]"; 
				if (size == sizeof(int)) {
					ikey = (int *) temp;
					cout << "\tkey = " << *ikey;
				} else {
					ckey = (char*) temp;
					cout <<"\t key = " << ckey;
				}
				cout << "\tdeleted !!" <<endl; 
			} else {
				cout << "Failure to delete record...\n";
				minibase_errors.show_errors();
			}
		}
		else if (status != DONE)
			minibase_errors.show_errors();
	}

	delete [] temp;  

	if (status != DONE) {
		cout << "Something is wrong in test1\n";
		minibase_errors.show_errors();
	}

	//    delete scan;

	delete btf;

	cout << "\n---------------End of Test 1----------------------\n\n";
}
Пример #7
0
bool BTreeDriver::TestDeleteCurrent() {
	Status status;
	BTreeFile *btf;
	bool res;

	btf = new BTreeFile(status, "BTreeTest6");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "Starting Test 6..." << std::endl;
	std::cout << "BTreeIndex created successfully." << std::endl;
	std::cout << "Inserting entries..." << std::endl;
	InsertRange(btf, 1, 10);
	char low[MAX_KEY_LENGTH];
	toString(3, low);
	BTreeFileScan* scan = btf->OpenScan(low, NULL);

	std::cout << "Deleting entries..." << std::endl;
	RecordID rid;
	char* keyPtr;
	scan->GetNext(rid, keyPtr); // 3
	scan->GetNext(rid, keyPtr); // 4
	scan->DeleteCurrent(); // 5
	scan->GetNext(rid, keyPtr); // 6
	scan->GetNext(rid, keyPtr); // 7
	scan->GetNext(rid, keyPtr); // 8
	scan->DeleteCurrent();
	delete scan;

	res = TestAbsent(btf, 4);
	res = TestAbsent(btf, 8);

	std::cout << "Inserting duplicate entry..." << std::endl;
	InsertKey(btf, 1, 3);
	toString(1, low);
	scan = btf->OpenScan(low, NULL);

	std::cout << "Deleting entry..." << std::endl;
	scan->GetNext(rid, keyPtr); // 1
	scan->DeleteCurrent(); // 1
	delete scan;

	res = TestAbsent(btf, 1, 1);
	res = TestPresent(btf, 1, 3);
	
	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;

	return res;
}
Пример #8
0
bool BTreeDriver::TestBufferPool() {
	// does some operations
	// at the end check if there's anything left in the buffer pool
	std::cout << "Starting Test 5..." << std::endl;
	unsigned int pinnedPages = MINIBASE_BM->GetNumOfBuffers() - MINIBASE_BM->GetNumOfUnpinnedBuffers();
	std::cout << "# pinned pages: " << pinnedPages << std::endl;

	BTreeFile* btf;
	Status status;
	bool res = true;

	btf = new BTreeFile(status, "BTreeTest5");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "BTreeIndex created successfully." << std::endl;

	std::cout << "Performing various operations on BTreeFile." << std::endl;
	InsertRange(btf, 1, 1000, 1, 5, true);
	InsertRange(btf, 1, 1000, 2, 5, false);
	InsertRange(btf, 501, 1500, 3, 5, false);
	InsertRange(btf, 2001, 4000, 1, 5, false);

	char low[MAX_KEY_LENGTH];
	char high[MAX_KEY_LENGTH];

	BTreeFileScan *scan = btf->OpenScan(NULL, NULL);

	RecordID rid;
	char* key;
	int count = 0;
	while (scan->GetNext(rid, key) != DONE) {
		count++;
	}

	if (count != 5000) {
		std::cerr << "Number of pages inserted doesn't equal 5000. Check insert." << std::endl;
		res = false;
	}

	delete scan;
	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;

	unsigned int numPinned = MINIBASE_BM->GetNumOfBuffers() - MINIBASE_BM->GetNumOfUnpinnedBuffers();
	
	if (pinnedPages - numPinned != 0) {
		std::cerr << pinnedPages - numPinned << " pages still left in buffer pool after clean up." << std::endl;
		res = false;
	}
	return res;
}
Пример #9
0
bool BTreeDriver::TestInsertsWithIndexSplits()
{
	Status status;
	BTreeFile *btf;
	bool res;

	btf = new BTreeFile(status, "BTreeTest3");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "Starting Test 3..." << std::endl;
	std::cout << "BTreeIndex created successfully." << std::endl;

	// Insert a bunch of long keys into the tree until we cause the root
	// node to split.
	std::cout << "Inserting 31 large keys..."	<< std::endl;
	res = InsertRange(btf, 1, 31, 1, 20);
	res = res && TestNumLeafPages(btf, 2);
	res = res && TestNumEntries(btf, 31);

	std::cout << "Inserting keys until root splits." << std::endl;

	PageID rootId = btf->header->GetRootPageID();
	PageID newRootId;
	int key = 32;
	int numInserted = 0;

	PageID leftPid, rightPid;
	IndexPage *leftPage;
	IndexPage *rightPage;

	while (true) {
		res = res && InsertKey(btf, key, 1, 20);
		newRootId = btf->header->GetRootPageID();

		// there was a split. Check balance.
		if (newRootId != rootId) {
			IndexPage *ip;

			if (MINIBASE_BM->PinPage(newRootId, (Page *&) ip) == FAIL) {
				std::cerr << "Error pinning root page." << std::endl;
				res = false;
			}

			if (ip->GetNumOfRecords() != 1) {
				std::cerr << "Error: Expected 1 key in root, got "
						  << ip->GetNumOfRecords() << std::endl;
				res = false;
			}

			leftPid = ip->GetPrevPage();

			char *rightKey;
			ip->GetMinKeyValue(rightKey, rightPid);

			if (MINIBASE_BM->PinPage(leftPid, (Page *&) leftPage) == FAIL) {
				std::cerr << "Error pinning left leaf page." << std::endl;
				res = false;
			}

			if (MINIBASE_BM->PinPage(rightPid, (Page *&) rightPage) == FAIL) {
				std::cerr << "Error pinning right leaf page." << std::endl;
				res = false;
			}

			res = res && TestBalance(btf, leftPage, rightPage);

			if (MINIBASE_BM->UnpinPage(leftPid, CLEAN) == FAIL) {
				std::cerr << "Error unpinning left leaf page." << std::endl;
				res = false;
			}

			if (MINIBASE_BM->UnpinPage(rightPid, CLEAN) == FAIL) {
				std::cerr << "Error unpinning right leaf page." << std::endl;
				res = false;
			}

			if (MINIBASE_BM->UnpinPage(newRootId, CLEAN) == FAIL) {
				std::cerr << "Error unpinning root page." << std::endl;
				res = false;
			}

			break;
		}

		key++;
		numInserted++;
	}

	res = res && TestNumEntries(btf, key);

	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;

	return res;
}
Пример #10
0
bool BTreeDriver::TestInsertsWithLeafSplits()
{
	Status status;
	BTreeFile *btf;
	bool res;
	LeafPage *leftPage;
	LeafPage *rightPage;
	btf = new BTreeFile(status, "BTreeTest2");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "Starting Test 2..." << std::endl;
	std::cout << "BTreeIndex created successfully." << std::endl;

	std::cout << "Inserting 30 large keys..."	<< std::endl;
	res = InsertRange(btf, 1, 30, 1, 20);
	res = res && TestNumLeafPages(btf, 1);
	res = res && TestNumEntries(btf, 30);

	// Insert some more long keys. This should cause the tree to split.
	std::cout << "Causing split with new key in right node..."	<< std::endl;
	res = res && InsertKey(btf, 31, 1, 20);
	res = res && TestNumLeafPages(btf, 2);
	res = res && TestNumEntries(btf, 31);

	// Make sure that the split happened as expected.
	PageID leftPid = btf->GetLeftLeaf();

	if (MINIBASE_BM->PinPage(leftPid, (Page *&) leftPage) == FAIL) {
		std::cerr << "Error pinning left leaf page." << std::endl;
		res = false;
	}

	PageID rightPid = leftPage->GetNextPage();

	if (MINIBASE_BM->PinPage(rightPid, (Page *&) rightPage) == FAIL) {
		std::cerr << "Error pinning right leaf page." << std::endl;
		res = false;
	}

	res = res && TestBalance(btf, leftPage, rightPage);

	if (MINIBASE_BM->UnpinPage(leftPid, CLEAN) == FAIL) {
		std::cerr << "Error unpinning left leaf page." << std::endl;
		res = false;
	}

	if (MINIBASE_BM->UnpinPage(rightPid, CLEAN) == FAIL) {
		std::cerr << "Error unpinning right leaf page." << std::endl;
		res = false;
	}

	// We destroy and rebuild the file before to reduce
	// dependence on working Delete function.
	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;

	// Create a new tree.
	btf = new BTreeFile(status, "BTreeTest2");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	// Insert 30 long keys.
	std::cout << "Inserting 30 large keys..."	<< std::endl;
	res = InsertRange(btf, 2, 31, 1, 20);

	res = res && TestNumLeafPages(btf, 1);
	res = res && TestNumEntries(btf, 30);

	// Insert some more nodes with long keys into the tree.
	// This should cause the tree to split.
	std::cout << "Causing split with new key in left node..."	<< std::endl;
	res = res && InsertKey(btf, 1, 1, 20);

	res = res && TestNumLeafPages(btf, 2);
	res = res && TestNumEntries(btf, 31);

	// Make sure that the tree is balanced.
	leftPid = btf->GetLeftLeaf();

	if (MINIBASE_BM->PinPage(leftPid, (Page *&) leftPage) == FAIL) {
		std::cerr << "Error pinning left leaf page." << std::endl;
		res = false;
	}

	rightPid = leftPage->GetNextPage();

	if (MINIBASE_BM->PinPage(rightPid, (Page *&) rightPage) == FAIL) {
		std::cerr << "Error pinning right leaf page." << std::endl;
		res = false;
	}

	res = res && TestBalance(btf, leftPage, rightPage);

	if (MINIBASE_BM->UnpinPage(leftPid, CLEAN) == FAIL) {
		std::cerr << "Error unpinning left leaf page." << std::endl;
		res = false;
	}

	if (MINIBASE_BM->UnpinPage(rightPid, CLEAN) == FAIL) {
		std::cerr << "Error unpinning right leaf page." << std::endl;
		res = false;
	}

	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;

	// That's all, folks.
	return res;
}
Пример #11
0
bool BTreeDriver::TestSinglePage()
{
	Status status;
	BTreeFile *btf;

	btf = new BTreeFile(status, "BTreeTest1");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "Starting Test 1..." << std::endl;
	std::cout << "BTreeIndex created successfully." << std::endl;

	bool res;

	std::cout << "Inserting 59 initial keys..."	<< std::endl;
	res = InsertRange(btf, 1, 59);
	res = res && TestNumLeafPages(btf, 1);
	res = res && TestNumEntries(btf, 59);

	std::cout << "Checking a few individual keys..." << std::endl;
	res = res && TestAbsent(btf, 0);
	res = res && TestPresent(btf, 2);
	res = res && TestPresent(btf, 59);
	res = res && TestAbsent(btf, 60);

	std::cout << "Checking scans..." << std::endl;

	char low[MAX_KEY_LENGTH];
	char high[MAX_KEY_LENGTH];
	toString(5, low);
	toString(15, high);
	BTreeFileScan *scan = btf->OpenScan(low, high);
	res = res && TestScanCount(scan, 11);
	delete scan;

	toString(58, low);
	toString(64, high);
	scan = btf->OpenScan(low, high);
	res = res && TestScanCount(scan, 2);
	delete scan;

	toString(0, low);
	toString(5, high);
	scan = btf->OpenScan(low, high);
	res = res && TestScanCount(scan, 5);
	delete scan;

	// We destroy and rebuild the file before to reduce
	// dependence on working Delete function.
	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;

	btf = new BTreeFile(status, "BTreeTest2");

	if (status != OK) {
		std::cerr << "ERROR: Couldn't create a BTreeFile" << std::endl;
		minibase_errors.show_errors();

		std::cerr << "Hit [enter] to continue..." << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "Inserting 124 duplicates." << std::endl;
	res = res && InsertDuplicates(btf, 3, 124);
	res = res && TestNumLeafPages(btf, 1);
	res = res && TestNumEntries(btf, 124);

	if (btf->DestroyFile() != OK) {
		std::cerr << "Error destroying BTreeFile" << std::endl;
		res = false;
	}

	delete btf;
	return res;
}
Пример #12
0
//--------------------------------------------------------------------
// JoinMethod::SortFile
// 
// Purpose :  Sorts a relation by an integer attribute. 
// Input   :  file - pointer to the HeapFile to be sorted.
//            len  - length of the records in the file. (assume fixed size).
//            offset - offset of the sort attribute from the beginning of the record.
// Method  :  We create a B+-Tree using that attribute as the key. Then
//            we scan the B+-Tree and insert the records into a new
//            HeapFile. he HeapFile guarantees that the order of 
//            insertion will be the same as the order of scan later.
// Return  :  The new sorted relation/HeapFile.
//-------------------------------------------------------------------- 
HeapFile* JoinMethod::SortHeapFile(HeapFile *file, int len, int offset) {

	Status s;

	Scan *scan;
	scan = file->OpenScan(s);
	if (s != OK) {
		std::cerr << "ERROR : cannot open scan on the heapfile to sort." << std::endl;
	}

	//
	// Scan the HeapFile S, create a new B+Tree and insert the records into B+Tree.
	// 

	BTreeFile *btree;
	btree = new BTreeFile (s, "BTree");

	char* recPtr = new char[len];
	int recLen = len;
	RecordID rid;

	char* recKey = new char[100];

	while (scan->GetNext(rid, recPtr, recLen) == OK)
	{
		int* valPtr = (int*)(recPtr+offset);
		int val = *valPtr;
		toString(val,recKey);
		btree->Insert(recKey, rid);
	}
	delete scan;
	delete [] recKey;
	//std::cout << "created B+ tree!" << std::endl;

	HeapFile *sorted = new HeapFile(NULL, s); // create a temp HeapFile
	if (s != OK)
	{
		std::cerr << "Cannot create new file for sortedS\n";
	}

	// Now scan the B+-Tree and insert the records into a 
	// new (sorted) HeapFile.

	BTreeFileScan* btreeScan = btree->OpenScan(NULL, NULL);

	//int key;
	char* keyPtr;
	while (btreeScan->GetNext(rid, keyPtr) == OK)
	{
		//std::cout << "scanning " << rid << " " << keyPtr << std::endl;

	    file->GetRecord (rid, recPtr, recLen);
	    sorted->InsertRecord (recPtr, recLen, rid);
	}
	btree->DestroyFile();

	delete btree;
	delete btreeScan;
	delete [] recPtr;

	return sorted;
}
Пример #13
0
HeapFile* IndexNestedLoopJoin(JoinSpec specOfR, JoinSpec specOfS)
{
	Status status = OK;

	// Create a HeapFile for join results
	HeapFile* joinedFile = new HeapFile(NULL, status);
	if (OK != status)
	{
		cerr << "ERROR: cannot create a file for the joined relation.\n";
		return NULL;
	}

	int recLenR = specOfR.recLen;
	int recLenS = specOfS.recLen;
	int recLenJoined = recLenR + recLenS;

	char* recR = new char[recLenR];
	char* recS = new char[recLenS];
	char* recJoined = new char[recLenJoined];

	RecordID ridR, ridS, ridJoined;

	// Build the B+-tree index on the inner relation (S)
	Scan* scanS = specOfS.file->OpenScan(status);
	if (OK != status)
	{
		cerr << "ERROR: cannot open scan on the relation S heap file.\n";
		return NULL;
	}

	BTreeFile* bTree = new BTreeFile(status, "IJBT", ATTR_INT, sizeof(int));
	while (OK == scanS->GetNext(ridS, recS, recLenS))
	{
		bTree->Insert(recS + specOfS.offset, ridS);
	}
	delete scanS;

	// Iterate through the outer relation (R) and join
	Scan* scanR = specOfR.file->OpenScan(status);
	if (OK != status)
	{
		cerr << "ERROR: cannot open scan on the relation R heap file.\n";
		return NULL;
	}

	while (OK == scanR->GetNext(ridR, recR, recLenR))
	{
		int* joinArgR = (int*)&recR[specOfR.offset];

		BTreeFileScan* bTreeScan = (BTreeFileScan*)bTree->OpenSearchScan(joinArgR, joinArgR);
		int key;
		while (OK == bTreeScan->GetNext(ridS, &key))
		{
		    specOfS.file->GetRecord(ridS, recS, recLenS);

			MakeNewRecord(recJoined, recR, recS, recLenR, recLenS);
			joinedFile->InsertRecord(recJoined, recLenJoined, ridJoined);
		}
		delete bTreeScan;
	}

	// Release the allocated resources
	delete scanR;

	delete[] recR;
	delete[] recS;
	delete[] recJoined;

	delete bTree;

	return joinedFile;
}