Example #1
0
//-------------------------------------------------------------------
// BTreeDriver::TestAbsent
//
// Input   : btf,  The BTree to test.
//           key,  The key to test.
//           ridOffset, The offset used to compute the rid.
//           pad,  The amount of padding to use for the keys.
// Output  : None
// Return  : True if the key was not present in the tree.
// Purpose : Tests whether a key is absent from the tree.
//-------------------------------------------------------------------
bool BTreeDriver::TestAbsent(BTreeFile *btf, int key, int ridOffset, int pad)
{
	char skey[MAX_KEY_LENGTH];
	BTreeDriver::toString(key, skey, pad);
	RecordID rid;
	rid.pageNo = key + ridOffset;
	rid.slotNo = key + ridOffset + 1;

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

	if (scan == NULL) {
		std::cerr << "Error opening scan. " << std::endl;
		return false;
	}

	char *curKey;
	RecordID curRid;
	bool ret = true;

	while (scan->GetNext(curRid, curKey) != DONE) {
		if (strcmp(curKey, skey) == 0 && curRid == rid) {
			std::cerr << "Error: Unexpected key " << skey << " present." << std::endl;
			ret = false;
			break;
		} else if (strcmp(curKey, skey) > 0) {
			break;
		}
	}

	delete scan;
	return ret;
}
Example #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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}
Example #6
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;
}