kamilosxd678

Basy

Jan 8th, 2014
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 45.84 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <sys/stat.h>
  4. #include <fstream>
  5. #include <ctime>
  6.  
  7.  
  8. const double PI = 3.14159265359;
  9. const int DATA_BUFFER_SIZE = 400;
  10. const int INDEX_BUFFER_SIZE = 20;
  11. const int OVERFLOW_MAX_SIZE = 800;
  12. const double ALPHA = 0.6;
  13. int RECORDS_PER_PAGE = DATA_BUFFER_SIZE * ALPHA;
  14.  
  15. class CStats
  16. {
  17. public:
  18. int m_discReads;
  19. int m_discWrites;
  20. int m_reorganisations;
  21. bool m_freeze;
  22. void incReorganisations()
  23. {
  24. if(!m_freeze)
  25. m_reorganisations++;
  26. }
  27. void incDiscReads()
  28. {
  29. if(!m_freeze)
  30. m_discReads++;
  31. }
  32. void incDiscWrites()
  33. {
  34. if(!m_freeze)
  35. m_discWrites++;
  36. }
  37. void freeze()
  38. {
  39. m_freeze = true;
  40. }
  41. void unfreeze()
  42. {
  43. m_freeze = false;
  44. }
  45. void print()
  46. {
  47. std::cout << "Writes: " << m_discWrites << " reads: " << m_discReads << " reorgs: " << m_reorganisations << std::endl;
  48. }
  49. CStats()
  50. {
  51. m_discReads = 0;
  52. m_discWrites = 0;
  53. m_reorganisations = 0;
  54. m_freeze = false;
  55. }
  56. } Stats;
  57. enum EOperationType
  58. {
  59. ADD_RECORD,
  60. REM_RECORD,
  61. FIND_RECORD,
  62. MODIFY_RECORD,
  63. REORGANIZE_DATABASE,
  64. PRINT_SORTED,
  65. PRINT_AS_IS
  66. };
  67.  
  68. //Record class
  69. class CCone
  70. {
  71. private:
  72. int m_radius;
  73. int m_height;
  74. public:
  75. //Getters
  76. inline int getRadius(){ return m_radius; }
  77. inline int getHeight(){ return m_height; }
  78. inline double getVolume(){
  79. double dRadius2 = (double)m_radius;
  80. double dPI = (double)PI;
  81. double dHeight = (double)m_height;
  82. double dThird = (double)1;
  83. dThird /= (double)3;
  84. dRadius2 *= dRadius2;
  85. return dThird*dPI*dRadius2*dHeight;
  86. }
  87. //Setters
  88. inline void setRadius(int radius) { m_radius = radius; }
  89. inline void setHeight(int height) { m_height = height; }
  90. //Others
  91. void reset()
  92. {
  93. m_radius = 0;
  94. m_height = 0;
  95. }
  96. //Constructors
  97. CCone()
  98. {
  99. m_radius = 0;
  100. m_height = 0;
  101. }
  102. CCone(int radius, int height)
  103. {
  104. m_radius = radius;
  105. m_height = height;
  106. }
  107. };
  108.  
  109. class CRecord
  110. {
  111. private:
  112. int m_key;
  113. CCone m_data;
  114. unsigned int m_overflowPointer;
  115. public:
  116. inline int getKey() { return m_key; }
  117. inline CCone* getDataPtr() { return &m_data; }
  118. inline CCone getData() { return m_data; }
  119. inline int getOverflowPointer() { return m_overflowPointer; }
  120. inline bool hasOverflowArea() { return m_overflowPointer != NULL; }
  121. void setData(int height, int radius)
  122. {
  123. m_data.setHeight(height);
  124. m_data.setRadius(radius);
  125. }
  126. inline void setKey(int key) { m_key = key; }
  127. inline void setOverflowPointer(int ovfPtr) { m_overflowPointer = ovfPtr; }
  128. std::string toString()
  129. {
  130. char ret[512];
  131. for(int i = 0; i < 512; i++)
  132. ret[i] = 0;
  133. if(m_key == 0xFFFFFFFF)
  134. {
  135. return "RECORD EMPTY";
  136. }
  137. else
  138. {
  139. sprintf(ret, "(Key: %d; Data: (H: %d; R: %d); overflowPtr: %d)", m_key, m_data.getHeight(), m_data.getRadius(), m_overflowPointer);
  140. }
  141. std::string retVal(ret);
  142. return retVal;
  143. }
  144. void setAll(CRecord* input)
  145. {
  146. m_key = input->getKey();
  147. m_data.setRadius(input->getData().getRadius());
  148. m_data.setHeight(input->getData().getHeight());
  149. m_overflowPointer = input->getOverflowPointer();
  150. }
  151. void reset()
  152. {
  153. m_key = 0xFFFFFFFF;
  154. m_data.reset();
  155. m_overflowPointer = 0;
  156. }
  157. CRecord()
  158. {
  159. m_key = 0xFFFFFFFF;
  160. m_overflowPointer = NULL;
  161. }
  162. CRecord(int key, int radius, int height)
  163. {
  164. m_key = key;
  165. m_data.setHeight(height);
  166. m_data.setRadius(radius);
  167. m_overflowPointer = NULL;
  168. }
  169. };
  170.  
  171. class CIndex
  172. {
  173. private:
  174. int m_key;
  175. int m_pageNumber;
  176. public:
  177. inline int getKey() { return m_key; }
  178. inline int getPageNumber() { return m_pageNumber; }
  179. inline int getPageByte() { return m_pageNumber*sizeof(CCone); }
  180. inline void setPageNumber(int pageNumber) { m_pageNumber = pageNumber; }
  181. inline void setKey(int key) { m_key = key; }
  182. std::string toString()
  183. {
  184. char ret[512];
  185. for(int i = 0; i < 512; i++)
  186. ret[i] = 0;
  187. if(m_key == 0xFFFFFFFF)
  188. {
  189. return "INDEX EMPTY";
  190. }
  191. else
  192. {
  193. sprintf(ret, "(Key: %d; PageNumber: %d)", m_key, m_pageNumber);
  194. }
  195. std::string retVal(ret);
  196. return retVal;
  197. }
  198. void setAll(CIndex* idx)
  199. {
  200. m_key = idx->getKey();
  201. m_pageNumber = idx->getPageNumber();
  202. }
  203. void reset()
  204. {
  205. m_key = 0xFFFFFFFF;
  206. m_pageNumber = 0xFFFFFFFF;
  207. }
  208. CIndex()
  209. {
  210. m_key = 0xFFFFFFFF;
  211. m_pageNumber = 0xFFFFFFFF;
  212. }
  213. CIndex(int key)
  214. {
  215. m_key = key;
  216. m_pageNumber = 0xFFFFFFFF;
  217. }
  218. CIndex(int key, int pageNumber)
  219. {
  220. m_key = key;
  221. m_pageNumber = pageNumber;
  222. }
  223. };
  224.  
  225. template <typename T>
  226. class CBase
  227. {
  228. protected:
  229. int BUFFER_SIZE;
  230. //File preferences
  231. FILE *m_saveFilePtr;
  232. std::string m_name;
  233. char m_filename[10];
  234. //IO Points
  235. int m_lastFileReadPoint;
  236. int m_lastFileWritePoint;
  237. int m_actualBufferReadPoint;
  238. int m_actualBufferWritePoint;
  239. bool m_readSuccessful;
  240. T* m_readBuffer;
  241. T* m_writeBuffer;
  242. public:
  243. int getPagesInFileCnt()
  244. {
  245. struct stat st;
  246. stat(m_filename, &st);
  247. int pagesInDataFile = st.st_size/(BUFFER_SIZE*sizeof(T));
  248. return pagesInDataFile;
  249. }
  250. int getElementsCnt()
  251. {
  252. struct stat st;
  253. stat(m_filename, &st);
  254. int retval = st.st_size/sizeof(T);
  255. return retval;
  256. }
  257. inline T* getReadBufferPtr() { return m_readBuffer; }
  258. inline T* getWriteBufferPtr() { return m_writeBuffer; }
  259. //Adders
  260. inline void addNextRecord(T* input) { m_writeBuffer[m_actualBufferWritePoint++].setAll(input); }
  261. inline T* getNextRecord() { return &m_readBuffer[m_actualBufferReadPoint++]; }
  262. inline T* getActualRecord() { return &m_readBuffer[m_actualBufferReadPoint]; }
  263. inline T* getPreviousRecord() { return &m_readBuffer[m_actualBufferReadPoint-1]; }
  264. //Getters
  265. inline int getLastFileReadPoint() { return m_lastFileReadPoint; }
  266. inline int getLastFileWritePoint() { return m_lastFileWritePoint; }
  267. inline int getActualBufferReadPoint() { return m_actualBufferReadPoint; }
  268. inline int getActualBufferWritePoint() { return m_actualBufferWritePoint; }
  269. inline std::string getName() { return m_name; }
  270. inline std::string getFilename() { return (std::string)m_filename; }
  271. inline bool isReadSuccessful() { return m_readSuccessful; }
  272. inline bool isReadBufferFull() { return m_actualBufferReadPoint == BUFFER_SIZE; }
  273. inline bool isWriteBufferFull() { return m_actualBufferWritePoint == BUFFER_SIZE; }
  274. inline bool isReadBufferEmpty() { return m_actualBufferReadPoint == 0; }
  275. inline bool isWriteBufferEmpty() { return m_actualBufferWritePoint == 0; }
  276. //Setters
  277. inline void setLastFileReadPoint(int point) { m_lastFileReadPoint = point; }
  278. inline void setLastFileWritePoint(int point) { m_lastFileWritePoint = point; }
  279. inline void setActualBufferReadPoint(int point) { m_actualBufferReadPoint = point; }
  280. inline void setActualBufferWritePoint(int point) { m_actualBufferWritePoint = point; }
  281. inline void clearActualBufferReadPoint() { m_actualBufferReadPoint = 0; }
  282. inline void clearActualBufferWritePoint() { m_actualBufferWritePoint = 0; }
  283. inline void incActualBufferReadPoint() { m_actualBufferReadPoint++; }
  284. inline void incActualBufferWritePoint() { m_actualBufferWritePoint++; }
  285. void clearFile()
  286. {
  287. m_saveFilePtr = fopen(m_filename, "wb");
  288. fclose(m_saveFilePtr);
  289. }
  290. void setName(std::string name)
  291. {
  292. m_name = name;
  293. strcpy(m_filename,name.c_str());
  294. m_filename[5] = '.';
  295. m_filename[6] = 'b';
  296. m_filename[7] = 'i';
  297. m_filename[8] = 'n';
  298. m_filename[9] = '\0';
  299. struct stat st;
  300. stat(m_filename, &st);
  301. if(st.st_size < 0)
  302. {
  303. m_saveFilePtr = fopen(m_filename, "wb");
  304. fclose(m_saveFilePtr);
  305. }
  306. }
  307. //Other
  308. int getEOF()
  309. {
  310. int retVal;
  311. m_saveFilePtr = fopen(m_filename, "rb");
  312. fseek(m_saveFilePtr, 0, SEEK_END);
  313. retVal = ftell(m_saveFilePtr);
  314. fclose(m_saveFilePtr);
  315. return retVal;
  316. }
  317. inline T* getLastWriteBufferRecord() { return &m_writeBuffer[m_actualBufferWritePoint]; }
  318. inline T* getLastReadBufferRecord() { return &m_readBuffer[m_actualBufferReadPoint]; }
  319. void readPage(int pageNum)
  320. {
  321. m_saveFilePtr = fopen(m_filename, "rb");
  322. fseek(m_saveFilePtr, pageNum*BUFFER_SIZE*sizeof(T), SEEK_SET);
  323. m_readSuccessful = fread(m_readBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
  324. m_lastFileReadPoint = ftell(m_saveFilePtr);
  325. fclose(m_saveFilePtr);
  326. Stats.incDiscReads();
  327. }
  328. void writePage(int pageNum)
  329. {
  330. m_saveFilePtr = fopen(m_filename, "r+b");
  331. fseek(m_saveFilePtr, pageNum*BUFFER_SIZE*sizeof(T), SEEK_SET);
  332. fwrite(m_writeBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
  333. m_lastFileWritePoint = ftell(m_saveFilePtr);
  334. fclose(m_saveFilePtr);
  335. Stats.incDiscWrites();
  336. }
  337. void readPage()
  338. {
  339. m_saveFilePtr = fopen(m_filename, "rb");
  340. fseek(m_saveFilePtr, m_lastFileReadPoint, SEEK_SET);
  341. m_readSuccessful = fread(m_readBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
  342. m_lastFileReadPoint = ftell(m_saveFilePtr);
  343. fclose(m_saveFilePtr);
  344. Stats.incDiscReads();
  345. }
  346. void writePage()
  347. {
  348. m_saveFilePtr = fopen(m_filename, "r+b");
  349. fseek(m_saveFilePtr, m_lastFileWritePoint, SEEK_SET);
  350. fwrite(m_writeBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
  351. m_lastFileWritePoint = ftell(m_saveFilePtr);
  352. fclose(m_saveFilePtr);
  353. Stats.incDiscWrites();
  354. }
  355. void clearReadBuffer()
  356. {
  357. for(int i = 0; i < BUFFER_SIZE; i++)
  358. {
  359. m_readBuffer[i].reset();
  360. }
  361. }
  362. void clearWriteBuffer()
  363. {
  364. for(int i = 0; i < BUFFER_SIZE; i++)
  365. {
  366. m_writeBuffer[i].reset();
  367. }
  368. }
  369. void loadPage(int pageNum)
  370. {
  371. m_actualBufferReadPoint = 0;
  372. clearReadBuffer();
  373. readPage(pageNum);
  374. }
  375. void savePage(int pageNum)
  376. {
  377. writePage(pageNum);
  378. m_actualBufferWritePoint = 0;
  379. clearWriteBuffer();
  380. }
  381. void loadNextPage()
  382. {
  383. m_actualBufferReadPoint = 0;
  384. clearReadBuffer();
  385. readPage();
  386. }
  387. void saveNextPage()
  388. {
  389. writePage();
  390. m_actualBufferWritePoint = 0;
  391. clearWriteBuffer();
  392. }
  393. void copyReadBuffer(T* inputBuffer)
  394. {
  395. for(int i = 0; i < BUFFER_SIZE; i++)
  396. {
  397. m_readBuffer[i].setAll(&inputBuffer[i]);
  398. }
  399. }
  400. void copyWriteBuffer(T* inputBuffer)
  401. {
  402. for(int i = 0; i < BUFFER_SIZE; i++)
  403. {
  404. m_writeBuffer[i].setAll(&inputBuffer[i]);
  405. }
  406. }
  407. void resetStats()
  408. {
  409. m_lastFileReadPoint = 0;
  410. m_lastFileWritePoint = 0;
  411. m_actualBufferReadPoint = 0;
  412. m_actualBufferWritePoint = 0;
  413. clearReadBuffer();
  414. clearWriteBuffer();
  415. m_readSuccessful = false;
  416. }
  417. void reset()
  418. {
  419. m_lastFileReadPoint = 0;
  420. m_lastFileWritePoint = 0;
  421. m_actualBufferReadPoint = 0;
  422. m_actualBufferWritePoint = 0;
  423. clearReadBuffer();
  424. clearWriteBuffer();
  425. m_readSuccessful = false;
  426. m_saveFilePtr = fopen(m_filename, "wb");
  427. fclose(m_saveFilePtr);
  428. }
  429. };
  430.  
  431. class CIndexesDatabase: public CBase<CIndex>
  432. {
  433. public:
  434. inline char* getFilename() { return m_filename; }
  435. bool findPageForKey(int inputKey, int* outputPageNum, bool* duplicate)
  436. {
  437. *outputPageNum = -1;
  438. *duplicate = false;
  439. int pagesInFile = getPagesInFileCnt();
  440. bool found = false;
  441. for(int i = 0; i < pagesInFile && !found && !(*duplicate); i++)
  442. {
  443. loadPage(i);
  444. for(int j = 0; j < BUFFER_SIZE; j++)
  445. {
  446. if(i == 0 && j == 0)
  447. continue;
  448. if(m_readBuffer[j].getKey() == inputKey)
  449. {
  450. *outputPageNum = m_readBuffer[j].getPageNumber();
  451. *duplicate = true;
  452. break;
  453. }
  454. if(m_readBuffer[j].getKey() > inputKey || m_readBuffer[j].getKey() == 0xFFFFFFFF)
  455. {
  456. found = true;
  457. if(j == 0) //Last good record was on previous page
  458. {
  459. loadPage(i-1);
  460. *outputPageNum = m_readBuffer[BUFFER_SIZE-1].getPageNumber();
  461. }
  462. else
  463. {
  464. *outputPageNum = m_readBuffer[j-1].getPageNumber();
  465. }
  466. break;
  467. }
  468. }
  469. }
  470. return found;
  471. }
  472.  
  473. void addIdxPage()
  474. {
  475. int lastWritePoint = m_lastFileWritePoint;
  476. m_lastFileWritePoint = getEOF();
  477. int pagesInFile = getPagesInFileCnt();
  478. clearWriteBuffer();
  479. for(int i = 0; i < INDEX_BUFFER_SIZE; i++)
  480. {
  481. m_writeBuffer[i].setPageNumber(pagesInFile*INDEX_BUFFER_SIZE+i);
  482. }
  483. writePage();
  484. clearWriteBuffer();
  485. m_lastFileWritePoint = lastWritePoint;
  486. }
  487. //Constructor
  488. CIndexesDatabase(std::string name)
  489. {
  490. BUFFER_SIZE = INDEX_BUFFER_SIZE;
  491. m_writeBuffer = new CIndex[BUFFER_SIZE];
  492. m_readBuffer = new CIndex[BUFFER_SIZE];
  493. setName(name);
  494. //Clear buffer and points
  495. m_lastFileReadPoint = 0;
  496. m_lastFileWritePoint = 0;
  497. m_actualBufferReadPoint = 0;
  498. m_actualBufferWritePoint = 0;
  499. clearReadBuffer();
  500. clearWriteBuffer();
  501. m_readSuccessful = false;
  502. }
  503. };
  504.  
  505. class CDatabase: public CBase<CRecord>
  506. {
  507. private:
  508. CRecord m_tmpOverflowRecord;
  509. public:
  510. int addOverflowRecord(CRecord* input)
  511. {
  512. struct stat st;
  513. stat(m_filename, &st);
  514. int newRecordByte;
  515. m_saveFilePtr = fopen(m_filename, "r+b");
  516. fseek(m_saveFilePtr, st.st_size, SEEK_SET);
  517. fwrite(input, sizeof(CRecord), 1, m_saveFilePtr);
  518. newRecordByte = ftell(m_saveFilePtr) - sizeof(CRecord);
  519. fclose(m_saveFilePtr);
  520. Stats.incDiscWrites();
  521. return newRecordByte;
  522. }
  523. void modifyOverflowRecord(CRecord* input, int byte)
  524. {
  525. m_saveFilePtr = fopen(m_filename, "r+b");
  526. fseek(m_saveFilePtr, byte, SEEK_SET);
  527. fwrite(input, sizeof(CRecord), 1, m_saveFilePtr);
  528. fclose(m_saveFilePtr);
  529. Stats.incDiscWrites();
  530. }
  531. void clearOverflowRecord(int byte)
  532. {
  533. CRecord empty;
  534. m_saveFilePtr = fopen(m_filename, "r+b");
  535. fseek(m_saveFilePtr, byte, SEEK_SET);
  536. fwrite(&empty, sizeof(CRecord), 1, m_saveFilePtr);
  537. fclose(m_saveFilePtr);
  538. Stats.incDiscWrites();
  539. }
  540. CRecord* getOverflowRecord(int byte)
  541. {
  542. m_saveFilePtr = fopen(m_filename, "rb");
  543. fseek(m_saveFilePtr, byte, SEEK_SET);
  544. m_readSuccessful = fread(&m_tmpOverflowRecord, sizeof(CRecord), 1, m_saveFilePtr);
  545. fclose(m_saveFilePtr);
  546. Stats.incDiscReads();
  547. return &m_tmpOverflowRecord;
  548. }
  549. bool findMatchingPlaceForKey(int inputKey, int pageNum, int* outputPosOnPage, bool* outputPosEmpty, bool* duplicate)
  550. {
  551. *outputPosOnPage = -1;
  552. *outputPosEmpty = false;
  553. *duplicate = false;
  554. bool found = false;
  555. loadPage(pageNum);
  556. for(int i = 0; i < BUFFER_SIZE; i++)
  557. {
  558. if(m_readBuffer[i].getKey() == inputKey)
  559. {
  560. *outputPosOnPage = i;
  561. *duplicate = true;
  562. break;
  563. }
  564. if(m_readBuffer[i].getKey() > inputKey)
  565. {
  566. found = true;
  567. *outputPosOnPage = i - 1;
  568. break;
  569. }
  570. else if(m_readBuffer[i].getKey() == 0xFFFFFFFF)
  571. {
  572. *outputPosEmpty = true;
  573. found = true;
  574. *outputPosOnPage = i;
  575. break;
  576. }
  577. }
  578. return found;
  579. }
  580. void addMissingDataPages(char* idxDbFilename)
  581. {
  582. struct stat st;
  583. stat(idxDbFilename, &st);
  584. int pagesExpected = st.st_size/sizeof(CIndex);
  585. int missingPages = pagesExpected - getPagesInFileCnt();
  586. for(int i = 0; i < missingPages; i++)
  587. {
  588. clearWriteBuffer();
  589. writePage();
  590. }
  591. clearWriteBuffer();
  592. }
  593. //Constructor
  594. CDatabase(std::string name)
  595. {
  596. BUFFER_SIZE = DATA_BUFFER_SIZE;
  597. m_writeBuffer = new CRecord[BUFFER_SIZE];
  598. m_readBuffer = new CRecord[BUFFER_SIZE];
  599. //Set name and create apropriate file
  600. setName(name);
  601. //Clear buffer and points
  602. m_lastFileReadPoint = 0;
  603. m_lastFileWritePoint = 0;
  604. m_actualBufferReadPoint = 0;
  605. m_actualBufferWritePoint = 0;
  606. clearReadBuffer();
  607. clearWriteBuffer();
  608. m_readSuccessful = false;
  609. }
  610. };
  611.  
  612. class CDatabaseMgr
  613. {
  614. private:
  615. CDatabase* m_database;
  616. CIndexesDatabase* m_idxDatabase;
  617. bool m_noRecords;
  618. int m_minKey;
  619. CIndex m_tmpIdx;
  620. CRecord m_tmpData;
  621. int m_overflowSize;
  622. public:
  623. void reorganise()
  624. {
  625. Stats.incReorganisations();
  626. m_database->setName("bdb");
  627. m_database->reset();
  628. m_idxDatabase->clearFile();
  629. m_idxDatabase->reset();
  630. m_idxDatabase->addIdxPage();
  631. m_idxDatabase->loadNextPage();
  632. CDatabase tmpDb("adb");
  633. int recordsInDatabase = tmpDb.getElementsCnt();
  634. CRecord tmpRecord, overflowRecord;
  635. CIndex tmpIdx;
  636. bool prevHasOverflow = false;
  637. bool hasOverflow = false;
  638. int prevNextOverflowByte = NULL;
  639. int nextOverflowByte = NULL;
  640. tmpDb.loadNextPage();
  641. int addedRecords = 0;
  642. while(recordsInDatabase != 0)
  643. {
  644. while(addedRecords < RECORDS_PER_PAGE && recordsInDatabase != 0)
  645. {
  646. if(!hasOverflow)
  647. {
  648. tmpRecord.setAll(tmpDb.getNextRecord());
  649. prevHasOverflow = hasOverflow;
  650. hasOverflow = tmpRecord.hasOverflowArea();
  651. prevNextOverflowByte = nextOverflowByte;
  652. nextOverflowByte = tmpRecord.getOverflowPointer();
  653. if(tmpRecord.getKey() == 0xFFFFFFFF)
  654. {
  655. --recordsInDatabase;
  656. if(tmpDb.isReadBufferFull())
  657. tmpDb.loadNextPage();
  658. continue;
  659. }
  660. tmpRecord.setOverflowPointer(0);
  661. m_database->addNextRecord(&tmpRecord);
  662. ++addedRecords;
  663. }
  664. else
  665. {
  666. tmpRecord.setAll(tmpDb.getOverflowRecord(nextOverflowByte));
  667. prevHasOverflow = hasOverflow;
  668. hasOverflow = tmpRecord.hasOverflowArea();
  669. prevNextOverflowByte = nextOverflowByte;
  670. nextOverflowByte = tmpRecord.getOverflowPointer();
  671. tmpRecord.setOverflowPointer(0);
  672. m_database->addNextRecord(&tmpRecord);
  673. ++addedRecords;
  674. }
  675. if(tmpDb.isReadBufferFull())
  676. tmpDb.loadNextPage();
  677. --recordsInDatabase;
  678. }
  679. if(addedRecords > 0)
  680. {
  681. tmpIdx.setAll(m_idxDatabase->getNextRecord());
  682. tmpIdx.setKey(m_database->getWriteBufferPtr()[0].getKey());
  683. m_idxDatabase->addNextRecord(&tmpIdx);
  684. std::cout << m_idxDatabase->getWriteBufferPtr()[m_idxDatabase->getActualBufferWritePoint()-1].getKey() << std::endl;
  685. m_database->saveNextPage();
  686. addedRecords = 0;
  687. if(m_idxDatabase->isWriteBufferFull())
  688. {
  689. m_idxDatabase->saveNextPage();
  690. m_idxDatabase->addIdxPage();
  691. m_idxDatabase->loadNextPage();
  692. }
  693. }
  694. }
  695. m_overflowSize = 0;
  696. m_idxDatabase->saveNextPage();
  697. //CleanUp
  698. remove("adb");
  699. rename("bdb","adb");
  700. m_database->setName("adb");
  701. m_database->resetStats();
  702. }
  703. bool isOverflowSizeExceeded()
  704. {
  705. return m_overflowSize == OVERFLOW_MAX_SIZE;
  706. }
  707. void addOverflowRecord(int masterPage, int masterPos, CRecord* slave)
  708. {
  709. //Czy ma overflow
  710. m_database->loadPage(masterPage);
  711. if(m_database->getReadBufferPtr()[masterPos].hasOverflowArea())
  712. {
  713. int lastLastRecordPointer = NULL;
  714. int lastRecordPointer = m_database->getReadBufferPtr()[masterPos].getOverflowPointer();
  715. //Czy overflow mniejszy ode mnie
  716. m_tmpData.setAll(m_database->getOverflowRecord(m_database->getReadBufferPtr()[masterPos].getOverflowPointer()));
  717. if(m_tmpData.getKey() < slave->getKey())
  718. {
  719. bool added = false;
  720. while(m_tmpData.getKey() < slave->getKey() && !added)
  721. {
  722. if(m_tmpData.hasOverflowArea())
  723. {
  724. //Zapamietaj pointer i wez nastepny
  725. lastLastRecordPointer = lastRecordPointer;
  726. lastRecordPointer = m_tmpData.getOverflowPointer();
  727. m_tmpData.setAll(m_database->getOverflowRecord(lastRecordPointer));
  728. }
  729. else
  730. {
  731. //Append na koncu
  732. int newRecordByte = m_database->addOverflowRecord(slave);
  733. //Dodaj pointer do ostatniego
  734. m_tmpData.setOverflowPointer(newRecordByte);
  735. m_database->modifyOverflowRecord(&m_tmpData,lastRecordPointer);
  736. added = true;
  737. }
  738. }
  739. if(m_tmpData.getKey() >= slave->getKey() && !added)
  740. {
  741. slave->setOverflowPointer(lastRecordPointer);
  742. //Append na koncu
  743. int newRecordByte = m_database->addOverflowRecord(slave);
  744. //Dodaj pointer do wczesniejszego
  745. m_tmpData.setAll(m_database->getOverflowRecord(lastLastRecordPointer));
  746. m_tmpData.setOverflowPointer(newRecordByte);
  747. m_database->modifyOverflowRecord(&m_tmpData,lastLastRecordPointer);
  748. }
  749. }
  750. else
  751. {
  752. slave->setOverflowPointer(lastRecordPointer);
  753. //Append na koncu
  754. int newRecordByte = m_database->addOverflowRecord(slave);
  755. //Dodaj pointer do mastera
  756. m_database->getReadBufferPtr()[masterPos].setOverflowPointer(newRecordByte);
  757. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  758. m_database->savePage(masterPage);
  759. }
  760. }
  761. else
  762. {
  763. //Append na koncu
  764. int newRecordByte = m_database->addOverflowRecord(slave);
  765. //Dodaj pointer do mastera
  766. m_database->getReadBufferPtr()[masterPos].setOverflowPointer(newRecordByte);
  767. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  768. m_database->savePage(masterPage);
  769. }
  770. ++m_overflowSize;
  771. if(isOverflowSizeExceeded())
  772. reorganise();
  773. }
  774. void shiftRecordsInBuffer(int pageNum, int startRecordIdx)
  775. {
  776. m_database->loadPage(pageNum);
  777. for(int i = startRecordIdx; i < DATA_BUFFER_SIZE; i++)
  778. {
  779. if(i+1 < DATA_BUFFER_SIZE)
  780. {
  781. m_database->getReadBufferPtr()[i].setAll(&m_database->getReadBufferPtr()[i+1]);
  782. }
  783. else
  784. {
  785. m_database->getReadBufferPtr()[i-1].setOverflowPointer(0);
  786. if(m_database->getReadBufferPtr()[i].hasOverflowArea())
  787. {
  788. int overflowPtr = m_database->getReadBufferPtr()[i].getOverflowPointer();
  789. m_database->getReadBufferPtr()[i].setAll(m_database->getOverflowRecord(overflowPtr));
  790. m_database->clearOverflowRecord(overflowPtr);
  791. }
  792. else
  793. {
  794. m_database->getReadBufferPtr()[i].reset();
  795. }
  796. }
  797. }
  798. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  799. m_database->savePage(pageNum);
  800. }
  801. void delRecord(int key)
  802. {
  803. if(m_noRecords)
  804. {
  805. std::cout << "ERROR: Database empty!" << std::endl;
  806. }
  807. else
  808. {
  809. //Znajdz strone gdzie moze sie zmiescic
  810. //Czyli znajdz strone wieksza niz on sam
  811. int dataPageNum, dataPosOnPage;
  812. bool dataIsEmpty;
  813. bool duplicateKey;
  814. if(m_idxDatabase->findPageForKey(key,&dataPageNum, &duplicateKey))
  815. {
  816. if(m_database->findMatchingPlaceForKey(key, dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
  817. {
  818. if(dataIsEmpty)
  819. {
  820. std::cout << "ERROR: Record not found!" << std::endl;
  821. }
  822. else
  823. {
  824. m_database->loadPage(dataPageNum);
  825. if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
  826. {
  827. int nextOverflowByte = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
  828. int lastNextOverflowByte = NULL;
  829. CRecord* tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
  830. if(tmpOverflowRecord->getKey() == key)
  831. {
  832. //Znaleziony
  833. if(tmpOverflowRecord->hasOverflowArea())
  834. {
  835. lastNextOverflowByte = nextOverflowByte;
  836. nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
  837. m_database->getReadBufferPtr()[dataPosOnPage].setOverflowPointer(nextOverflowByte);
  838. m_database->clearOverflowRecord(lastNextOverflowByte);
  839. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  840. m_database->savePage(dataPageNum);
  841. std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
  842. }
  843. else
  844. {
  845. m_database->getReadBufferPtr()[dataPosOnPage].setOverflowPointer(0);
  846. m_database->clearOverflowRecord(nextOverflowByte);
  847. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  848. m_database->savePage(dataPageNum);
  849. std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
  850. }
  851. }
  852. else
  853. {
  854. while(tmpOverflowRecord->getKey() != key)
  855. {
  856. if(tmpOverflowRecord->hasOverflowArea())
  857. {
  858. lastNextOverflowByte = nextOverflowByte;
  859. nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
  860. tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
  861. }
  862. else
  863. {
  864. break;
  865. }
  866. }
  867. if(tmpOverflowRecord->getKey() == key)
  868. {
  869. int previous = lastNextOverflowByte;
  870. int me = nextOverflowByte;
  871. int next = tmpOverflowRecord->getOverflowPointer();
  872. tmpOverflowRecord = m_database->getOverflowRecord(previous);
  873. tmpOverflowRecord->setOverflowPointer(next);
  874. m_database->modifyOverflowRecord(tmpOverflowRecord,previous);
  875. m_database->clearOverflowRecord(me);
  876. std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
  877. }
  878. else
  879. {
  880. std::cout << "ERROR: Record not found!" << std::endl;
  881. }
  882. }
  883. }
  884. else
  885. {
  886. std::cout << "ERROR: Record not found!" << std::endl;
  887. }
  888. }
  889. }
  890. else
  891. {
  892. if(duplicateKey)
  893. {
  894. //Znaleziony w srodku
  895. if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
  896. {
  897. //Podmieniamy z jego overflowem
  898. int myOverflowPtr = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
  899. CRecord* tmpOverflowRecord = m_database->getOverflowRecord(m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer());
  900. m_database->getReadBufferPtr()[dataPosOnPage].setAll(tmpOverflowRecord);
  901. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  902. m_database->savePage(dataPageNum);
  903. m_database->clearOverflowRecord(myOverflowPtr);
  904. std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
  905. }
  906. else
  907. {
  908. //Swap
  909. shiftRecordsInBuffer(dataPageNum, dataPosOnPage);
  910. std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
  911. }
  912. }
  913. else
  914. {
  915. std::cout << "ERROR: Record not found!" << std::endl;
  916. }
  917. }
  918. }
  919. else
  920. {
  921. if(duplicateKey)
  922. {
  923. m_database->loadPage(dataPageNum);
  924. if(m_database->getReadBufferPtr()[0].getKey() == key)
  925. {
  926. if(m_database->getReadBufferPtr()[0].hasOverflowArea())
  927. {
  928. //Podmieniamy z jego overflowem
  929. int myOverflowPtr = m_database->getReadBufferPtr()[0].getOverflowPointer();
  930. CRecord* tmpOverflowRecord = m_database->getOverflowRecord(m_database->getReadBufferPtr()[0].getOverflowPointer());
  931. m_database->getReadBufferPtr()[0].setAll(tmpOverflowRecord);
  932. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  933. m_database->savePage(dataPageNum);
  934. m_database->clearOverflowRecord(myOverflowPtr);
  935. std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
  936. }
  937. else
  938. {
  939. shiftRecordsInBuffer(dataPageNum, 0);
  940. std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
  941. }
  942. }
  943. else
  944. {
  945. std::cout << "ERROR: Record not found!" << std::endl;
  946. }
  947. }
  948. else
  949. {
  950. std::cout << "ERROR: Record not found!" << std::endl;
  951. }
  952. }
  953. }
  954. }
  955. void updateRecord(CRecord* record)
  956. {
  957. if(m_noRecords)
  958. {
  959. std::cout << "ERROR: Database empty!" << std::endl;
  960. }
  961. else
  962. {
  963. //Znajdz strone gdzie moze sie zmiescic
  964. //Czyli znajdz strone wieksza niz on sam
  965. int dataPageNum, dataPosOnPage;
  966. bool dataIsEmpty;
  967. bool duplicateKey;
  968. if(m_idxDatabase->findPageForKey(record->getKey(),&dataPageNum, &duplicateKey))
  969. {
  970. if(m_database->findMatchingPlaceForKey(record->getKey(), dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
  971. {
  972. if(dataIsEmpty)
  973. {
  974. std::cout << "ERROR: Record not found!" << std::endl;
  975. }
  976. else
  977. {
  978. m_database->loadPage(dataPageNum);
  979. if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
  980. {
  981. int nextOverflowByte = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
  982. int lastNextOverflowByte = NULL;
  983. CRecord* tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
  984. if(tmpOverflowRecord->getKey() == record->getKey())
  985. {
  986. tmpOverflowRecord->setAll(record);
  987. m_database->modifyOverflowRecord(tmpOverflowRecord, nextOverflowByte);
  988. std::cout << "SUCCESS: Record updated" << std::endl;
  989. }
  990. else
  991. {
  992. while(tmpOverflowRecord->getKey() != record->getKey())
  993. {
  994. if(tmpOverflowRecord->hasOverflowArea())
  995. {
  996. lastNextOverflowByte = nextOverflowByte;
  997. nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
  998. tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
  999. }
  1000. else
  1001. {
  1002. break;
  1003. }
  1004. }
  1005. if(tmpOverflowRecord->getKey() == record->getKey())
  1006. {
  1007. tmpOverflowRecord->setAll(record);
  1008. m_database->modifyOverflowRecord(tmpOverflowRecord, nextOverflowByte);
  1009. std::cout << "SUCCESS: Record updated" << std::endl;
  1010. }
  1011. else
  1012. {
  1013. std::cout << "ERROR: Record not found!" << std::endl;
  1014. }
  1015. }
  1016. }
  1017. else
  1018. {
  1019. std::cout << "ERROR: Record not found!" << std::endl;
  1020. }
  1021. }
  1022. }
  1023. else
  1024. {
  1025. if(duplicateKey)
  1026. {
  1027. //Znaleziony w srodku
  1028. m_database->loadPage(dataPageNum);
  1029. m_database->getReadBufferPtr()[dataPosOnPage].setAll(record);
  1030. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  1031. m_database->savePage(dataPageNum);
  1032. std::cout << "SUCCESS: Record updated!" << std::endl;
  1033. }
  1034. else
  1035. {
  1036. std::cout << "ERROR: Record not found!" << std::endl;
  1037. }
  1038. }
  1039. }
  1040. else
  1041. {
  1042. if(duplicateKey)
  1043. {
  1044. m_database->loadPage(dataPageNum);
  1045. if(m_database->getReadBufferPtr()[0].getKey() == record->getKey())
  1046. {
  1047. m_database->loadPage(dataPageNum);
  1048. m_database->getReadBufferPtr()[0].setAll(record);
  1049. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  1050. m_database->savePage(dataPageNum);
  1051. std::cout << "SUCCESS: Record updated!" << std::endl;
  1052. }
  1053. else
  1054. {
  1055. std::cout << "ERROR: Record not found!" << std::endl;
  1056. }
  1057. }
  1058. else
  1059. {
  1060. std::cout << "ERROR: Record not found!" << std::endl;
  1061. }
  1062. }
  1063. }
  1064. }
  1065. void findRecord(int key)
  1066. {
  1067. if(m_noRecords)
  1068. {
  1069. std::cout << "ERROR: Database empty!" << std::endl;
  1070. }
  1071. else
  1072. {
  1073. //Znajdz strone gdzie moze sie zmiescic
  1074. //Czyli znajdz strone wieksza niz on sam
  1075. int dataPageNum, dataPosOnPage;
  1076. bool dataIsEmpty;
  1077. bool duplicateKey;
  1078. if(m_idxDatabase->findPageForKey(key,&dataPageNum, &duplicateKey))
  1079. {
  1080. if(m_database->findMatchingPlaceForKey(key, dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
  1081. {
  1082. if(dataIsEmpty)
  1083. {
  1084. std::cout << "ERROR: Record not found!" << std::endl;
  1085. }
  1086. else
  1087. {
  1088. m_database->loadPage(dataPageNum);
  1089. if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
  1090. {
  1091. int nextOverflowByte = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
  1092. int lastNextOverflowByte = NULL;
  1093. CRecord* tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
  1094. if(tmpOverflowRecord->getKey() == key)
  1095. {
  1096. std::cout << "SUCCESS: Record found. Key: " << tmpOverflowRecord->getKey() << "; Height: " << tmpOverflowRecord->getDataPtr()->getHeight() << "; Radius: " << tmpOverflowRecord->getDataPtr()->getRadius() << std::endl;
  1097. }
  1098. else
  1099. {
  1100. while(tmpOverflowRecord->getKey() != key)
  1101. {
  1102. if(tmpOverflowRecord->hasOverflowArea())
  1103. {
  1104. lastNextOverflowByte = nextOverflowByte;
  1105. nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
  1106. tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
  1107. }
  1108. else
  1109. {
  1110. break;
  1111. }
  1112. }
  1113. if(tmpOverflowRecord->getKey() == key)
  1114. {
  1115. std::cout << "SUCCESS: Record found. Key: " << tmpOverflowRecord->getKey() << "; Height: " << tmpOverflowRecord->getDataPtr()->getHeight() << "; Radius: " << tmpOverflowRecord->getDataPtr()->getRadius() << std::endl;
  1116. }
  1117. else
  1118. {
  1119. std::cout << "ERROR: Record not found!" << std::endl;
  1120. }
  1121. }
  1122. }
  1123. else
  1124. {
  1125. std::cout << "ERROR: Record not found!" << std::endl;
  1126. }
  1127. }
  1128. }
  1129. else
  1130. {
  1131. if(duplicateKey)
  1132. {
  1133. //Znaleziony w srodku
  1134. std::cout << "SUCCESS: Record found. Key: " << m_database->getReadBufferPtr()[dataPosOnPage].getKey()
  1135. << "; Height: " << m_database->getReadBufferPtr()[dataPosOnPage].getDataPtr()->getHeight()
  1136. << "; Radius: " << m_database->getReadBufferPtr()[dataPosOnPage].getDataPtr()->getRadius() << std::endl;
  1137. }
  1138. else
  1139. {
  1140. std::cout << "ERROR: Record not found!" << std::endl;
  1141. }
  1142. }
  1143. }
  1144. else
  1145. {
  1146. if(duplicateKey)
  1147. {
  1148. m_database->loadPage(dataPageNum);
  1149. if(m_database->getReadBufferPtr()[0].getKey() == key)
  1150. {
  1151. std::cout << "SUCCESS: Record found. Key: " << m_database->getReadBufferPtr()[0].getKey()
  1152. << "; Height: " << m_database->getReadBufferPtr()[0].getDataPtr()->getHeight()
  1153. << "; Radius: " << m_database->getReadBufferPtr()[0].getDataPtr()->getRadius() << std::endl;
  1154. }
  1155. else
  1156. {
  1157. std::cout << "ERROR: Record not found!" << std::endl;
  1158. }
  1159. }
  1160. else
  1161. {
  1162. std::cout << "ERROR: Record not found!" << std::endl;
  1163. }
  1164. }
  1165. }
  1166. }
  1167. void addRecord(CRecord* record)
  1168. {
  1169. if(m_noRecords)
  1170. {
  1171. //Dodaj strone z indeksami w bazie
  1172. m_idxDatabase->addIdxPage();
  1173. m_database->addMissingDataPages(m_idxDatabase->getFilename());
  1174. //Dodaj klucz do bazy indeksow
  1175. m_idxDatabase->loadPage(0);
  1176. m_tmpIdx.reset();
  1177. m_tmpIdx.setKey(record->getKey());
  1178. m_tmpIdx.setPageNumber(m_idxDatabase->getNextRecord()->getPageNumber());
  1179. m_idxDatabase->copyWriteBuffer(m_idxDatabase->getReadBufferPtr());
  1180. m_idxDatabase->clearActualBufferWritePoint();
  1181. m_idxDatabase->addNextRecord(&m_tmpIdx);
  1182. m_idxDatabase->writePage(0);
  1183. //Dodaj klucz do pierwszej strony bazy
  1184. m_database->clearWriteBuffer();
  1185. m_database->addNextRecord(record);
  1186. m_database->savePage(m_tmpIdx.getPageNumber());
  1187. m_noRecords = false;
  1188. }
  1189. else
  1190. {
  1191. //Sprawdz czy klucz jest mniejszy niz najmniejszy
  1192. if(m_minKey > record->getKey())
  1193. {
  1194. std::cout << "ERROR: Key value is lower than the lowest! Record cannot be added!" << std::endl;
  1195. }
  1196. else
  1197. {
  1198. //Znajdz strone gdzie moze sie zmiescic
  1199. //Czyli znajdz strone wieksza niz on sam
  1200. int dataPageNum, dataPosOnPage;
  1201. bool dataIsEmpty;
  1202. bool duplicateKey;
  1203. if(m_idxDatabase->findPageForKey(record->getKey(),&dataPageNum, &duplicateKey))
  1204. {
  1205. if(m_database->findMatchingPlaceForKey(record->getKey(), dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
  1206. {
  1207. if(dataPosOnPage == -1)
  1208. {
  1209. std::cout << "WARNING: Operation cannot be executed without reorganising the file! Reorganise file and try again!" << std::endl;
  1210. return;
  1211. }
  1212. else if(dataIsEmpty)
  1213. {
  1214. m_database->loadPage(dataPageNum);
  1215. m_database->getReadBufferPtr()[dataPosOnPage].setAll(record);
  1216. m_database->copyWriteBuffer(m_database->getReadBufferPtr());
  1217. m_database->savePage(dataPageNum);
  1218. }
  1219. else
  1220. {
  1221. //Dodaj do overflowa znalezionego
  1222. addOverflowRecord(dataPageNum, dataPosOnPage, record);
  1223. }
  1224. }
  1225. else
  1226. {
  1227. if(duplicateKey)
  1228. {
  1229. std::cout << "ERROR: Key already in database!" << std::endl;
  1230. }
  1231. //Dodaj do overflowa ostatniego
  1232. addOverflowRecord(dataPageNum, DATA_BUFFER_SIZE-1, record);
  1233. }
  1234. }
  1235. else
  1236. {
  1237. if(duplicateKey)
  1238. {
  1239. m_database->loadPage(dataPageNum);
  1240. if(m_database->getReadBufferPtr()[0].getKey() > record->getKey())
  1241. {
  1242. std::cout << "WARNING: Operation cannot be executed without reorganising the file! Reorganise file and try again!" << std::endl;
  1243. }
  1244. else
  1245. {
  1246. std::cout << "ERROR: Key already in database!" << std::endl;
  1247. }
  1248. return;
  1249. }
  1250. //TBD
  1251. }
  1252. }
  1253. }
  1254. m_minKey = m_minKey < record->getKey() ? m_minKey : record->getKey();
  1255. }
  1256. int getOverflowSize()
  1257. {
  1258. int idxPages = m_idxDatabase->getPagesInFileCnt();
  1259. int dataRecords = m_database->getElementsCnt();
  1260. return (idxPages * INDEX_BUFFER_SIZE) - dataRecords;
  1261. }
  1262. void printSorted()
  1263. {
  1264. Stats.freeze();
  1265. std::fstream idxLog;
  1266. std::fstream dataLog;
  1267. std::fstream overflowLog;
  1268. idxLog.open("indexFileLogS.txt",std::ios::out);
  1269. dataLog.open("dataFileLogS.txt",std::ios::out);
  1270. int idxDbSize = m_idxDatabase->getElementsCnt();
  1271. int dbSize = m_database->getElementsCnt() - m_overflowSize;
  1272. int overflowStartByte = dbSize * sizeof(CRecord);
  1273. CRecord overflowRecord;
  1274. for(int i = 0; i < idxDbSize/INDEX_BUFFER_SIZE; i++)
  1275. {
  1276. m_idxDatabase->loadPage(i);
  1277. idxLog << "Indexes page #" << i << std::endl;
  1278. for(int j = 0; j < INDEX_BUFFER_SIZE; j++)
  1279. {
  1280. if(m_idxDatabase->getReadBufferPtr()[j].getKey() != 0xFFFFFFFF)
  1281. idxLog << "#" << j << ": " << m_idxDatabase->getReadBufferPtr()[j].toString() << std::endl;
  1282. }
  1283. }
  1284. for(int i = 0; i < dbSize/DATA_BUFFER_SIZE; i++)
  1285. {
  1286. m_database->loadPage(i);
  1287. dataLog << "Data page #" << i << std::endl;
  1288. int j = 0;
  1289. bool hasOverflowArea = false;
  1290. int overflowByte = true;
  1291. CRecord* tmpRecord;
  1292. while(j < DATA_BUFFER_SIZE)
  1293. {
  1294. if(!hasOverflowArea)
  1295. {
  1296. hasOverflowArea = m_database->getReadBufferPtr()[j].hasOverflowArea();
  1297. overflowByte = m_database->getReadBufferPtr()[j].getOverflowPointer();
  1298. if(m_database->getReadBufferPtr()[j].getKey() != 0xFFFFFFFF)
  1299. dataLog << "#" << j << ": " << m_database->getReadBufferPtr()[j].toString() << std::endl;
  1300. j++;
  1301. }
  1302. else
  1303. {
  1304. tmpRecord = m_database->getOverflowRecord(overflowByte);
  1305. hasOverflowArea = tmpRecord->hasOverflowArea();
  1306. overflowByte = tmpRecord->getOverflowPointer();
  1307. dataLog << "OverflowRecord: " << m_database->getReadBufferPtr()[j].toString() << std::endl;
  1308. }
  1309. }
  1310. }
  1311. Stats.unfreeze();
  1312. }
  1313. void printAsIs()
  1314. {
  1315. Stats.freeze();
  1316. std::fstream idxLog;
  1317. std::fstream dataLog;
  1318. std::fstream overflowLog;
  1319. idxLog.open("indexFileLogA.txt",std::ios::out);
  1320. dataLog.open("dataFileLogA.txt",std::ios::out);
  1321. overflowLog.open("overflowFileLogA.txt",std::ios::out);
  1322. int idxDbSize = m_idxDatabase->getElementsCnt();
  1323. int dbSize = m_database->getElementsCnt() - m_overflowSize;
  1324. int overflowStartByte = dbSize * sizeof(CRecord);
  1325. CRecord overflowRecord;
  1326. for(int i = 0; i < idxDbSize/INDEX_BUFFER_SIZE; i++)
  1327. {
  1328. m_idxDatabase->loadPage(i);
  1329. idxLog << "Indexes page #" << i << std::endl;
  1330. for(int j = 0; j < INDEX_BUFFER_SIZE; j++)
  1331. {
  1332. idxLog << "#" << j << ": " << m_idxDatabase->getReadBufferPtr()[j].toString() << std::endl;
  1333. }
  1334. }
  1335. for(int i = 0; i < dbSize/DATA_BUFFER_SIZE; i++)
  1336. {
  1337. m_database->loadPage(i);
  1338. dataLog << "Data page #" << i << std::endl;
  1339. for(int j = 0; j < DATA_BUFFER_SIZE; j++)
  1340. {
  1341. dataLog << "#" << j << ": " << m_database->getReadBufferPtr()[j].toString() << std::endl;
  1342. }
  1343. }
  1344. for(int i = 0; i < m_overflowSize; i++)
  1345. {
  1346. overflowRecord.setAll(m_database->getOverflowRecord(overflowStartByte+(i*sizeof(CRecord))));
  1347. overflowLog << "#" << i << ": " << overflowRecord.toString() << std::endl;
  1348. }
  1349. Stats.unfreeze();
  1350. }
  1351. CDatabaseMgr(CDatabase* db, CIndexesDatabase* idxDb)
  1352. {
  1353. m_database = db;
  1354. m_idxDatabase = idxDb;
  1355. m_overflowSize = getOverflowSize();
  1356. struct stat st;
  1357. stat(m_idxDatabase->getFilename(), &st);
  1358. m_noRecords = (st.st_size <= 0);
  1359. if(m_noRecords)
  1360. m_minKey = 0x7FFFFFFF;
  1361. else
  1362. {
  1363. m_idxDatabase->readPage();
  1364. m_tmpIdx.setAll(m_idxDatabase->getNextRecord());
  1365. m_minKey = m_tmpIdx.getKey();
  1366. }
  1367. }
  1368. };
  1369. int main()
  1370. {
  1371. int inputSource = -1;
  1372. EOperationType inputType;
  1373. int argCounter = 0;
  1374. std::string inputText = "";
  1375. char inputTextCstr[256];
  1376. std::string command = "";
  1377. int lastSpace = 0;
  1378. int lastLastSpace = 0;
  1379. CRecord inputRecord;
  1380. CIndexesDatabase idxDb("aidxdb");
  1381. CDatabase db("adb");
  1382. CDatabaseMgr dbMgr(&db, &idxDb);
  1383. std::fstream inputFile;
  1384. do
  1385. {
  1386. std::cout << "Wybierz zrodlo danych wejsciowych: " << std::endl
  1387. << "1 - Dane z pliku zewnetrznego" << std::endl
  1388. << "2 - Wpisywanie danych z klawiatury" << std::endl
  1389. << "3 - Pseudolosowy generator rekordow" << std::endl
  1390. << "4 - WYJSCIE Z PROGRAMU" << std::endl;
  1391. std::cin >> inputSource;
  1392.  
  1393. if (inputSource == 1)
  1394. {
  1395. std::string inputFileName;
  1396. std::cout << "Specify input file name: ";
  1397. std::cin >> inputFileName;
  1398. inputFile.open(inputFileName,std::ios::in);
  1399. do
  1400. {
  1401. inputFile.getline(inputTextCstr,256);
  1402. inputText = inputTextCstr;
  1403. if(inputText == "" || inputText == "end") continue;
  1404. else inputText += " x";
  1405. lastLastSpace = lastSpace;
  1406. lastSpace = inputText.find(" ", lastSpace);
  1407. command = inputText.substr(lastLastSpace, lastSpace);
  1408. if(command == "add")
  1409. {
  1410. inputType = ADD_RECORD;
  1411. }
  1412. else if(command == "rem")
  1413. {
  1414. inputType = REM_RECORD;
  1415. }
  1416. else if(command == "find" || command == "seek")
  1417. {
  1418. inputType = FIND_RECORD;
  1419. }
  1420. else if(command == "reorganise")
  1421. {
  1422. inputType = REORGANIZE_DATABASE;
  1423. std::cout << "Reorganising" << std::endl;
  1424. dbMgr.reorganise();
  1425. continue;
  1426. }
  1427. else if(command == "edit" || command == "modify")
  1428. {
  1429. inputType = MODIFY_RECORD;
  1430. }
  1431. lastLastSpace = lastSpace;
  1432. lastSpace = inputText.find(" ", lastSpace+1);
  1433. int key = -1;
  1434. while(lastSpace != lastLastSpace && lastSpace != -1)
  1435. {
  1436. command = inputText.substr(lastLastSpace+1, lastSpace-lastLastSpace-1);
  1437. lastLastSpace = lastSpace;
  1438. lastSpace = inputText.find(" ", lastSpace+1);
  1439. if(inputType == ADD_RECORD)
  1440. {
  1441. if(argCounter == 0)
  1442. {
  1443. inputRecord.setKey(atoi(command.c_str()));
  1444. }
  1445. else if(argCounter == 1)
  1446. {
  1447. inputRecord.getDataPtr()->setHeight(atoi(command.c_str()));
  1448. }
  1449. else if(argCounter == 2)
  1450. {
  1451. inputRecord.getDataPtr()->setRadius(atoi(command.c_str()));
  1452. }
  1453. }
  1454. else if(inputType == REM_RECORD)
  1455. {
  1456. if(argCounter == 0)
  1457. {
  1458. key = atoi(command.c_str());
  1459. }
  1460. }
  1461. ++argCounter;
  1462. }
  1463. command = inputText.substr(lastLastSpace+1, inputText.size()-lastLastSpace-1);
  1464. lastLastSpace = lastSpace = 0;
  1465. if(inputType == ADD_RECORD)
  1466. {
  1467. dbMgr.addRecord(&inputRecord);
  1468. }
  1469. else if(inputType == REM_RECORD)
  1470. {
  1471. dbMgr.delRecord(key);
  1472. }
  1473. key = -1;
  1474. argCounter = 0;
  1475. inputRecord.reset();
  1476. for(int i = 0; i < 256; i++)
  1477. inputTextCstr[i] = 0;
  1478. } while(inputText != "end");
  1479. inputFile.close();
  1480. inputSource = 0;
  1481. }
  1482. else if (inputSource == 2)
  1483. {
  1484. do
  1485. {
  1486. std::cin.getline(inputTextCstr,256);
  1487. inputText = inputTextCstr;
  1488. if(inputText == "" || inputText == "end") continue;
  1489. else inputText += " x";
  1490. lastLastSpace = lastSpace;
  1491. lastSpace = inputText.find(" ", lastSpace);
  1492. command = inputText.substr(lastLastSpace, lastSpace);
  1493. if(command == "add")
  1494. {
  1495. inputType = ADD_RECORD;
  1496. }
  1497. else if(command == "rem")
  1498. {
  1499. inputType = REM_RECORD;
  1500. }
  1501. else if(command == "find" || command == "seek")
  1502. {
  1503. inputType = FIND_RECORD;
  1504. }
  1505. else if(command == "reorganise")
  1506. {
  1507. inputType = REORGANIZE_DATABASE;
  1508. std::cout << "Reorganising" << std::endl;
  1509. dbMgr.reorganise();
  1510. continue;
  1511. }
  1512. else if(command == "print")
  1513. {
  1514. dbMgr.printSorted();
  1515. std::cout << "Check log files" << std::endl;
  1516. continue;
  1517. }
  1518. else if(command == "print_as")
  1519. {
  1520. dbMgr.printAsIs();
  1521. std::cout << "Check log files" << std::endl;
  1522. continue;
  1523. }
  1524. else if(command == "edit" || command == "modify")
  1525. {
  1526. inputType = MODIFY_RECORD;
  1527. }
  1528. lastLastSpace = lastSpace;
  1529. lastSpace = inputText.find(" ", lastSpace+1);
  1530. int key = -1;
  1531. while(lastSpace != lastLastSpace && lastSpace != -1)
  1532. {
  1533. command = inputText.substr(lastLastSpace+1, lastSpace-lastLastSpace-1);
  1534. lastLastSpace = lastSpace;
  1535. lastSpace = inputText.find(" ", lastSpace+1);
  1536. if(inputType == ADD_RECORD || inputType == MODIFY_RECORD)
  1537. {
  1538. if(argCounter == 0)
  1539. {
  1540. inputRecord.setKey(atoi(command.c_str()));
  1541. }
  1542. else if(argCounter == 1)
  1543. {
  1544. inputRecord.getDataPtr()->setHeight(atoi(command.c_str()));
  1545. }
  1546. else if(argCounter == 2)
  1547. {
  1548. inputRecord.getDataPtr()->setRadius(atoi(command.c_str()));
  1549. }
  1550. }
  1551. else if(inputType == REM_RECORD || inputType == FIND_RECORD)
  1552. {
  1553. if(argCounter == 0)
  1554. {
  1555. key = atoi(command.c_str());
  1556. }
  1557. }
  1558. ++argCounter;
  1559. }
  1560. command = inputText.substr(lastLastSpace+1, inputText.size()-lastLastSpace-1);
  1561. lastLastSpace = lastSpace = 0;
  1562. if(inputType == ADD_RECORD)
  1563. {
  1564. if(inputRecord.getKey() < 0)
  1565. std::cout << "ERROR: Key cannot be negative" << std::endl;
  1566. else
  1567. dbMgr.addRecord(&inputRecord);
  1568. }
  1569. else if(inputType == REM_RECORD)
  1570. {
  1571. dbMgr.delRecord(key);
  1572. }
  1573. else if(inputType == FIND_RECORD)
  1574. {
  1575. dbMgr.findRecord(key);
  1576. }
  1577. else if(inputType == MODIFY_RECORD)
  1578. {
  1579. dbMgr.updateRecord(&inputRecord);
  1580. }
  1581. key = -1;
  1582. argCounter = 0;
  1583. inputRecord.reset();
  1584. for(int i = 0; i < 256; i++)
  1585. inputTextCstr[i] = 0;
  1586. } while(inputText != "end");
  1587. inputSource = 0;
  1588. }
  1589. else if(inputSource == 3)
  1590. {
  1591. std::string outputFileName;
  1592. std::cout << "Specify output file name: ";
  1593. std::cin >> outputFileName;
  1594. inputFile.open(outputFileName, std::ios::out);
  1595. int keyMin = 0;
  1596. int keyMax = 0;
  1597. std::cout << "Specify min keyValue: ";
  1598. std::cin >> keyMin;
  1599. std::cout << "Specify max keyValue: ";
  1600. std::cin >> keyMax;
  1601. int records = 0;
  1602. std::cout << "Specify records count: ";
  1603. std::cin >> records;
  1604. srand(time(NULL));
  1605. inputFile << "add " << keyMin << " " << 1+rand()%50 << " " << 1+rand()%50 << " x" << std::endl;
  1606. records--;
  1607. for(int i = 0; i < records; i++)
  1608. {
  1609. inputFile << "add " << keyMin+rand()%(keyMax-keyMin) << " " << 1+rand()%50 << " " << 1+rand()%50 << " x" << std::endl;
  1610. }
  1611. inputFile << "end" << std::endl;
  1612. std::cout << "File generated successfully" << std::endl;
  1613. inputFile.close();
  1614. }
  1615. } while (inputSource < 1 || inputSource > 4);
  1616. Stats.print();
  1617. system("pause");
  1618. return 0;
  1619. }
Advertisement
Add Comment
Please, Sign In to add comment