12 #include "page_iterator.h"
13 #include "file_iterator.h"
14 #include "exceptions/insufficient_space_exception.h"
15 #include "exceptions/index_scan_completed_exception.h"
16 #include "exceptions/file_not_found_exception.h"
17 #include "exceptions/no_such_key_found_exception.h"
18 #include "exceptions/bad_scanrange_exception.h"
19 #include "exceptions/bad_opcodes_exception.h"
20 #include "exceptions/scan_not_initialized_exception.h"
21 #include "exceptions/end_of_file_exception.h"
23 #define checkPassFail(a, b) \
26 std::cout << "\nTest passed at line no:" << __LINE__ << "\n"; \
29 std::cout << "\nTest FAILS at line no:" << __LINE__; \
30 std::cout << "\nExpected no of records:" << b; \
31 std::cout << "\nActual no of records found:" << a; \
32 std::cout << std::endl; \
37 using namespace badgerdb;
43 const std::string relationName =
"relA";
45 const int relationSize = 5000;
46 std::string intIndexName, doubleIndexName, stringIndexName;
59 std::string dbRecord1;
67 void createRelationForward();
68 void createRelationBackward();
69 void createRelationRandom();
81 void deleteRelation();
83 int main(
int argc,
char **argv)
87 std::cout <<
"Expects one argument as a number between 1 to 3 to choose datatype of key.\n";
88 std::cout <<
"For INTEGER keys run as: ./badgerdb_main 1\n";
89 std::cout <<
"For DOUBLE keys run as: ./badgerdb_main 2\n";
90 std::cout <<
"For STRING keys run as: ./badgerdb_main 3\n";
95 sscanf(argv[1],
"%d",&testNum);
125 for (
int i = 0; i < 20; ++i)
130 sprintf(record1.s,
"%05d string record", i);
132 record1.d = (double)i;
133 std::string new_data(reinterpret_cast<char*>(&record1),
sizeof(record1));
136 new_file.
writePage(new_page_number, new_page);
143 FileScan fscan(relationName, bufMgr);
150 fscan.scanNext(scanRid);
152 std::string recordStr = fscan.getRecord();
153 const char *record = recordStr.c_str();
154 int key = *((
int *)(record + offsetof (
RECORD, i)));
155 std::cout <<
"Extracted : " << key << std::endl;
160 std::cout <<
"Read all records" << std::endl;
180 std::cout <<
"---------------------" << std::endl;
181 std::cout <<
"createRelationForward" << std::endl;
182 createRelationForward();
191 std::cout <<
"----------------------" << std::endl;
192 std::cout <<
"createRelationBackward" << std::endl;
193 createRelationBackward();
202 std::cout <<
"--------------------" << std::endl;
203 std::cout <<
"createRelationRandom" << std::endl;
204 createRelationRandom();
213 void createRelationForward()
215 std::vector<RecordId> ridVec;
225 file1 =
new PageFile(relationName,
true);
228 memset(record1.s,
' ',
sizeof(record1.s));
233 for(
int i = 0; i < relationSize; i++ )
235 sprintf(record1.s,
"%05d string record", i);
237 record1.d = (double)i;
238 std::string new_data(reinterpret_cast<char*>(&record1),
sizeof(record1));
249 file1->
writePage(new_page_number, new_page);
255 file1->
writePage(new_page_number, new_page);
262 void createRelationBackward()
272 file1 =
new PageFile(relationName,
true);
275 memset(record1.s,
' ',
sizeof(record1.s));
280 for(
int i = relationSize - 1; i >= 0; i-- )
282 sprintf(record1.s,
"%05d string record", i);
286 std::string new_data(reinterpret_cast<char*>(&record1),
sizeof(
RECORD));
297 file1->
writePage(new_page_number, new_page);
303 file1->
writePage(new_page_number, new_page);
310 void createRelationRandom()
320 file1 =
new PageFile(relationName,
true);
323 memset(record1.s,
' ',
sizeof(record1.s));
329 std::vector<int> intvec(relationSize);
330 for(
int i = 0; i < relationSize; i++ )
338 while( i < relationSize )
340 pos = random() % (relationSize-i);
342 sprintf(record1.s,
"%05d string record", val);
346 std::string new_data(reinterpret_cast<char*>(&record1),
sizeof(
RECORD));
357 file1->
writePage(new_page_number, new_page);
362 int temp = intvec[relationSize-1-i];
363 intvec[relationSize-1-i] = intvec[pos];
368 file1->
writePage(new_page_number, new_page);
388 else if(testNum == 2)
399 else if(testNum == 3)
418 std::cout <<
"Create a B+ Tree index on the integer field" << std::endl;
419 BTreeIndex index(relationName, intIndexName, bufMgr, offsetof(
tuple,i), INTEGER);
422 checkPassFail(intScan(&index,25,GT,40,LT), 14)
423 checkPassFail(intScan(&index,20,GTE,35,LTE), 16)
424 checkPassFail(intScan(&index,-3,GT,3,LT), 3)
425 checkPassFail(intScan(&index,996,GT,1001,LT), 4)
426 checkPassFail(intScan(&index,0,GT,1,LT), 0)
427 checkPassFail(intScan(&index,300,GT,400,LT), 99)
428 checkPassFail(intScan(&index,3000,GTE,4000,LT), 1000)
436 std::cout <<
"Scan for ";
437 if( lowOp == GT ) { std::cout <<
"("; }
else { std::cout <<
"["; }
438 std::cout << lowVal <<
"," << highVal;
439 if( highOp == LT ) { std::cout <<
")"; }
else { std::cout <<
"]"; }
440 std::cout << std::endl;
446 index->startScan(&lowVal, lowOp, &highVal, highOp);
450 std::cout <<
"No Key Found satisfying the scan criteria." << std::endl;
458 index->scanNext(scanRid);
466 std::cout <<
" -->:" << myRec.i <<
":" << myRec.d <<
":" << myRec.s <<
":" <<std::endl;
468 else if( numResults == 5 )
470 std::cout <<
"..." << std::endl;
481 if( numResults >= 5 )
483 std::cout <<
"Number of results: " << numResults << std::endl;
486 std::cout << std::endl;
497 std::cout <<
"Create a B+ Tree index on the double field" << std::endl;
498 BTreeIndex index(relationName, doubleIndexName, bufMgr, offsetof(
tuple,d), DOUBLE);
501 checkPassFail(doubleScan(&index,25,GT,40,LT), 14)
502 checkPassFail(doubleScan(&index,20,GTE,35,LTE), 16)
503 checkPassFail(doubleScan(&index,-3,GT,3,LT), 3)
504 checkPassFail(doubleScan(&index,996,GT,1001,LT), 4)
505 checkPassFail(doubleScan(&index,0,GT,1,LT), 0)
506 checkPassFail(doubleScan(&index,300,GT,400,LT), 99)
507 checkPassFail(doubleScan(&index,3000,GTE,4000,LT), 1000)
515 std::cout <<
"Scan for ";
516 if( lowOp == GT ) { std::cout <<
"("; }
else { std::cout <<
"["; }
517 std::cout << lowVal <<
"," << highVal;
518 if( highOp == LT ) { std::cout <<
")"; }
else { std::cout <<
"]"; }
519 std::cout << std::endl;
525 index->startScan(&lowVal, lowOp, &highVal, highOp);
529 std::cout <<
"No Key Found satisfying the scan criteria." << std::endl;
537 index->scanNext(scanRid);
545 std::cout <<
" -->:" << myRec.i <<
":" << myRec.d <<
":" << myRec.s <<
":" <<std::endl;
547 else if( numResults == 5 )
549 std::cout <<
"..." << std::endl;
560 if( numResults >= 5 )
562 std::cout <<
"Number of results: " << numResults << std::endl;
565 std::cout << std::endl;
576 std::cout <<
"Create a B+ Tree index on the string field" << std::endl;
577 BTreeIndex index(relationName, stringIndexName, bufMgr, offsetof(
tuple,s), STRING);
580 checkPassFail(stringScan(&index,25,GT,40,LT), 14)
581 checkPassFail(stringScan(&index,20,GTE,35,LTE), 16)
582 checkPassFail(stringScan(&index,-3,GT,3,LT), 3)
583 checkPassFail(stringScan(&index,996,GT,1001,LT), 4)
584 checkPassFail(stringScan(&index,0,GT,1,LT), 0)
585 checkPassFail(stringScan(&index,300,GT,400,LT), 99)
586 checkPassFail(stringScan(&index,3000,GTE,4000,LT), 1000)
594 std::cout <<
"Scan for ";
595 if( lowOp == GT ) { std::cout <<
"("; }
else { std::cout <<
"["; }
596 std::cout << lowVal <<
"," << highVal;
597 if( highOp == LT ) { std::cout <<
")"; }
else { std::cout <<
"]"; }
598 std::cout << std::endl;
601 sprintf(lowValStr,
"%05d string record",lowVal);
602 char highValStr[100];
603 sprintf(highValStr,
"%05d string record",highVal);
609 index->startScan(lowValStr, lowOp, highValStr, highOp);
613 std::cout <<
"No Key Found satisfying the scan criteria." << std::endl;
621 index->scanNext(scanRid);
629 std::cout <<
" -->:" << myRec.i <<
":" << myRec.d <<
":" << myRec.s <<
":" <<std::endl;
631 else if( numResults == 5 )
633 std::cout <<
"..." << std::endl;
644 if( numResults >= 5 )
646 std::cout <<
"Number of results: " << numResults << std::endl;
649 std::cout << std::endl;
660 std::cout <<
"Error handling tests" << std::endl;
661 std::cout <<
"--------------------" << std::endl;
672 file1 =
new PageFile(relationName,
true);
675 memset(record1.s,
' ',
sizeof(record1.s));
680 for(
int i = 0; i <10; i++ )
682 sprintf(record1.s,
"%05d string record", i);
684 record1.d = (double)i;
685 std::string new_data(reinterpret_cast<char*>(&record1),
sizeof(record1));
696 file1->
writePage(new_page_number, new_page);
702 file1->
writePage(new_page_number, new_page);
704 BTreeIndex index(relationName, intIndexName, bufMgr, offsetof(
tuple,i), INTEGER);
710 std::cout <<
"Call endScan before startScan" << std::endl;
714 std::cout <<
"ScanNotInitialized Test 1 Failed." << std::endl;
718 std::cout <<
"ScanNotInitialized Test 1 Passed." << std::endl;
721 std::cout <<
"Call scanNext before startScan" << std::endl;
726 std::cout <<
"ScanNotInitialized Test 2 Failed." << std::endl;
730 std::cout <<
"ScanNotInitialized Test 2 Passed." << std::endl;
733 std::cout <<
"Scan with bad lowOp" << std::endl;
736 index.startScan(&int2, LTE, &int5, LTE);
737 std::cout <<
"BadOpcodesException Test 1 Failed." << std::endl;
741 std::cout <<
"BadOpcodesException Test 1 Passed." << std::endl;
744 std::cout <<
"Scan with bad highOp" << std::endl;
747 index.startScan(&int2, GTE, &int5, GTE);
748 std::cout <<
"BadOpcodesException Test 2 Failed." << std::endl;
752 std::cout <<
"BadOpcodesException Test 2 Passed." << std::endl;
756 std::cout <<
"Scan with bad range" << std::endl;
759 index.startScan(&int5, GTE, &int2, LTE);
760 std::cout <<
"BadScanrangeException Test 1 Failed." << std::endl;
764 std::cout <<
"BadScanrangeException Test 1 Passed." << std::endl;
770 void deleteRelation()
An exception that is thrown when some unexpected error occurs in the hash table.
An exception that is thrown when some unexpected error occurs in the hash table.
The central class which manages the buffer pool including frame allocation and deallocation to pages ...
void readPage(File *file, const PageId PageNo, Page *&page)
An exception that is thrown when a file operation is requested for a filename that doesn't exist...
const int INTARRAYNONLEAFSIZE
Number of key slots in B+Tree non-leaf for INTEGER key.
const int DOUBLEARRAYLEAFSIZE
Number of key slots in B+Tree leaf for DOUBLE key.
std::string getRecord(const RecordId &record_id) const
const int DOUBLEARRAYNONLEAFSIZE
Number of key slots in B+Tree leaf for DOUBLE key.
const int INTARRAYLEAFSIZE
Number of key slots in B+Tree leaf for INTEGER key.
Operator
Scan operations enumeration. Passed to BTreeIndex::startScan() method.
void unPinPage(File *file, const PageId PageNo, const bool dirty)
std::uint32_t PageId
Identifier for a page in a file.
An exception that is thrown when a file operation is requested for a filename that doesn't exist...
Class which represents a fixed-size database page containing records.
void writePage(const PageId page_number, const Page &new_page)
void flushFile(const File *file)
BTreeIndex class. It implements a B+ Tree index on a single attribute of a relation. This index supports only one scan at a time.
An exception that is thrown when a file operation is requested for a filename that doesn't exist...
An exception that is thrown when a file operation is requested for a filename that doesn't exist...
static void remove(const std::string &filename)
const int STRINGARRAYLEAFSIZE
Number of key slots in B+Tree leaf for STRING key.
static PageFile create(const std::string &filename)
Identifier for a record in a page.
Page allocatePage(PageId &new_page_number)
This class is used to sequentially scan records in a relation.
An exception that is thrown when a record is attempted to be inserted into a page that doesn't have s...
An exception that is thrown when some unexpected error occurs in the hash table.
const int STRINGARRAYNONLEAFSIZE
Number of key slots in B+Tree leaf for STRING key.
RecordId insertRecord(const std::string &record_data)