Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <sys/stat.h>
- #include <fstream>
- #include <ctime>
- const double PI = 3.14159265359;
- const int DATA_BUFFER_SIZE = 400;
- const int INDEX_BUFFER_SIZE = 20;
- const int OVERFLOW_MAX_SIZE = 800;
- const double ALPHA = 0.6;
- int RECORDS_PER_PAGE = DATA_BUFFER_SIZE * ALPHA;
- class CStats
- {
- public:
- int m_discReads;
- int m_discWrites;
- int m_reorganisations;
- bool m_freeze;
- void incReorganisations()
- {
- if(!m_freeze)
- m_reorganisations++;
- }
- void incDiscReads()
- {
- if(!m_freeze)
- m_discReads++;
- }
- void incDiscWrites()
- {
- if(!m_freeze)
- m_discWrites++;
- }
- void freeze()
- {
- m_freeze = true;
- }
- void unfreeze()
- {
- m_freeze = false;
- }
- void print()
- {
- std::cout << "Writes: " << m_discWrites << " reads: " << m_discReads << " reorgs: " << m_reorganisations << std::endl;
- }
- CStats()
- {
- m_discReads = 0;
- m_discWrites = 0;
- m_reorganisations = 0;
- m_freeze = false;
- }
- } Stats;
- enum EOperationType
- {
- ADD_RECORD,
- REM_RECORD,
- FIND_RECORD,
- MODIFY_RECORD,
- REORGANIZE_DATABASE,
- PRINT_SORTED,
- PRINT_AS_IS
- };
- //Record class
- class CCone
- {
- private:
- int m_radius;
- int m_height;
- public:
- //Getters
- inline int getRadius(){ return m_radius; }
- inline int getHeight(){ return m_height; }
- inline double getVolume(){
- double dRadius2 = (double)m_radius;
- double dPI = (double)PI;
- double dHeight = (double)m_height;
- double dThird = (double)1;
- dThird /= (double)3;
- dRadius2 *= dRadius2;
- return dThird*dPI*dRadius2*dHeight;
- }
- //Setters
- inline void setRadius(int radius) { m_radius = radius; }
- inline void setHeight(int height) { m_height = height; }
- //Others
- void reset()
- {
- m_radius = 0;
- m_height = 0;
- }
- //Constructors
- CCone()
- {
- m_radius = 0;
- m_height = 0;
- }
- CCone(int radius, int height)
- {
- m_radius = radius;
- m_height = height;
- }
- };
- class CRecord
- {
- private:
- int m_key;
- CCone m_data;
- unsigned int m_overflowPointer;
- public:
- inline int getKey() { return m_key; }
- inline CCone* getDataPtr() { return &m_data; }
- inline CCone getData() { return m_data; }
- inline int getOverflowPointer() { return m_overflowPointer; }
- inline bool hasOverflowArea() { return m_overflowPointer != NULL; }
- void setData(int height, int radius)
- {
- m_data.setHeight(height);
- m_data.setRadius(radius);
- }
- inline void setKey(int key) { m_key = key; }
- inline void setOverflowPointer(int ovfPtr) { m_overflowPointer = ovfPtr; }
- std::string toString()
- {
- char ret[512];
- for(int i = 0; i < 512; i++)
- ret[i] = 0;
- if(m_key == 0xFFFFFFFF)
- {
- return "RECORD EMPTY";
- }
- else
- {
- sprintf(ret, "(Key: %d; Data: (H: %d; R: %d); overflowPtr: %d)", m_key, m_data.getHeight(), m_data.getRadius(), m_overflowPointer);
- }
- std::string retVal(ret);
- return retVal;
- }
- void setAll(CRecord* input)
- {
- m_key = input->getKey();
- m_data.setRadius(input->getData().getRadius());
- m_data.setHeight(input->getData().getHeight());
- m_overflowPointer = input->getOverflowPointer();
- }
- void reset()
- {
- m_key = 0xFFFFFFFF;
- m_data.reset();
- m_overflowPointer = 0;
- }
- CRecord()
- {
- m_key = 0xFFFFFFFF;
- m_overflowPointer = NULL;
- }
- CRecord(int key, int radius, int height)
- {
- m_key = key;
- m_data.setHeight(height);
- m_data.setRadius(radius);
- m_overflowPointer = NULL;
- }
- };
- class CIndex
- {
- private:
- int m_key;
- int m_pageNumber;
- public:
- inline int getKey() { return m_key; }
- inline int getPageNumber() { return m_pageNumber; }
- inline int getPageByte() { return m_pageNumber*sizeof(CCone); }
- inline void setPageNumber(int pageNumber) { m_pageNumber = pageNumber; }
- inline void setKey(int key) { m_key = key; }
- std::string toString()
- {
- char ret[512];
- for(int i = 0; i < 512; i++)
- ret[i] = 0;
- if(m_key == 0xFFFFFFFF)
- {
- return "INDEX EMPTY";
- }
- else
- {
- sprintf(ret, "(Key: %d; PageNumber: %d)", m_key, m_pageNumber);
- }
- std::string retVal(ret);
- return retVal;
- }
- void setAll(CIndex* idx)
- {
- m_key = idx->getKey();
- m_pageNumber = idx->getPageNumber();
- }
- void reset()
- {
- m_key = 0xFFFFFFFF;
- m_pageNumber = 0xFFFFFFFF;
- }
- CIndex()
- {
- m_key = 0xFFFFFFFF;
- m_pageNumber = 0xFFFFFFFF;
- }
- CIndex(int key)
- {
- m_key = key;
- m_pageNumber = 0xFFFFFFFF;
- }
- CIndex(int key, int pageNumber)
- {
- m_key = key;
- m_pageNumber = pageNumber;
- }
- };
- template <typename T>
- class CBase
- {
- protected:
- int BUFFER_SIZE;
- //File preferences
- FILE *m_saveFilePtr;
- std::string m_name;
- char m_filename[10];
- //IO Points
- int m_lastFileReadPoint;
- int m_lastFileWritePoint;
- int m_actualBufferReadPoint;
- int m_actualBufferWritePoint;
- bool m_readSuccessful;
- T* m_readBuffer;
- T* m_writeBuffer;
- public:
- int getPagesInFileCnt()
- {
- struct stat st;
- stat(m_filename, &st);
- int pagesInDataFile = st.st_size/(BUFFER_SIZE*sizeof(T));
- return pagesInDataFile;
- }
- int getElementsCnt()
- {
- struct stat st;
- stat(m_filename, &st);
- int retval = st.st_size/sizeof(T);
- return retval;
- }
- inline T* getReadBufferPtr() { return m_readBuffer; }
- inline T* getWriteBufferPtr() { return m_writeBuffer; }
- //Adders
- inline void addNextRecord(T* input) { m_writeBuffer[m_actualBufferWritePoint++].setAll(input); }
- inline T* getNextRecord() { return &m_readBuffer[m_actualBufferReadPoint++]; }
- inline T* getActualRecord() { return &m_readBuffer[m_actualBufferReadPoint]; }
- inline T* getPreviousRecord() { return &m_readBuffer[m_actualBufferReadPoint-1]; }
- //Getters
- inline int getLastFileReadPoint() { return m_lastFileReadPoint; }
- inline int getLastFileWritePoint() { return m_lastFileWritePoint; }
- inline int getActualBufferReadPoint() { return m_actualBufferReadPoint; }
- inline int getActualBufferWritePoint() { return m_actualBufferWritePoint; }
- inline std::string getName() { return m_name; }
- inline std::string getFilename() { return (std::string)m_filename; }
- inline bool isReadSuccessful() { return m_readSuccessful; }
- inline bool isReadBufferFull() { return m_actualBufferReadPoint == BUFFER_SIZE; }
- inline bool isWriteBufferFull() { return m_actualBufferWritePoint == BUFFER_SIZE; }
- inline bool isReadBufferEmpty() { return m_actualBufferReadPoint == 0; }
- inline bool isWriteBufferEmpty() { return m_actualBufferWritePoint == 0; }
- //Setters
- inline void setLastFileReadPoint(int point) { m_lastFileReadPoint = point; }
- inline void setLastFileWritePoint(int point) { m_lastFileWritePoint = point; }
- inline void setActualBufferReadPoint(int point) { m_actualBufferReadPoint = point; }
- inline void setActualBufferWritePoint(int point) { m_actualBufferWritePoint = point; }
- inline void clearActualBufferReadPoint() { m_actualBufferReadPoint = 0; }
- inline void clearActualBufferWritePoint() { m_actualBufferWritePoint = 0; }
- inline void incActualBufferReadPoint() { m_actualBufferReadPoint++; }
- inline void incActualBufferWritePoint() { m_actualBufferWritePoint++; }
- void clearFile()
- {
- m_saveFilePtr = fopen(m_filename, "wb");
- fclose(m_saveFilePtr);
- }
- void setName(std::string name)
- {
- m_name = name;
- strcpy(m_filename,name.c_str());
- m_filename[5] = '.';
- m_filename[6] = 'b';
- m_filename[7] = 'i';
- m_filename[8] = 'n';
- m_filename[9] = '\0';
- struct stat st;
- stat(m_filename, &st);
- if(st.st_size < 0)
- {
- m_saveFilePtr = fopen(m_filename, "wb");
- fclose(m_saveFilePtr);
- }
- }
- //Other
- int getEOF()
- {
- int retVal;
- m_saveFilePtr = fopen(m_filename, "rb");
- fseek(m_saveFilePtr, 0, SEEK_END);
- retVal = ftell(m_saveFilePtr);
- fclose(m_saveFilePtr);
- return retVal;
- }
- inline T* getLastWriteBufferRecord() { return &m_writeBuffer[m_actualBufferWritePoint]; }
- inline T* getLastReadBufferRecord() { return &m_readBuffer[m_actualBufferReadPoint]; }
- void readPage(int pageNum)
- {
- m_saveFilePtr = fopen(m_filename, "rb");
- fseek(m_saveFilePtr, pageNum*BUFFER_SIZE*sizeof(T), SEEK_SET);
- m_readSuccessful = fread(m_readBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
- m_lastFileReadPoint = ftell(m_saveFilePtr);
- fclose(m_saveFilePtr);
- Stats.incDiscReads();
- }
- void writePage(int pageNum)
- {
- m_saveFilePtr = fopen(m_filename, "r+b");
- fseek(m_saveFilePtr, pageNum*BUFFER_SIZE*sizeof(T), SEEK_SET);
- fwrite(m_writeBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
- m_lastFileWritePoint = ftell(m_saveFilePtr);
- fclose(m_saveFilePtr);
- Stats.incDiscWrites();
- }
- void readPage()
- {
- m_saveFilePtr = fopen(m_filename, "rb");
- fseek(m_saveFilePtr, m_lastFileReadPoint, SEEK_SET);
- m_readSuccessful = fread(m_readBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
- m_lastFileReadPoint = ftell(m_saveFilePtr);
- fclose(m_saveFilePtr);
- Stats.incDiscReads();
- }
- void writePage()
- {
- m_saveFilePtr = fopen(m_filename, "r+b");
- fseek(m_saveFilePtr, m_lastFileWritePoint, SEEK_SET);
- fwrite(m_writeBuffer, sizeof(T), BUFFER_SIZE, m_saveFilePtr);
- m_lastFileWritePoint = ftell(m_saveFilePtr);
- fclose(m_saveFilePtr);
- Stats.incDiscWrites();
- }
- void clearReadBuffer()
- {
- for(int i = 0; i < BUFFER_SIZE; i++)
- {
- m_readBuffer[i].reset();
- }
- }
- void clearWriteBuffer()
- {
- for(int i = 0; i < BUFFER_SIZE; i++)
- {
- m_writeBuffer[i].reset();
- }
- }
- void loadPage(int pageNum)
- {
- m_actualBufferReadPoint = 0;
- clearReadBuffer();
- readPage(pageNum);
- }
- void savePage(int pageNum)
- {
- writePage(pageNum);
- m_actualBufferWritePoint = 0;
- clearWriteBuffer();
- }
- void loadNextPage()
- {
- m_actualBufferReadPoint = 0;
- clearReadBuffer();
- readPage();
- }
- void saveNextPage()
- {
- writePage();
- m_actualBufferWritePoint = 0;
- clearWriteBuffer();
- }
- void copyReadBuffer(T* inputBuffer)
- {
- for(int i = 0; i < BUFFER_SIZE; i++)
- {
- m_readBuffer[i].setAll(&inputBuffer[i]);
- }
- }
- void copyWriteBuffer(T* inputBuffer)
- {
- for(int i = 0; i < BUFFER_SIZE; i++)
- {
- m_writeBuffer[i].setAll(&inputBuffer[i]);
- }
- }
- void resetStats()
- {
- m_lastFileReadPoint = 0;
- m_lastFileWritePoint = 0;
- m_actualBufferReadPoint = 0;
- m_actualBufferWritePoint = 0;
- clearReadBuffer();
- clearWriteBuffer();
- m_readSuccessful = false;
- }
- void reset()
- {
- m_lastFileReadPoint = 0;
- m_lastFileWritePoint = 0;
- m_actualBufferReadPoint = 0;
- m_actualBufferWritePoint = 0;
- clearReadBuffer();
- clearWriteBuffer();
- m_readSuccessful = false;
- m_saveFilePtr = fopen(m_filename, "wb");
- fclose(m_saveFilePtr);
- }
- };
- class CIndexesDatabase: public CBase<CIndex>
- {
- public:
- inline char* getFilename() { return m_filename; }
- bool findPageForKey(int inputKey, int* outputPageNum, bool* duplicate)
- {
- *outputPageNum = -1;
- *duplicate = false;
- int pagesInFile = getPagesInFileCnt();
- bool found = false;
- for(int i = 0; i < pagesInFile && !found && !(*duplicate); i++)
- {
- loadPage(i);
- for(int j = 0; j < BUFFER_SIZE; j++)
- {
- if(i == 0 && j == 0)
- continue;
- if(m_readBuffer[j].getKey() == inputKey)
- {
- *outputPageNum = m_readBuffer[j].getPageNumber();
- *duplicate = true;
- break;
- }
- if(m_readBuffer[j].getKey() > inputKey || m_readBuffer[j].getKey() == 0xFFFFFFFF)
- {
- found = true;
- if(j == 0) //Last good record was on previous page
- {
- loadPage(i-1);
- *outputPageNum = m_readBuffer[BUFFER_SIZE-1].getPageNumber();
- }
- else
- {
- *outputPageNum = m_readBuffer[j-1].getPageNumber();
- }
- break;
- }
- }
- }
- return found;
- }
- void addIdxPage()
- {
- int lastWritePoint = m_lastFileWritePoint;
- m_lastFileWritePoint = getEOF();
- int pagesInFile = getPagesInFileCnt();
- clearWriteBuffer();
- for(int i = 0; i < INDEX_BUFFER_SIZE; i++)
- {
- m_writeBuffer[i].setPageNumber(pagesInFile*INDEX_BUFFER_SIZE+i);
- }
- writePage();
- clearWriteBuffer();
- m_lastFileWritePoint = lastWritePoint;
- }
- //Constructor
- CIndexesDatabase(std::string name)
- {
- BUFFER_SIZE = INDEX_BUFFER_SIZE;
- m_writeBuffer = new CIndex[BUFFER_SIZE];
- m_readBuffer = new CIndex[BUFFER_SIZE];
- setName(name);
- //Clear buffer and points
- m_lastFileReadPoint = 0;
- m_lastFileWritePoint = 0;
- m_actualBufferReadPoint = 0;
- m_actualBufferWritePoint = 0;
- clearReadBuffer();
- clearWriteBuffer();
- m_readSuccessful = false;
- }
- };
- class CDatabase: public CBase<CRecord>
- {
- private:
- CRecord m_tmpOverflowRecord;
- public:
- int addOverflowRecord(CRecord* input)
- {
- struct stat st;
- stat(m_filename, &st);
- int newRecordByte;
- m_saveFilePtr = fopen(m_filename, "r+b");
- fseek(m_saveFilePtr, st.st_size, SEEK_SET);
- fwrite(input, sizeof(CRecord), 1, m_saveFilePtr);
- newRecordByte = ftell(m_saveFilePtr) - sizeof(CRecord);
- fclose(m_saveFilePtr);
- Stats.incDiscWrites();
- return newRecordByte;
- }
- void modifyOverflowRecord(CRecord* input, int byte)
- {
- m_saveFilePtr = fopen(m_filename, "r+b");
- fseek(m_saveFilePtr, byte, SEEK_SET);
- fwrite(input, sizeof(CRecord), 1, m_saveFilePtr);
- fclose(m_saveFilePtr);
- Stats.incDiscWrites();
- }
- void clearOverflowRecord(int byte)
- {
- CRecord empty;
- m_saveFilePtr = fopen(m_filename, "r+b");
- fseek(m_saveFilePtr, byte, SEEK_SET);
- fwrite(&empty, sizeof(CRecord), 1, m_saveFilePtr);
- fclose(m_saveFilePtr);
- Stats.incDiscWrites();
- }
- CRecord* getOverflowRecord(int byte)
- {
- m_saveFilePtr = fopen(m_filename, "rb");
- fseek(m_saveFilePtr, byte, SEEK_SET);
- m_readSuccessful = fread(&m_tmpOverflowRecord, sizeof(CRecord), 1, m_saveFilePtr);
- fclose(m_saveFilePtr);
- Stats.incDiscReads();
- return &m_tmpOverflowRecord;
- }
- bool findMatchingPlaceForKey(int inputKey, int pageNum, int* outputPosOnPage, bool* outputPosEmpty, bool* duplicate)
- {
- *outputPosOnPage = -1;
- *outputPosEmpty = false;
- *duplicate = false;
- bool found = false;
- loadPage(pageNum);
- for(int i = 0; i < BUFFER_SIZE; i++)
- {
- if(m_readBuffer[i].getKey() == inputKey)
- {
- *outputPosOnPage = i;
- *duplicate = true;
- break;
- }
- if(m_readBuffer[i].getKey() > inputKey)
- {
- found = true;
- *outputPosOnPage = i - 1;
- break;
- }
- else if(m_readBuffer[i].getKey() == 0xFFFFFFFF)
- {
- *outputPosEmpty = true;
- found = true;
- *outputPosOnPage = i;
- break;
- }
- }
- return found;
- }
- void addMissingDataPages(char* idxDbFilename)
- {
- struct stat st;
- stat(idxDbFilename, &st);
- int pagesExpected = st.st_size/sizeof(CIndex);
- int missingPages = pagesExpected - getPagesInFileCnt();
- for(int i = 0; i < missingPages; i++)
- {
- clearWriteBuffer();
- writePage();
- }
- clearWriteBuffer();
- }
- //Constructor
- CDatabase(std::string name)
- {
- BUFFER_SIZE = DATA_BUFFER_SIZE;
- m_writeBuffer = new CRecord[BUFFER_SIZE];
- m_readBuffer = new CRecord[BUFFER_SIZE];
- //Set name and create apropriate file
- setName(name);
- //Clear buffer and points
- m_lastFileReadPoint = 0;
- m_lastFileWritePoint = 0;
- m_actualBufferReadPoint = 0;
- m_actualBufferWritePoint = 0;
- clearReadBuffer();
- clearWriteBuffer();
- m_readSuccessful = false;
- }
- };
- class CDatabaseMgr
- {
- private:
- CDatabase* m_database;
- CIndexesDatabase* m_idxDatabase;
- bool m_noRecords;
- int m_minKey;
- CIndex m_tmpIdx;
- CRecord m_tmpData;
- int m_overflowSize;
- public:
- void reorganise()
- {
- Stats.incReorganisations();
- m_database->setName("bdb");
- m_database->reset();
- m_idxDatabase->clearFile();
- m_idxDatabase->reset();
- m_idxDatabase->addIdxPage();
- m_idxDatabase->loadNextPage();
- CDatabase tmpDb("adb");
- int recordsInDatabase = tmpDb.getElementsCnt();
- CRecord tmpRecord, overflowRecord;
- CIndex tmpIdx;
- bool prevHasOverflow = false;
- bool hasOverflow = false;
- int prevNextOverflowByte = NULL;
- int nextOverflowByte = NULL;
- tmpDb.loadNextPage();
- int addedRecords = 0;
- while(recordsInDatabase != 0)
- {
- while(addedRecords < RECORDS_PER_PAGE && recordsInDatabase != 0)
- {
- if(!hasOverflow)
- {
- tmpRecord.setAll(tmpDb.getNextRecord());
- prevHasOverflow = hasOverflow;
- hasOverflow = tmpRecord.hasOverflowArea();
- prevNextOverflowByte = nextOverflowByte;
- nextOverflowByte = tmpRecord.getOverflowPointer();
- if(tmpRecord.getKey() == 0xFFFFFFFF)
- {
- --recordsInDatabase;
- if(tmpDb.isReadBufferFull())
- tmpDb.loadNextPage();
- continue;
- }
- tmpRecord.setOverflowPointer(0);
- m_database->addNextRecord(&tmpRecord);
- ++addedRecords;
- }
- else
- {
- tmpRecord.setAll(tmpDb.getOverflowRecord(nextOverflowByte));
- prevHasOverflow = hasOverflow;
- hasOverflow = tmpRecord.hasOverflowArea();
- prevNextOverflowByte = nextOverflowByte;
- nextOverflowByte = tmpRecord.getOverflowPointer();
- tmpRecord.setOverflowPointer(0);
- m_database->addNextRecord(&tmpRecord);
- ++addedRecords;
- }
- if(tmpDb.isReadBufferFull())
- tmpDb.loadNextPage();
- --recordsInDatabase;
- }
- if(addedRecords > 0)
- {
- tmpIdx.setAll(m_idxDatabase->getNextRecord());
- tmpIdx.setKey(m_database->getWriteBufferPtr()[0].getKey());
- m_idxDatabase->addNextRecord(&tmpIdx);
- std::cout << m_idxDatabase->getWriteBufferPtr()[m_idxDatabase->getActualBufferWritePoint()-1].getKey() << std::endl;
- m_database->saveNextPage();
- addedRecords = 0;
- if(m_idxDatabase->isWriteBufferFull())
- {
- m_idxDatabase->saveNextPage();
- m_idxDatabase->addIdxPage();
- m_idxDatabase->loadNextPage();
- }
- }
- }
- m_overflowSize = 0;
- m_idxDatabase->saveNextPage();
- //CleanUp
- remove("adb");
- rename("bdb","adb");
- m_database->setName("adb");
- m_database->resetStats();
- }
- bool isOverflowSizeExceeded()
- {
- return m_overflowSize == OVERFLOW_MAX_SIZE;
- }
- void addOverflowRecord(int masterPage, int masterPos, CRecord* slave)
- {
- //Czy ma overflow
- m_database->loadPage(masterPage);
- if(m_database->getReadBufferPtr()[masterPos].hasOverflowArea())
- {
- int lastLastRecordPointer = NULL;
- int lastRecordPointer = m_database->getReadBufferPtr()[masterPos].getOverflowPointer();
- //Czy overflow mniejszy ode mnie
- m_tmpData.setAll(m_database->getOverflowRecord(m_database->getReadBufferPtr()[masterPos].getOverflowPointer()));
- if(m_tmpData.getKey() < slave->getKey())
- {
- bool added = false;
- while(m_tmpData.getKey() < slave->getKey() && !added)
- {
- if(m_tmpData.hasOverflowArea())
- {
- //Zapamietaj pointer i wez nastepny
- lastLastRecordPointer = lastRecordPointer;
- lastRecordPointer = m_tmpData.getOverflowPointer();
- m_tmpData.setAll(m_database->getOverflowRecord(lastRecordPointer));
- }
- else
- {
- //Append na koncu
- int newRecordByte = m_database->addOverflowRecord(slave);
- //Dodaj pointer do ostatniego
- m_tmpData.setOverflowPointer(newRecordByte);
- m_database->modifyOverflowRecord(&m_tmpData,lastRecordPointer);
- added = true;
- }
- }
- if(m_tmpData.getKey() >= slave->getKey() && !added)
- {
- slave->setOverflowPointer(lastRecordPointer);
- //Append na koncu
- int newRecordByte = m_database->addOverflowRecord(slave);
- //Dodaj pointer do wczesniejszego
- m_tmpData.setAll(m_database->getOverflowRecord(lastLastRecordPointer));
- m_tmpData.setOverflowPointer(newRecordByte);
- m_database->modifyOverflowRecord(&m_tmpData,lastLastRecordPointer);
- }
- }
- else
- {
- slave->setOverflowPointer(lastRecordPointer);
- //Append na koncu
- int newRecordByte = m_database->addOverflowRecord(slave);
- //Dodaj pointer do mastera
- m_database->getReadBufferPtr()[masterPos].setOverflowPointer(newRecordByte);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(masterPage);
- }
- }
- else
- {
- //Append na koncu
- int newRecordByte = m_database->addOverflowRecord(slave);
- //Dodaj pointer do mastera
- m_database->getReadBufferPtr()[masterPos].setOverflowPointer(newRecordByte);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(masterPage);
- }
- ++m_overflowSize;
- if(isOverflowSizeExceeded())
- reorganise();
- }
- void shiftRecordsInBuffer(int pageNum, int startRecordIdx)
- {
- m_database->loadPage(pageNum);
- for(int i = startRecordIdx; i < DATA_BUFFER_SIZE; i++)
- {
- if(i+1 < DATA_BUFFER_SIZE)
- {
- m_database->getReadBufferPtr()[i].setAll(&m_database->getReadBufferPtr()[i+1]);
- }
- else
- {
- m_database->getReadBufferPtr()[i-1].setOverflowPointer(0);
- if(m_database->getReadBufferPtr()[i].hasOverflowArea())
- {
- int overflowPtr = m_database->getReadBufferPtr()[i].getOverflowPointer();
- m_database->getReadBufferPtr()[i].setAll(m_database->getOverflowRecord(overflowPtr));
- m_database->clearOverflowRecord(overflowPtr);
- }
- else
- {
- m_database->getReadBufferPtr()[i].reset();
- }
- }
- }
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(pageNum);
- }
- void delRecord(int key)
- {
- if(m_noRecords)
- {
- std::cout << "ERROR: Database empty!" << std::endl;
- }
- else
- {
- //Znajdz strone gdzie moze sie zmiescic
- //Czyli znajdz strone wieksza niz on sam
- int dataPageNum, dataPosOnPage;
- bool dataIsEmpty;
- bool duplicateKey;
- if(m_idxDatabase->findPageForKey(key,&dataPageNum, &duplicateKey))
- {
- if(m_database->findMatchingPlaceForKey(key, dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
- {
- if(dataIsEmpty)
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- else
- {
- m_database->loadPage(dataPageNum);
- if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
- {
- int nextOverflowByte = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
- int lastNextOverflowByte = NULL;
- CRecord* tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
- if(tmpOverflowRecord->getKey() == key)
- {
- //Znaleziony
- if(tmpOverflowRecord->hasOverflowArea())
- {
- lastNextOverflowByte = nextOverflowByte;
- nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
- m_database->getReadBufferPtr()[dataPosOnPage].setOverflowPointer(nextOverflowByte);
- m_database->clearOverflowRecord(lastNextOverflowByte);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(dataPageNum);
- std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
- }
- else
- {
- m_database->getReadBufferPtr()[dataPosOnPage].setOverflowPointer(0);
- m_database->clearOverflowRecord(nextOverflowByte);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(dataPageNum);
- std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
- }
- }
- else
- {
- while(tmpOverflowRecord->getKey() != key)
- {
- if(tmpOverflowRecord->hasOverflowArea())
- {
- lastNextOverflowByte = nextOverflowByte;
- nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
- tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
- }
- else
- {
- break;
- }
- }
- if(tmpOverflowRecord->getKey() == key)
- {
- int previous = lastNextOverflowByte;
- int me = nextOverflowByte;
- int next = tmpOverflowRecord->getOverflowPointer();
- tmpOverflowRecord = m_database->getOverflowRecord(previous);
- tmpOverflowRecord->setOverflowPointer(next);
- m_database->modifyOverflowRecord(tmpOverflowRecord,previous);
- m_database->clearOverflowRecord(me);
- std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- if(duplicateKey)
- {
- //Znaleziony w srodku
- if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
- {
- //Podmieniamy z jego overflowem
- int myOverflowPtr = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
- CRecord* tmpOverflowRecord = m_database->getOverflowRecord(m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer());
- m_database->getReadBufferPtr()[dataPosOnPage].setAll(tmpOverflowRecord);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(dataPageNum);
- m_database->clearOverflowRecord(myOverflowPtr);
- std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
- }
- else
- {
- //Swap
- shiftRecordsInBuffer(dataPageNum, dataPosOnPage);
- std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- if(duplicateKey)
- {
- m_database->loadPage(dataPageNum);
- if(m_database->getReadBufferPtr()[0].getKey() == key)
- {
- if(m_database->getReadBufferPtr()[0].hasOverflowArea())
- {
- //Podmieniamy z jego overflowem
- int myOverflowPtr = m_database->getReadBufferPtr()[0].getOverflowPointer();
- CRecord* tmpOverflowRecord = m_database->getOverflowRecord(m_database->getReadBufferPtr()[0].getOverflowPointer());
- m_database->getReadBufferPtr()[0].setAll(tmpOverflowRecord);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(dataPageNum);
- m_database->clearOverflowRecord(myOverflowPtr);
- std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
- }
- else
- {
- shiftRecordsInBuffer(dataPageNum, 0);
- std::cout << "SUCCESS: Record successfully deleted!" << std::endl;
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- }
- void updateRecord(CRecord* record)
- {
- if(m_noRecords)
- {
- std::cout << "ERROR: Database empty!" << std::endl;
- }
- else
- {
- //Znajdz strone gdzie moze sie zmiescic
- //Czyli znajdz strone wieksza niz on sam
- int dataPageNum, dataPosOnPage;
- bool dataIsEmpty;
- bool duplicateKey;
- if(m_idxDatabase->findPageForKey(record->getKey(),&dataPageNum, &duplicateKey))
- {
- if(m_database->findMatchingPlaceForKey(record->getKey(), dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
- {
- if(dataIsEmpty)
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- else
- {
- m_database->loadPage(dataPageNum);
- if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
- {
- int nextOverflowByte = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
- int lastNextOverflowByte = NULL;
- CRecord* tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
- if(tmpOverflowRecord->getKey() == record->getKey())
- {
- tmpOverflowRecord->setAll(record);
- m_database->modifyOverflowRecord(tmpOverflowRecord, nextOverflowByte);
- std::cout << "SUCCESS: Record updated" << std::endl;
- }
- else
- {
- while(tmpOverflowRecord->getKey() != record->getKey())
- {
- if(tmpOverflowRecord->hasOverflowArea())
- {
- lastNextOverflowByte = nextOverflowByte;
- nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
- tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
- }
- else
- {
- break;
- }
- }
- if(tmpOverflowRecord->getKey() == record->getKey())
- {
- tmpOverflowRecord->setAll(record);
- m_database->modifyOverflowRecord(tmpOverflowRecord, nextOverflowByte);
- std::cout << "SUCCESS: Record updated" << std::endl;
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- if(duplicateKey)
- {
- //Znaleziony w srodku
- m_database->loadPage(dataPageNum);
- m_database->getReadBufferPtr()[dataPosOnPage].setAll(record);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(dataPageNum);
- std::cout << "SUCCESS: Record updated!" << std::endl;
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- if(duplicateKey)
- {
- m_database->loadPage(dataPageNum);
- if(m_database->getReadBufferPtr()[0].getKey() == record->getKey())
- {
- m_database->loadPage(dataPageNum);
- m_database->getReadBufferPtr()[0].setAll(record);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(dataPageNum);
- std::cout << "SUCCESS: Record updated!" << std::endl;
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- }
- void findRecord(int key)
- {
- if(m_noRecords)
- {
- std::cout << "ERROR: Database empty!" << std::endl;
- }
- else
- {
- //Znajdz strone gdzie moze sie zmiescic
- //Czyli znajdz strone wieksza niz on sam
- int dataPageNum, dataPosOnPage;
- bool dataIsEmpty;
- bool duplicateKey;
- if(m_idxDatabase->findPageForKey(key,&dataPageNum, &duplicateKey))
- {
- if(m_database->findMatchingPlaceForKey(key, dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
- {
- if(dataIsEmpty)
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- else
- {
- m_database->loadPage(dataPageNum);
- if(m_database->getReadBufferPtr()[dataPosOnPage].hasOverflowArea())
- {
- int nextOverflowByte = m_database->getReadBufferPtr()[dataPosOnPage].getOverflowPointer();
- int lastNextOverflowByte = NULL;
- CRecord* tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
- if(tmpOverflowRecord->getKey() == key)
- {
- std::cout << "SUCCESS: Record found. Key: " << tmpOverflowRecord->getKey() << "; Height: " << tmpOverflowRecord->getDataPtr()->getHeight() << "; Radius: " << tmpOverflowRecord->getDataPtr()->getRadius() << std::endl;
- }
- else
- {
- while(tmpOverflowRecord->getKey() != key)
- {
- if(tmpOverflowRecord->hasOverflowArea())
- {
- lastNextOverflowByte = nextOverflowByte;
- nextOverflowByte = tmpOverflowRecord->getOverflowPointer();
- tmpOverflowRecord = m_database->getOverflowRecord(nextOverflowByte);
- }
- else
- {
- break;
- }
- }
- if(tmpOverflowRecord->getKey() == key)
- {
- std::cout << "SUCCESS: Record found. Key: " << tmpOverflowRecord->getKey() << "; Height: " << tmpOverflowRecord->getDataPtr()->getHeight() << "; Radius: " << tmpOverflowRecord->getDataPtr()->getRadius() << std::endl;
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- if(duplicateKey)
- {
- //Znaleziony w srodku
- std::cout << "SUCCESS: Record found. Key: " << m_database->getReadBufferPtr()[dataPosOnPage].getKey()
- << "; Height: " << m_database->getReadBufferPtr()[dataPosOnPage].getDataPtr()->getHeight()
- << "; Radius: " << m_database->getReadBufferPtr()[dataPosOnPage].getDataPtr()->getRadius() << std::endl;
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- else
- {
- if(duplicateKey)
- {
- m_database->loadPage(dataPageNum);
- if(m_database->getReadBufferPtr()[0].getKey() == key)
- {
- std::cout << "SUCCESS: Record found. Key: " << m_database->getReadBufferPtr()[0].getKey()
- << "; Height: " << m_database->getReadBufferPtr()[0].getDataPtr()->getHeight()
- << "; Radius: " << m_database->getReadBufferPtr()[0].getDataPtr()->getRadius() << std::endl;
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- else
- {
- std::cout << "ERROR: Record not found!" << std::endl;
- }
- }
- }
- }
- void addRecord(CRecord* record)
- {
- if(m_noRecords)
- {
- //Dodaj strone z indeksami w bazie
- m_idxDatabase->addIdxPage();
- m_database->addMissingDataPages(m_idxDatabase->getFilename());
- //Dodaj klucz do bazy indeksow
- m_idxDatabase->loadPage(0);
- m_tmpIdx.reset();
- m_tmpIdx.setKey(record->getKey());
- m_tmpIdx.setPageNumber(m_idxDatabase->getNextRecord()->getPageNumber());
- m_idxDatabase->copyWriteBuffer(m_idxDatabase->getReadBufferPtr());
- m_idxDatabase->clearActualBufferWritePoint();
- m_idxDatabase->addNextRecord(&m_tmpIdx);
- m_idxDatabase->writePage(0);
- //Dodaj klucz do pierwszej strony bazy
- m_database->clearWriteBuffer();
- m_database->addNextRecord(record);
- m_database->savePage(m_tmpIdx.getPageNumber());
- m_noRecords = false;
- }
- else
- {
- //Sprawdz czy klucz jest mniejszy niz najmniejszy
- if(m_minKey > record->getKey())
- {
- std::cout << "ERROR: Key value is lower than the lowest! Record cannot be added!" << std::endl;
- }
- else
- {
- //Znajdz strone gdzie moze sie zmiescic
- //Czyli znajdz strone wieksza niz on sam
- int dataPageNum, dataPosOnPage;
- bool dataIsEmpty;
- bool duplicateKey;
- if(m_idxDatabase->findPageForKey(record->getKey(),&dataPageNum, &duplicateKey))
- {
- if(m_database->findMatchingPlaceForKey(record->getKey(), dataPageNum, &dataPosOnPage, &dataIsEmpty, &duplicateKey))
- {
- if(dataPosOnPage == -1)
- {
- std::cout << "WARNING: Operation cannot be executed without reorganising the file! Reorganise file and try again!" << std::endl;
- return;
- }
- else if(dataIsEmpty)
- {
- m_database->loadPage(dataPageNum);
- m_database->getReadBufferPtr()[dataPosOnPage].setAll(record);
- m_database->copyWriteBuffer(m_database->getReadBufferPtr());
- m_database->savePage(dataPageNum);
- }
- else
- {
- //Dodaj do overflowa znalezionego
- addOverflowRecord(dataPageNum, dataPosOnPage, record);
- }
- }
- else
- {
- if(duplicateKey)
- {
- std::cout << "ERROR: Key already in database!" << std::endl;
- }
- //Dodaj do overflowa ostatniego
- addOverflowRecord(dataPageNum, DATA_BUFFER_SIZE-1, record);
- }
- }
- else
- {
- if(duplicateKey)
- {
- m_database->loadPage(dataPageNum);
- if(m_database->getReadBufferPtr()[0].getKey() > record->getKey())
- {
- std::cout << "WARNING: Operation cannot be executed without reorganising the file! Reorganise file and try again!" << std::endl;
- }
- else
- {
- std::cout << "ERROR: Key already in database!" << std::endl;
- }
- return;
- }
- //TBD
- }
- }
- }
- m_minKey = m_minKey < record->getKey() ? m_minKey : record->getKey();
- }
- int getOverflowSize()
- {
- int idxPages = m_idxDatabase->getPagesInFileCnt();
- int dataRecords = m_database->getElementsCnt();
- return (idxPages * INDEX_BUFFER_SIZE) - dataRecords;
- }
- void printSorted()
- {
- Stats.freeze();
- std::fstream idxLog;
- std::fstream dataLog;
- std::fstream overflowLog;
- idxLog.open("indexFileLogS.txt",std::ios::out);
- dataLog.open("dataFileLogS.txt",std::ios::out);
- int idxDbSize = m_idxDatabase->getElementsCnt();
- int dbSize = m_database->getElementsCnt() - m_overflowSize;
- int overflowStartByte = dbSize * sizeof(CRecord);
- CRecord overflowRecord;
- for(int i = 0; i < idxDbSize/INDEX_BUFFER_SIZE; i++)
- {
- m_idxDatabase->loadPage(i);
- idxLog << "Indexes page #" << i << std::endl;
- for(int j = 0; j < INDEX_BUFFER_SIZE; j++)
- {
- if(m_idxDatabase->getReadBufferPtr()[j].getKey() != 0xFFFFFFFF)
- idxLog << "#" << j << ": " << m_idxDatabase->getReadBufferPtr()[j].toString() << std::endl;
- }
- }
- for(int i = 0; i < dbSize/DATA_BUFFER_SIZE; i++)
- {
- m_database->loadPage(i);
- dataLog << "Data page #" << i << std::endl;
- int j = 0;
- bool hasOverflowArea = false;
- int overflowByte = true;
- CRecord* tmpRecord;
- while(j < DATA_BUFFER_SIZE)
- {
- if(!hasOverflowArea)
- {
- hasOverflowArea = m_database->getReadBufferPtr()[j].hasOverflowArea();
- overflowByte = m_database->getReadBufferPtr()[j].getOverflowPointer();
- if(m_database->getReadBufferPtr()[j].getKey() != 0xFFFFFFFF)
- dataLog << "#" << j << ": " << m_database->getReadBufferPtr()[j].toString() << std::endl;
- j++;
- }
- else
- {
- tmpRecord = m_database->getOverflowRecord(overflowByte);
- hasOverflowArea = tmpRecord->hasOverflowArea();
- overflowByte = tmpRecord->getOverflowPointer();
- dataLog << "OverflowRecord: " << m_database->getReadBufferPtr()[j].toString() << std::endl;
- }
- }
- }
- Stats.unfreeze();
- }
- void printAsIs()
- {
- Stats.freeze();
- std::fstream idxLog;
- std::fstream dataLog;
- std::fstream overflowLog;
- idxLog.open("indexFileLogA.txt",std::ios::out);
- dataLog.open("dataFileLogA.txt",std::ios::out);
- overflowLog.open("overflowFileLogA.txt",std::ios::out);
- int idxDbSize = m_idxDatabase->getElementsCnt();
- int dbSize = m_database->getElementsCnt() - m_overflowSize;
- int overflowStartByte = dbSize * sizeof(CRecord);
- CRecord overflowRecord;
- for(int i = 0; i < idxDbSize/INDEX_BUFFER_SIZE; i++)
- {
- m_idxDatabase->loadPage(i);
- idxLog << "Indexes page #" << i << std::endl;
- for(int j = 0; j < INDEX_BUFFER_SIZE; j++)
- {
- idxLog << "#" << j << ": " << m_idxDatabase->getReadBufferPtr()[j].toString() << std::endl;
- }
- }
- for(int i = 0; i < dbSize/DATA_BUFFER_SIZE; i++)
- {
- m_database->loadPage(i);
- dataLog << "Data page #" << i << std::endl;
- for(int j = 0; j < DATA_BUFFER_SIZE; j++)
- {
- dataLog << "#" << j << ": " << m_database->getReadBufferPtr()[j].toString() << std::endl;
- }
- }
- for(int i = 0; i < m_overflowSize; i++)
- {
- overflowRecord.setAll(m_database->getOverflowRecord(overflowStartByte+(i*sizeof(CRecord))));
- overflowLog << "#" << i << ": " << overflowRecord.toString() << std::endl;
- }
- Stats.unfreeze();
- }
- CDatabaseMgr(CDatabase* db, CIndexesDatabase* idxDb)
- {
- m_database = db;
- m_idxDatabase = idxDb;
- m_overflowSize = getOverflowSize();
- struct stat st;
- stat(m_idxDatabase->getFilename(), &st);
- m_noRecords = (st.st_size <= 0);
- if(m_noRecords)
- m_minKey = 0x7FFFFFFF;
- else
- {
- m_idxDatabase->readPage();
- m_tmpIdx.setAll(m_idxDatabase->getNextRecord());
- m_minKey = m_tmpIdx.getKey();
- }
- }
- };
- int main()
- {
- int inputSource = -1;
- EOperationType inputType;
- int argCounter = 0;
- std::string inputText = "";
- char inputTextCstr[256];
- std::string command = "";
- int lastSpace = 0;
- int lastLastSpace = 0;
- CRecord inputRecord;
- CIndexesDatabase idxDb("aidxdb");
- CDatabase db("adb");
- CDatabaseMgr dbMgr(&db, &idxDb);
- std::fstream inputFile;
- do
- {
- std::cout << "Wybierz zrodlo danych wejsciowych: " << std::endl
- << "1 - Dane z pliku zewnetrznego" << std::endl
- << "2 - Wpisywanie danych z klawiatury" << std::endl
- << "3 - Pseudolosowy generator rekordow" << std::endl
- << "4 - WYJSCIE Z PROGRAMU" << std::endl;
- std::cin >> inputSource;
- if (inputSource == 1)
- {
- std::string inputFileName;
- std::cout << "Specify input file name: ";
- std::cin >> inputFileName;
- inputFile.open(inputFileName,std::ios::in);
- do
- {
- inputFile.getline(inputTextCstr,256);
- inputText = inputTextCstr;
- if(inputText == "" || inputText == "end") continue;
- else inputText += " x";
- lastLastSpace = lastSpace;
- lastSpace = inputText.find(" ", lastSpace);
- command = inputText.substr(lastLastSpace, lastSpace);
- if(command == "add")
- {
- inputType = ADD_RECORD;
- }
- else if(command == "rem")
- {
- inputType = REM_RECORD;
- }
- else if(command == "find" || command == "seek")
- {
- inputType = FIND_RECORD;
- }
- else if(command == "reorganise")
- {
- inputType = REORGANIZE_DATABASE;
- std::cout << "Reorganising" << std::endl;
- dbMgr.reorganise();
- continue;
- }
- else if(command == "edit" || command == "modify")
- {
- inputType = MODIFY_RECORD;
- }
- lastLastSpace = lastSpace;
- lastSpace = inputText.find(" ", lastSpace+1);
- int key = -1;
- while(lastSpace != lastLastSpace && lastSpace != -1)
- {
- command = inputText.substr(lastLastSpace+1, lastSpace-lastLastSpace-1);
- lastLastSpace = lastSpace;
- lastSpace = inputText.find(" ", lastSpace+1);
- if(inputType == ADD_RECORD)
- {
- if(argCounter == 0)
- {
- inputRecord.setKey(atoi(command.c_str()));
- }
- else if(argCounter == 1)
- {
- inputRecord.getDataPtr()->setHeight(atoi(command.c_str()));
- }
- else if(argCounter == 2)
- {
- inputRecord.getDataPtr()->setRadius(atoi(command.c_str()));
- }
- }
- else if(inputType == REM_RECORD)
- {
- if(argCounter == 0)
- {
- key = atoi(command.c_str());
- }
- }
- ++argCounter;
- }
- command = inputText.substr(lastLastSpace+1, inputText.size()-lastLastSpace-1);
- lastLastSpace = lastSpace = 0;
- if(inputType == ADD_RECORD)
- {
- dbMgr.addRecord(&inputRecord);
- }
- else if(inputType == REM_RECORD)
- {
- dbMgr.delRecord(key);
- }
- key = -1;
- argCounter = 0;
- inputRecord.reset();
- for(int i = 0; i < 256; i++)
- inputTextCstr[i] = 0;
- } while(inputText != "end");
- inputFile.close();
- inputSource = 0;
- }
- else if (inputSource == 2)
- {
- do
- {
- std::cin.getline(inputTextCstr,256);
- inputText = inputTextCstr;
- if(inputText == "" || inputText == "end") continue;
- else inputText += " x";
- lastLastSpace = lastSpace;
- lastSpace = inputText.find(" ", lastSpace);
- command = inputText.substr(lastLastSpace, lastSpace);
- if(command == "add")
- {
- inputType = ADD_RECORD;
- }
- else if(command == "rem")
- {
- inputType = REM_RECORD;
- }
- else if(command == "find" || command == "seek")
- {
- inputType = FIND_RECORD;
- }
- else if(command == "reorganise")
- {
- inputType = REORGANIZE_DATABASE;
- std::cout << "Reorganising" << std::endl;
- dbMgr.reorganise();
- continue;
- }
- else if(command == "print")
- {
- dbMgr.printSorted();
- std::cout << "Check log files" << std::endl;
- continue;
- }
- else if(command == "print_as")
- {
- dbMgr.printAsIs();
- std::cout << "Check log files" << std::endl;
- continue;
- }
- else if(command == "edit" || command == "modify")
- {
- inputType = MODIFY_RECORD;
- }
- lastLastSpace = lastSpace;
- lastSpace = inputText.find(" ", lastSpace+1);
- int key = -1;
- while(lastSpace != lastLastSpace && lastSpace != -1)
- {
- command = inputText.substr(lastLastSpace+1, lastSpace-lastLastSpace-1);
- lastLastSpace = lastSpace;
- lastSpace = inputText.find(" ", lastSpace+1);
- if(inputType == ADD_RECORD || inputType == MODIFY_RECORD)
- {
- if(argCounter == 0)
- {
- inputRecord.setKey(atoi(command.c_str()));
- }
- else if(argCounter == 1)
- {
- inputRecord.getDataPtr()->setHeight(atoi(command.c_str()));
- }
- else if(argCounter == 2)
- {
- inputRecord.getDataPtr()->setRadius(atoi(command.c_str()));
- }
- }
- else if(inputType == REM_RECORD || inputType == FIND_RECORD)
- {
- if(argCounter == 0)
- {
- key = atoi(command.c_str());
- }
- }
- ++argCounter;
- }
- command = inputText.substr(lastLastSpace+1, inputText.size()-lastLastSpace-1);
- lastLastSpace = lastSpace = 0;
- if(inputType == ADD_RECORD)
- {
- if(inputRecord.getKey() < 0)
- std::cout << "ERROR: Key cannot be negative" << std::endl;
- else
- dbMgr.addRecord(&inputRecord);
- }
- else if(inputType == REM_RECORD)
- {
- dbMgr.delRecord(key);
- }
- else if(inputType == FIND_RECORD)
- {
- dbMgr.findRecord(key);
- }
- else if(inputType == MODIFY_RECORD)
- {
- dbMgr.updateRecord(&inputRecord);
- }
- key = -1;
- argCounter = 0;
- inputRecord.reset();
- for(int i = 0; i < 256; i++)
- inputTextCstr[i] = 0;
- } while(inputText != "end");
- inputSource = 0;
- }
- else if(inputSource == 3)
- {
- std::string outputFileName;
- std::cout << "Specify output file name: ";
- std::cin >> outputFileName;
- inputFile.open(outputFileName, std::ios::out);
- int keyMin = 0;
- int keyMax = 0;
- std::cout << "Specify min keyValue: ";
- std::cin >> keyMin;
- std::cout << "Specify max keyValue: ";
- std::cin >> keyMax;
- int records = 0;
- std::cout << "Specify records count: ";
- std::cin >> records;
- srand(time(NULL));
- inputFile << "add " << keyMin << " " << 1+rand()%50 << " " << 1+rand()%50 << " x" << std::endl;
- records--;
- for(int i = 0; i < records; i++)
- {
- inputFile << "add " << keyMin+rand()%(keyMax-keyMin) << " " << 1+rand()%50 << " " << 1+rand()%50 << " x" << std::endl;
- }
- inputFile << "end" << std::endl;
- std::cout << "File generated successfully" << std::endl;
- inputFile.close();
- }
- } while (inputSource < 1 || inputSource > 4);
- Stats.print();
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment