BadgerDB
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends Pages
main.cpp
1 
8 #include <vector>
9 #include "btree.h"
10 #include "page.h"
11 #include "filescan.h"
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"
22 
23 #define checkPassFail(a, b) \
24 { \
25  if(a == b) \
26  std::cout << "\nTest passed at line no:" << __LINE__ << "\n"; \
27  else \
28  { \
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; \
33  exit(1); \
34  } \
35 }
36 
37 using namespace badgerdb;
38 
39 // -----------------------------------------------------------------------------
40 // Globals
41 // -----------------------------------------------------------------------------
42 int testNum = 1;
43 const std::string relationName = "relA";
44 //If the relation size is changed then the second parameter 2 chechPassFail may need to be changed to number of record that are expected to be found during the scan, else tests will erroneously be reported to have failed.
45 const int relationSize = 5000;
46 std::string intIndexName, doubleIndexName, stringIndexName;
47 
48 // This is the structure for tuples in the base relation
49 
50 typedef struct tuple {
51  int i;
52  double d;
53  char s[64];
54 } RECORD;
55 
56 PageFile* file1;
57 RecordId rid;
58 RECORD record1;
59 std::string dbRecord1;
60 
61 BufMgr * bufMgr = new BufMgr(100);
62 
63 // -----------------------------------------------------------------------------
64 // Forward declarations
65 // -----------------------------------------------------------------------------
66 
67 void createRelationForward();
68 void createRelationBackward();
69 void createRelationRandom();
70 void intTests();
71 int intScan(BTreeIndex *index, int lowVal, Operator lowOp, int highVal, Operator highOp);
72 void indexTests();
73 void doubleTests();
74 int doubleScan(BTreeIndex *index, double lowVal, Operator lowOp, double highVal, Operator highOp);
75 void stringTests();
76 int stringScan(BTreeIndex *index, int lowVal, Operator lowOp, int highVal, Operator highOp);
77 void test1();
78 void test2();
79 void test3();
80 void errorTests();
81 void deleteRelation();
82 
83 int main(int argc, char **argv)
84 {
85  if( argc != 2 )
86  {
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";
91  delete bufMgr;
92  return 1;
93  }
94 
95  sscanf(argv[1],"%d",&testNum);
96 
97  switch(testNum)
98  {
99  case 1:
100  std::cout << "leaf size:" << INTARRAYLEAFSIZE << " non-leaf size:" << INTARRAYNONLEAFSIZE << std::endl;
101  break;
102  case 2:
103  std::cout << "leaf size:" << DOUBLEARRAYLEAFSIZE << " non-leaf size:" << DOUBLEARRAYNONLEAFSIZE << std::endl;
104  break;
105  case 3:
106  std::cout << "leaf size:" << STRINGARRAYLEAFSIZE << " non-leaf size:" << STRINGARRAYNONLEAFSIZE << std::endl;
107  break;
108  }
109 
110 
111  // Clean up from any previous runs that crashed.
112  try
113  {
114  File::remove(relationName);
115  }
116  catch(FileNotFoundException)
117  {
118  }
119 
120  {
121  // Create a new database file.
122  PageFile new_file = PageFile::create(relationName);
123 
124  // Allocate some pages and put data on them.
125  for (int i = 0; i < 20; ++i)
126  {
127  PageId new_page_number;
128  Page new_page = new_file.allocatePage(new_page_number);
129 
130  sprintf(record1.s, "%05d string record", i);
131  record1.i = i;
132  record1.d = (double)i;
133  std::string new_data(reinterpret_cast<char*>(&record1), sizeof(record1));
134 
135  new_page.insertRecord(new_data);
136  new_file.writePage(new_page_number, new_page);
137  }
138 
139  }
140  // new_file goes out of scope here, so file is automatically closed.
141 
142  {
143  FileScan fscan(relationName, bufMgr);
144 
145  try
146  {
147  RecordId scanRid;
148  while(1)
149  {
150  fscan.scanNext(scanRid);
151  //Assuming RECORD.i is our key, lets extract the key, which we know is INTEGER and whose byte offset is also know inside the record.
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;
156  }
157  }
158  catch(EndOfFileException e)
159  {
160  std::cout << "Read all records" << std::endl;
161  }
162  }
163  // filescan goes out of scope here, so relation file gets closed.
164 
165  File::remove(relationName);
166 
167  test1();
168  test2();
169  test3();
170  //errorTests();
171 
172  delete bufMgr;
173  return 0;
174 }
175 
176 void test1()
177 {
178  // Create a relation with tuples valued 0 to relationSize and perform index tests
179  // on attributes of all three types (int, double, string)
180  std::cout << "---------------------" << std::endl;
181  std::cout << "createRelationForward" << std::endl;
182  createRelationForward();
183  indexTests();
184  deleteRelation();
185 }
186 
187 void test2()
188 {
189  // Create a relation with tuples valued 0 to relationSize in reverse order and perform index tests
190  // on attributes of all three types (int, double, string)
191  std::cout << "----------------------" << std::endl;
192  std::cout << "createRelationBackward" << std::endl;
193  createRelationBackward();
194  indexTests();
195  deleteRelation();
196 }
197 
198 void test3()
199 {
200  // Create a relation with tuples valued 0 to relationSize in random order and perform index tests
201  // on attributes of all three types (int, double, string)
202  std::cout << "--------------------" << std::endl;
203  std::cout << "createRelationRandom" << std::endl;
204  createRelationRandom();
205  indexTests();
206  deleteRelation();
207 }
208 
209 // -----------------------------------------------------------------------------
210 // createRelationForward
211 // -----------------------------------------------------------------------------
212 
213 void createRelationForward()
214 {
215  std::vector<RecordId> ridVec;
216  // destroy any old copies of relation file
217  try
218  {
219  File::remove(relationName);
220  }
221  catch(FileNotFoundException e)
222  {
223  }
224 
225  file1 = new PageFile(relationName, true);
226 
227  // initialize all of record1.s to keep purify happy
228  memset(record1.s, ' ', sizeof(record1.s));
229  PageId new_page_number;
230  Page new_page = file1->allocatePage(new_page_number);
231 
232  // Insert a bunch of tuples into the relation.
233  for(int i = 0; i < relationSize; i++ )
234  {
235  sprintf(record1.s, "%05d string record", i);
236  record1.i = i;
237  record1.d = (double)i;
238  std::string new_data(reinterpret_cast<char*>(&record1), sizeof(record1));
239 
240  while(1)
241  {
242  try
243  {
244  new_page.insertRecord(new_data);
245  break;
246  }
248  {
249  file1->writePage(new_page_number, new_page);
250  new_page = file1->allocatePage(new_page_number);
251  }
252  }
253  }
254 
255  file1->writePage(new_page_number, new_page);
256 }
257 
258 // -----------------------------------------------------------------------------
259 // createRelationBackward
260 // -----------------------------------------------------------------------------
261 
262 void createRelationBackward()
263 {
264  // destroy any old copies of relation file
265  try
266  {
267  File::remove(relationName);
268  }
269  catch(FileNotFoundException e)
270  {
271  }
272  file1 = new PageFile(relationName, true);
273 
274  // initialize all of record1.s to keep purify happy
275  memset(record1.s, ' ', sizeof(record1.s));
276  PageId new_page_number;
277  Page new_page = file1->allocatePage(new_page_number);
278 
279  // Insert a bunch of tuples into the relation.
280  for(int i = relationSize - 1; i >= 0; i-- )
281  {
282  sprintf(record1.s, "%05d string record", i);
283  record1.i = i;
284  record1.d = i;
285 
286  std::string new_data(reinterpret_cast<char*>(&record1), sizeof(RECORD));
287 
288  while(1)
289  {
290  try
291  {
292  new_page.insertRecord(new_data);
293  break;
294  }
296  {
297  file1->writePage(new_page_number, new_page);
298  new_page = file1->allocatePage(new_page_number);
299  }
300  }
301  }
302 
303  file1->writePage(new_page_number, new_page);
304 }
305 
306 // -----------------------------------------------------------------------------
307 // createRelationRandom
308 // -----------------------------------------------------------------------------
309 
310 void createRelationRandom()
311 {
312  // destroy any old copies of relation file
313  try
314  {
315  File::remove(relationName);
316  }
317  catch(FileNotFoundException e)
318  {
319  }
320  file1 = new PageFile(relationName, true);
321 
322  // initialize all of record1.s to keep purify happy
323  memset(record1.s, ' ', sizeof(record1.s));
324  PageId new_page_number;
325  Page new_page = file1->allocatePage(new_page_number);
326 
327  // insert records in random order
328 
329  std::vector<int> intvec(relationSize);
330  for( int i = 0; i < relationSize; i++ )
331  {
332  intvec[i] = i;
333  }
334 
335  long pos;
336  int val;
337  int i = 0;
338  while( i < relationSize )
339  {
340  pos = random() % (relationSize-i);
341  val = intvec[pos];
342  sprintf(record1.s, "%05d string record", val);
343  record1.i = val;
344  record1.d = val;
345 
346  std::string new_data(reinterpret_cast<char*>(&record1), sizeof(RECORD));
347 
348  while(1)
349  {
350  try
351  {
352  new_page.insertRecord(new_data);
353  break;
354  }
356  {
357  file1->writePage(new_page_number, new_page);
358  new_page = file1->allocatePage(new_page_number);
359  }
360  }
361 
362  int temp = intvec[relationSize-1-i];
363  intvec[relationSize-1-i] = intvec[pos];
364  intvec[pos] = temp;
365  i++;
366  }
367 
368  file1->writePage(new_page_number, new_page);
369 }
370 
371 // -----------------------------------------------------------------------------
372 // indexTests
373 // -----------------------------------------------------------------------------
374 
375 void indexTests()
376 {
377  if(testNum == 1)
378  {
379  intTests();
380  try
381  {
382  File::remove(intIndexName);
383  }
384  catch(FileNotFoundException e)
385  {
386  }
387  }
388  else if(testNum == 2)
389  {
390  doubleTests();
391  try
392  {
393  File::remove(doubleIndexName);
394  }
395  catch(FileNotFoundException e)
396  {
397  }
398  }
399  else if(testNum == 3)
400  {
401  stringTests();
402  try
403  {
404  File::remove(stringIndexName);
405  }
406  catch(FileNotFoundException e)
407  {
408  }
409  }
410 }
411 
412 // -----------------------------------------------------------------------------
413 // intTests
414 // -----------------------------------------------------------------------------
415 
416 void intTests()
417 {
418  std::cout << "Create a B+ Tree index on the integer field" << std::endl;
419  BTreeIndex index(relationName, intIndexName, bufMgr, offsetof(tuple,i), INTEGER);
420 
421  // run some tests
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)
429 }
430 
431 int intScan(BTreeIndex * index, int lowVal, Operator lowOp, int highVal, Operator highOp)
432 {
433  RecordId scanRid;
434  Page *curPage;
435 
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;
441 
442  int numResults = 0;
443 
444  try
445  {
446  index->startScan(&lowVal, lowOp, &highVal, highOp);
447  }
448  catch(NoSuchKeyFoundException e)
449  {
450  std::cout << "No Key Found satisfying the scan criteria." << std::endl;
451  return 0;
452  }
453 
454  while(1)
455  {
456  try
457  {
458  index->scanNext(scanRid);
459  bufMgr->readPage(file1, scanRid.page_number, curPage);
460  RECORD myRec = *(reinterpret_cast<const RECORD*>(curPage->getRecord(scanRid).data()));
461  bufMgr->unPinPage(file1, scanRid.page_number, false);
462 
463  if( numResults < 5 )
464  {
465  std::cout << "at:" << scanRid.page_number << "," << scanRid.slot_number;
466  std::cout << " -->:" << myRec.i << ":" << myRec.d << ":" << myRec.s << ":" <<std::endl;
467  }
468  else if( numResults == 5 )
469  {
470  std::cout << "..." << std::endl;
471  }
472  }
474  {
475  break;
476  }
477 
478  numResults++;
479  }
480 
481  if( numResults >= 5 )
482  {
483  std::cout << "Number of results: " << numResults << std::endl;
484  }
485  index->endScan();
486  std::cout << std::endl;
487 
488  return numResults;
489 }
490 
491 // -----------------------------------------------------------------------------
492 // doubleTests
493 // -----------------------------------------------------------------------------
494 
495 void doubleTests()
496 {
497  std::cout << "Create a B+ Tree index on the double field" << std::endl;
498  BTreeIndex index(relationName, doubleIndexName, bufMgr, offsetof(tuple,d), DOUBLE);
499 
500  // run some tests
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)
508 }
509 
510 int doubleScan(BTreeIndex * index, double lowVal, Operator lowOp, double highVal, Operator highOp)
511 {
512  RecordId scanRid;
513  Page *curPage;
514 
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;
520 
521  int numResults = 0;
522 
523  try
524  {
525  index->startScan(&lowVal, lowOp, &highVal, highOp);
526  }
527  catch(NoSuchKeyFoundException e)
528  {
529  std::cout << "No Key Found satisfying the scan criteria." << std::endl;
530  return 0;
531  }
532 
533  while(1)
534  {
535  try
536  {
537  index->scanNext(scanRid);
538  bufMgr->readPage(file1, scanRid.page_number, curPage);
539  RECORD myRec = *(reinterpret_cast<const RECORD*>(curPage->getRecord(scanRid).data()));
540  bufMgr->unPinPage(file1, scanRid.page_number, false);
541 
542  if( numResults < 5 )
543  {
544  std::cout << "rid:" << scanRid.page_number << "," << scanRid.slot_number;
545  std::cout << " -->:" << myRec.i << ":" << myRec.d << ":" << myRec.s << ":" <<std::endl;
546  }
547  else if( numResults == 5 )
548  {
549  std::cout << "..." << std::endl;
550  }
551  }
553  {
554  break;
555  }
556 
557  numResults++;
558  }
559 
560  if( numResults >= 5 )
561  {
562  std::cout << "Number of results: " << numResults << std::endl;
563  }
564  index->endScan();
565  std::cout << std::endl;
566 
567  return numResults;
568 }
569 
570 // -----------------------------------------------------------------------------
571 // stringTests
572 // -----------------------------------------------------------------------------
573 
574 void stringTests()
575 {
576  std::cout << "Create a B+ Tree index on the string field" << std::endl;
577  BTreeIndex index(relationName, stringIndexName, bufMgr, offsetof(tuple,s), STRING);
578 
579  // run some tests
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)
587 }
588 
589 int stringScan(BTreeIndex * index, int lowVal, Operator lowOp, int highVal, Operator highOp)
590 {
591  RecordId scanRid;
592  Page *curPage;
593 
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;
599 
600  char lowValStr[100];
601  sprintf(lowValStr,"%05d string record",lowVal);
602  char highValStr[100];
603  sprintf(highValStr,"%05d string record",highVal);
604 
605  int numResults = 0;
606 
607  try
608  {
609  index->startScan(lowValStr, lowOp, highValStr, highOp);
610  }
611  catch(NoSuchKeyFoundException e)
612  {
613  std::cout << "No Key Found satisfying the scan criteria." << std::endl;
614  return 0;
615  }
616 
617  while(1)
618  {
619  try
620  {
621  index->scanNext(scanRid);
622  bufMgr->readPage(file1, scanRid.page_number, curPage);
623  RECORD myRec = *(reinterpret_cast<const RECORD*>(curPage->getRecord(scanRid).data()));
624  bufMgr->unPinPage(file1, scanRid.page_number, false);
625 
626  if( numResults < 5 )
627  {
628  std::cout << "rid:" << scanRid.page_number << "," << scanRid.slot_number;
629  std::cout << " -->:" << myRec.i << ":" << myRec.d << ":" << myRec.s << ":" <<std::endl;
630  }
631  else if( numResults == 5 )
632  {
633  std::cout << "..." << std::endl;
634  }
635  }
637  {
638  break;
639  }
640 
641  numResults++;
642  }
643 
644  if( numResults >= 5 )
645  {
646  std::cout << "Number of results: " << numResults << std::endl;
647  }
648  index->endScan();
649  std::cout << std::endl;
650 
651  return numResults;
652 }
653 
654 // -----------------------------------------------------------------------------
655 // errorTests
656 // -----------------------------------------------------------------------------
657 
658 void errorTests()
659 {
660  std::cout << "Error handling tests" << std::endl;
661  std::cout << "--------------------" << std::endl;
662  // Given error test
663 
664  try
665  {
666  File::remove(relationName);
667  }
668  catch(FileNotFoundException e)
669  {
670  }
671 
672  file1 = new PageFile(relationName, true);
673 
674  // initialize all of record1.s to keep purify happy
675  memset(record1.s, ' ', sizeof(record1.s));
676  PageId new_page_number;
677  Page new_page = file1->allocatePage(new_page_number);
678 
679  // Insert a bunch of tuples into the relation.
680  for(int i = 0; i <10; i++ )
681  {
682  sprintf(record1.s, "%05d string record", i);
683  record1.i = i;
684  record1.d = (double)i;
685  std::string new_data(reinterpret_cast<char*>(&record1), sizeof(record1));
686 
687  while(1)
688  {
689  try
690  {
691  new_page.insertRecord(new_data);
692  break;
693  }
695  {
696  file1->writePage(new_page_number, new_page);
697  new_page = file1->allocatePage(new_page_number);
698  }
699  }
700  }
701 
702  file1->writePage(new_page_number, new_page);
703 
704  BTreeIndex index(relationName, intIndexName, bufMgr, offsetof(tuple,i), INTEGER);
705 
706  int int2 = 2;
707  int int5 = 5;
708 
709  // Scan Tests
710  std::cout << "Call endScan before startScan" << std::endl;
711  try
712  {
713  index.endScan();
714  std::cout << "ScanNotInitialized Test 1 Failed." << std::endl;
715  }
717  {
718  std::cout << "ScanNotInitialized Test 1 Passed." << std::endl;
719  }
720 
721  std::cout << "Call scanNext before startScan" << std::endl;
722  try
723  {
724  RecordId foo;
725  index.scanNext(foo);
726  std::cout << "ScanNotInitialized Test 2 Failed." << std::endl;
727  }
729  {
730  std::cout << "ScanNotInitialized Test 2 Passed." << std::endl;
731  }
732 
733  std::cout << "Scan with bad lowOp" << std::endl;
734  try
735  {
736  index.startScan(&int2, LTE, &int5, LTE);
737  std::cout << "BadOpcodesException Test 1 Failed." << std::endl;
738  }
739  catch(BadOpcodesException e)
740  {
741  std::cout << "BadOpcodesException Test 1 Passed." << std::endl;
742  }
743 
744  std::cout << "Scan with bad highOp" << std::endl;
745  try
746  {
747  index.startScan(&int2, GTE, &int5, GTE);
748  std::cout << "BadOpcodesException Test 2 Failed." << std::endl;
749  }
750  catch(BadOpcodesException e)
751  {
752  std::cout << "BadOpcodesException Test 2 Passed." << std::endl;
753  }
754 
755 
756  std::cout << "Scan with bad range" << std::endl;
757  try
758  {
759  index.startScan(&int5, GTE, &int2, LTE);
760  std::cout << "BadScanrangeException Test 1 Failed." << std::endl;
761  }
762  catch(BadScanrangeException e)
763  {
764  std::cout << "BadScanrangeException Test 1 Passed." << std::endl;
765  }
766 
767  deleteRelation();
768 }
769 
770 void deleteRelation()
771 {
772  if(file1)
773  {
774  bufMgr->flushFile(file1);
775  delete file1;
776  file1 = NULL;
777  }
778  try
779  {
780  File::remove(relationName);
781  }
782  catch(FileNotFoundException e)
783  {
784  }
785 }
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 ...
Definition: buffer.h:161
void readPage(File *file, const PageId PageNo, Page *&page)
Definition: buffer.cpp:120
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.
Definition: btree.h:71
const int DOUBLEARRAYLEAFSIZE
Number of key slots in B+Tree leaf for DOUBLE key.
Definition: btree.h:59
std::string getRecord(const RecordId &record_id) const
Definition: page.cpp:46
const int DOUBLEARRAYNONLEAFSIZE
Number of key slots in B+Tree leaf for DOUBLE key.
Definition: btree.h:77
const int INTARRAYLEAFSIZE
Number of key slots in B+Tree leaf for INTEGER key.
Definition: btree.h:53
Operator
Scan operations enumeration. Passed to BTreeIndex::startScan() method.
Definition: btree.h:36
void unPinPage(File *file, const PageId PageNo, const bool dirty)
Definition: buffer.cpp:154
std::uint32_t PageId
Identifier for a page in a file.
Definition: types.h:15
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.
Definition: page.h:108
SlotId slot_number
Definition: types.h:39
void writePage(const PageId page_number, const Page &new_page)
Definition: file.cpp:260
void flushFile(const File *file)
Definition: buffer.cpp:171
Definition: main.cpp:50
PageId page_number
Definition: types.h:34
BTreeIndex class. It implements a B+ Tree index on a single attribute of a relation. This index supports only one scan at a time.
Definition: btree.h:295
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)
Definition: file.cpp:29
const int STRINGARRAYLEAFSIZE
Number of key slots in B+Tree leaf for STRING key.
Definition: btree.h:65
static PageFile create(const std::string &filename)
Definition: file.cpp:135
Identifier for a record in a page.
Definition: types.h:30
Page allocatePage(PageId &new_page_number)
Definition: file.cpp:165
This class is used to sequentially scan records in a relation.
Definition: filescan.h:23
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.
Definition: btree.h:83
RecordId insertRecord(const std::string &record_data)
Definition: page.cpp:36