├── src ├── dbconstants.hpp ├── parser.hpp ├── DBSystem.h ├── configurations.cpp ├── configurations.hpp ├── parser.cpp ├── mem_model.hpp ├── mem_model.cpp └── DBSystem.cpp └── .gitignore /src/dbconstants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DBCONSTANTS_H 2 | #define _DBCONSTANTS_H 3 | 4 | const int PAGE_SIZE = 4096; 5 | const int MAX_NAME_SIZE = 256; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/parser.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * cofig_parser.hpp 3 | * 4 | * Created on: 25-Jan-2014 5 | * Author: sriram 6 | */ 7 | 8 | #ifndef PARSER_HPP_ 9 | #define PARSER_HPP_ 10 | 11 | #include 12 | 13 | class ConfigParser { 14 | public: 15 | void parse(std::string configFileName); 16 | }; 17 | 18 | class ParserFactory { 19 | public: 20 | static ConfigParser *newParserInstance(); 21 | }; 22 | 23 | #endif /* PARSER_HPP_ */ 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Some of these are related to eclipse. So i keep them out of my repo 2 | .cproject 3 | .dep/ 4 | .project 5 | .settings/ 6 | Debug/ 7 | Release/ 8 | config/ 9 | 10 | 11 | #files being edited 12 | *~ 13 | 14 | # make and build files 15 | *.lst 16 | *.o 17 | *.eep 18 | *.lss 19 | *.map 20 | *.sym 21 | *.obj 22 | 23 | *.lib 24 | *.so 25 | *.a 26 | *.out 27 | *.obj 28 | *.swp 29 | 30 | # I keep these, since I prefer having the reference of the final build 31 | # *.elf 32 | # *.hex 33 | -------------------------------------------------------------------------------- /src/DBSystem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DBSystem.h 3 | * 4 | * Created on: 25-Jan-2014 5 | * Author: arpit 6 | */ 7 | 8 | #ifndef DBSYSTEM_H_ 9 | #define DBSYSTEM_H_ 10 | 11 | #include 12 | 13 | class DBSystem 14 | { 15 | public: 16 | DBSystem(); 17 | virtual ~DBSystem(); 18 | 19 | void populateDBInfo(); 20 | void populateDBInfo(std::string); 21 | void readConfig(std::string); 22 | void insertRecord(std::string,std::string); 23 | std::string getRecord(std::string,int); 24 | 25 | private: 26 | bool canLineBeAdded(std::string,int); 27 | 28 | }; 29 | 30 | #endif /*DBSYSTEM_H_*/ 31 | -------------------------------------------------------------------------------- /src/configurations.cpp: -------------------------------------------------------------------------------- 1 | 2 | using namespace std; 3 | 4 | #include 5 | 6 | #include "configurations.hpp" 7 | 8 | int Configurations::pageSize; 9 | int Configurations::numberOfPages; 10 | string Configurations::pathForData; 11 | TableMap Configurations::tables; 12 | TableBlockMap Configurations::tableBlocks; 13 | 14 | const string Configurations::CONFIG_FILE_PATH = "./config/config.txt"; 15 | 16 | const string Configurations::TAG_PAGESIZE = "PAGE_SIZE"; 17 | const string Configurations::TAG_NUM_PAGES = "NUM_PAGES"; 18 | const string Configurations::TAG_PATH_FOR_DATA = "PATH_FOR_DATA"; 19 | const string Configurations::TAG_BEGIN_TABLE = "BEGIN"; 20 | const string Configurations::TAG_END_TABLE = "END"; -------------------------------------------------------------------------------- /src/configurations.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * configurations.hpp 3 | * 4 | * Created on: 25-Jan-2014 5 | * Author: sriram 6 | */ 7 | 8 | #ifndef CONFIGURATIONS_HPP_ 9 | #define CONFIGURATIONS_HPP_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "mem_model.hpp" 15 | 16 | /* 17 | * TableName -> { AttributeName , Attribute DataType } 18 | */ 19 | typedef std::map > TableMap; 20 | typedef std::map >::iterator TableMapIterator; 21 | typedef std::pair StringMapEntry; 22 | typedef std::pair > TableMapEntry; 23 | 24 | typedef std::map > TableBlockMap; 25 | typedef std::map >::iterator TableBlockMapIterator; 26 | 27 | typedef std::map BlockLineNumberMap; 28 | typedef std::map::iterator BlockLineNumberMapIterator; 29 | 30 | class Configurations { 31 | public: 32 | static const std::string CONFIG_FILE_PATH; 33 | 34 | static const std::string TAG_PAGESIZE; 35 | static const std::string TAG_NUM_PAGES; 36 | static const std::string TAG_PATH_FOR_DATA; 37 | static const std::string TAG_BEGIN_TABLE; 38 | static const std::string TAG_END_TABLE; 39 | 40 | static int pageSize; 41 | static int numberOfPages; 42 | static std::string pathForData; 43 | static TableMap tables; // key: tableName value: map 44 | static TableBlockMap tableBlocks; 45 | 46 | }; 47 | 48 | #endif /* CONFIGURATIONS_HPP_ */ 49 | -------------------------------------------------------------------------------- /src/parser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * config_parser.cpp 3 | * 4 | * Created on: 25-Jan-2014 5 | * Author: sriram 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "parser.hpp" 15 | #include "configurations.hpp" 16 | 17 | using namespace std; 18 | 19 | void ConfigParser::parse(string configFileName) { 20 | ifstream fin(configFileName.c_str()); 21 | 22 | string tag; 23 | while (fin >> tag) { 24 | if (tag.compare(Configurations::TAG_PAGESIZE) == 0) { 25 | fin >> Configurations::pageSize; 26 | 27 | } else if (tag.compare(Configurations::TAG_NUM_PAGES) == 0) { 28 | fin >> Configurations::numberOfPages; 29 | 30 | } else if (tag.compare(Configurations::TAG_PATH_FOR_DATA) == 0) { 31 | fin >> Configurations::pathForData; 32 | 33 | } else if (tag.compare(Configurations::TAG_BEGIN_TABLE) == 0) { 34 | string tableName; 35 | fin >> tableName; 36 | 37 | map tableAttributes; 38 | while (1) { 39 | string line; 40 | fin >> line; 41 | 42 | if (line.compare(Configurations::TAG_END_TABLE) == 0) 43 | break; 44 | 45 | istringstream iss(line); 46 | string columnName, dataType; 47 | std::getline(iss, columnName, ','); 48 | std::getline(iss, dataType, ','); 49 | tableAttributes.insert(StringMapEntry(columnName, dataType)); 50 | } 51 | 52 | Configurations::tables.insert(TableMapEntry(tableName, 53 | tableAttributes)); 54 | } 55 | } 56 | } 57 | 58 | ConfigParser *ParserFactory::newParserInstance() { 59 | return (new ConfigParser()); 60 | } 61 | 62 | //int main() { 63 | // ConfigParser *parser = ParserFactory::newParserInstance(); 64 | // parser->parse(Configurations::CONFIG_FILE_PATH); 65 | // return 0; 66 | //} 67 | -------------------------------------------------------------------------------- /src/mem_model.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _MEM_MODEL_H 2 | #define _MEM_MODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dbconstants.hpp" 9 | 10 | #define PAGE_NOT_REPLACED -1 11 | #define PAGE_SIZE_EXCEEDED -2 12 | 13 | struct TableBlockId { 14 | std::string tableName; //data from this table 15 | long tableBlockNumber; //table file block number (unspanned) 16 | 17 | TableBlockId(std::string name, int number) { 18 | tableName = name; 19 | tableBlockNumber = number; 20 | } 21 | }; 22 | 23 | class MemoryModel { 24 | public: 25 | struct Page { 26 | int pageNumber; //page number 27 | 28 | TableBlockId *tableBlockId; 29 | 30 | char *data; //actual data 31 | int dataLength; //total occupied data size 32 | 33 | bool isModified; 34 | }; 35 | 36 | typedef std::list PageList; 37 | typedef std::map PageMap; 38 | 39 | private: 40 | int _capacity; 41 | int _currentSize; 42 | int _pageSize; 43 | 44 | PageList _pageList; 45 | PageList _freePageList; 46 | PageMap _tableToPagesMap; 47 | 48 | inline MemoryModel::Page * newPage(int, int); 49 | std::string tableBlockIdToKey(TableBlockId *); 50 | 51 | static MemoryModel *mm; 52 | MemoryModel(int, int); 53 | 54 | public: 55 | static MemoryModel *getInstance(int, int); 56 | ~MemoryModel(); 57 | 58 | //Check if the given table file block is present in the memory 59 | inline bool isPresent(TableBlockId *); 60 | 61 | //Add page. Returns replaced page number if any otherwise -1 62 | int allocate(TableBlockId *, const char *, int); 63 | 64 | std::string getRecordForBlock(TableBlockId *, int, int); 65 | std::string getBlockData(TableBlockId *); 66 | 67 | //Touch the page number to move to front 68 | void touch(TableBlockId *); 69 | void traverseList(); 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/mem_model.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "mem_model.hpp" 7 | 8 | using namespace std; 9 | 10 | typedef map::iterator PageMapIterator; 11 | typedef list::iterator PageListIterator; 12 | typedef pair PageMapEntry; 13 | 14 | MemoryModel *MemoryModel::mm= NULL; 15 | 16 | MemoryModel * MemoryModel::getInstance(int capacity, int pageSize) { 17 | if (mm == NULL) 18 | mm = new MemoryModel(capacity, pageSize); 19 | 20 | return mm; 21 | } 22 | 23 | ////////////////////// private methods /////////////////////// 24 | 25 | inline MemoryModel::Page * MemoryModel::newPage(int pageNumber, int pageSize) { 26 | Page *p = new Page(); 27 | p->pageNumber = pageNumber; 28 | p->tableBlockId = NULL; 29 | p->data = new char[pageSize + 1]; 30 | p->dataLength = 0; 31 | p->isModified = false; 32 | return p; 33 | } 34 | 35 | string MemoryModel::tableBlockIdToKey(TableBlockId *tid) { 36 | int digitCount = 1; 37 | long blockNumber = tid->tableBlockNumber; 38 | while (blockNumber >= 10) { 39 | blockNumber /= 10; 40 | digitCount++; 41 | } 42 | 43 | string key; 44 | key.append(tid->tableName); 45 | key.append("_"); 46 | char *number = new char[digitCount + 1]; 47 | sprintf(number, "%ld", tid->tableBlockNumber); 48 | key.append(number); 49 | 50 | delete[] number; 51 | 52 | return key; 53 | } 54 | 55 | inline bool MemoryModel::isPresent(TableBlockId *tid) { 56 | return (_tableToPagesMap.find(tableBlockIdToKey(tid)) 57 | != _tableToPagesMap.end()); 58 | } 59 | 60 | void MemoryModel::touch(TableBlockId *tid) { 61 | PageMapIterator it = _tableToPagesMap.find(tableBlockIdToKey(tid)); 62 | 63 | if (it == _tableToPagesMap.end()) 64 | return; 65 | 66 | //TODO: write the page to memory when touched. 67 | 68 | // TODO: See if this can be done efficiently 69 | _pageList.remove(it->second); 70 | _pageList.push_back(it->second); 71 | } 72 | 73 | ////////////////////// public methods /////////////////////// 74 | 75 | MemoryModel::MemoryModel(int capacity, int pageSize) : 76 | _capacity(capacity), _pageSize(pageSize) { 77 | 78 | int i; 79 | for (i = 0; i < _capacity; i++) 80 | _freePageList.push_back(newPage(i, _pageSize)); 81 | } 82 | 83 | void deleteList(MemoryModel::PageList &list) { 84 | PageListIterator it = list.begin(); 85 | while (it != list.end()) { 86 | MemoryModel::Page *p = *it; 87 | delete p->tableBlockId; 88 | delete[] p->data; 89 | delete p; 90 | it = list.erase(it); 91 | } 92 | } 93 | 94 | void MemoryModel::traverseList() { 95 | PageListIterator it = _pageList.begin() ; 96 | cout << "LRU : "; 97 | while (it != _pageList.end()) { 98 | MemoryModel::Page *p = *it; 99 | cout << p->tableBlockId->tableBlockNumber << " "; 100 | it++; 101 | } 102 | cout << endl; 103 | } 104 | 105 | MemoryModel::~MemoryModel() { 106 | if (!_freePageList.empty()) { 107 | deleteList(_freePageList); 108 | } 109 | 110 | if (!_pageList.empty()) { 111 | deleteList(_pageList); 112 | } 113 | 114 | _tableToPagesMap.clear(); 115 | } 116 | 117 | int MemoryModel::allocate(TableBlockId *tid, const char *content, 118 | int contentLength) { 119 | if (contentLength > _pageSize) { 120 | cout << "File block length is more than allowed page size." << endl; 121 | return PAGE_SIZE_EXCEEDED; 122 | } 123 | 124 | //Checking if the page is already present in the allocated list. 125 | if (isPresent(tid)) { 126 | //TODO: change the data if it has been changed 127 | 128 | cout << "Found in block number : " << tid->tableBlockNumber << endl; 129 | touch(tid); 130 | return PAGE_NOT_REPLACED; 131 | } 132 | 133 | // Freelist is empty then allocate a page from that 134 | if (!_freePageList.empty()) { 135 | Page *p = _freePageList.front(); 136 | _freePageList.pop_front(); 137 | 138 | p->tableBlockId = tid; 139 | p->dataLength = contentLength; 140 | memcpy(p->data, content, contentLength); 141 | p->data[contentLength] = '\0'; 142 | 143 | //New page mapping added 144 | //cout << "MISS " << p->pageNumber << endl; 145 | _tableToPagesMap.insert(PageMapEntry(tableBlockIdToKey(tid), p)); 146 | _pageList.push_back(p); 147 | 148 | return p->pageNumber; 149 | } 150 | 151 | //Replacing a page cause freelist is empty 152 | Page *p = _pageList.front(); 153 | //cout << "MISS " << p->pageNumber << endl; 154 | 155 | //Erase previous data 156 | _tableToPagesMap.erase(tableBlockIdToKey(p->tableBlockId)); 157 | delete (p->tableBlockId); 158 | 159 | //Write new data to the page 160 | p->isModified = false; 161 | p->dataLength = contentLength; 162 | memcpy(p->data, content, contentLength); 163 | p->data[contentLength] = '\0'; 164 | p->tableBlockId = tid; 165 | 166 | //Insert new mapping to map and move the page to the end of the list 167 | _tableToPagesMap.insert(PageMapEntry(tableBlockIdToKey(tid), p)); 168 | touch(tid); 169 | 170 | return p->pageNumber; 171 | } 172 | 173 | string MemoryModel::getRecordForBlock(TableBlockId *tableBlock, int recordId, 174 | int firstBlockRecordId) { 175 | PageMapIterator pageIterator = 176 | _tableToPagesMap.find(tableBlockIdToKey(tableBlock)); 177 | Page *pageToChange = pageIterator->second; 178 | string recordsString(pageToChange->data); 179 | 180 | istringstream iss(recordsString); 181 | string record; 182 | while(std::getline(iss, record, '\n')) { 183 | if(recordId == firstBlockRecordId) 184 | return record; 185 | firstBlockRecordId++; 186 | } 187 | 188 | return ""; 189 | } 190 | 191 | string MemoryModel::getBlockData(TableBlockId *tableBlock) { 192 | PageMapIterator pageIterator = 193 | _tableToPagesMap.find(tableBlockIdToKey(tableBlock)); 194 | Page *pageToChange = pageIterator->second; 195 | string recordsString(pageToChange->data); 196 | 197 | return recordsString; 198 | } 199 | 200 | /*int main() { 201 | MemoryModel *mm = MemoryModel::getInstance(3, 1024); 202 | 203 | mm->allocate(newBlock(7), (char *) "content", 7); 204 | mm->allocate(newBlock(0), (char *) "content", 7); 205 | mm->allocate(newBlock(1), (char *) "content", 7); 206 | mm->allocate(newBlock(2), (char *) "content", 7); 207 | mm->allocate(newBlock(0), (char *) "content", 7); 208 | mm->allocate(newBlock(3), (char *) "content", 7); 209 | mm->allocate(newBlock(0), (char *) "content", 7); 210 | mm->allocate(newBlock(4), (char *) "content", 7); 211 | mm->allocate(newBlock(2), (char *) "content", 7); 212 | mm->allocate(newBlock(3), (char *) "content", 7); 213 | mm->allocate(newBlock(0), (char *) "content", 7); 214 | mm->allocate(newBlock(3), (char *) "content", 7); 215 | mm->allocate(newBlock(2), (char *) "content", 7); 216 | mm->allocate(newBlock(1), (char *) "content", 7); 217 | mm->allocate(newBlock(2), (char *) "content", 7); 218 | mm->allocate(newBlock(0), (char *) "content", 7); 219 | mm->allocate(newBlock(1), (char *) "content", 7); 220 | mm->allocate(newBlock(7), (char *) "content", 7); 221 | mm->allocate(newBlock(0), (char *) "content", 7); 222 | mm->allocate(newBlock(1), (char *) "content", 7); 223 | 224 | delete mm; 225 | 226 | return 0; 227 | }*/ 228 | -------------------------------------------------------------------------------- /src/DBSystem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * DBSystem.cpp 3 | * 4 | * Created on: 25-Jan-2014 5 | * Author: arpit 6 | */ 7 | 8 | #include "DBSystem.h" 9 | 10 | #include "mem_model.hpp" 11 | #include "parser.hpp" 12 | #include "configurations.hpp" 13 | 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | 19 | DBSystem::DBSystem() { 20 | } 21 | 22 | DBSystem::~DBSystem() { 23 | } 24 | 25 | bool DBSystem::canLineBeAdded(string tableName, int length) { 26 | return true; 27 | } 28 | 29 | void DBSystem::readConfig(string filePath) { 30 | ConfigParser *parser = ParserFactory::newParserInstance(); 31 | parser->parse(filePath); 32 | 33 | //cout << "Page Size : " << Configurations::pageSize << endl; 34 | //cout << "Number of pages : " << Configurations::numberOfPages << endl; 35 | 36 | } 37 | 38 | string DBSystem::getRecord(string tableName, int recordId) { 39 | 40 | //cout << "GET : " << tableName << " and record : " << recordId << endl; 41 | 42 | MemoryModel *mm = MemoryModel::getInstance(Configurations::numberOfPages, 43 | Configurations::pageSize); 44 | 45 | TableBlockMapIterator tableBlockIterator = 46 | Configurations::tableBlocks.find(tableName); 47 | BlockLineNumberMap m = (BlockLineNumberMap) tableBlockIterator->second; 48 | BlockLineNumberMapIterator blockLineItr = m.begin(); 49 | 50 | int previousPageNumber = blockLineItr->first; 51 | int blockNumberToGetIntoMemory = -1; 52 | 53 | if (recordId == blockLineItr->second) { 54 | blockNumberToGetIntoMemory = previousPageNumber; 55 | } 56 | 57 | for (blockLineItr++; blockNumberToGetIntoMemory == -1 && blockLineItr 58 | != m.end(); blockLineItr++) { 59 | int currentPageNumber = blockLineItr->first; 60 | int currentLineNumber = blockLineItr->second; 61 | 62 | if (recordId == currentLineNumber) { 63 | blockNumberToGetIntoMemory = blockLineItr->first; 64 | } else if (recordId < currentLineNumber) { 65 | blockNumberToGetIntoMemory = previousPageNumber; 66 | } else { 67 | previousPageNumber = currentPageNumber; 68 | } 69 | } 70 | 71 | if (blockNumberToGetIntoMemory == -1) { 72 | blockNumberToGetIntoMemory = previousPageNumber; 73 | } 74 | 75 | TableBlockId * tableBlockId = new TableBlockId(tableName, 76 | blockNumberToGetIntoMemory); 77 | if (!mm->isPresent(tableBlockId)) { 78 | 79 | //if required block is not found in memory (LRU) 80 | int currentLineNumber = 0; 81 | string filePath = Configurations::pathForData + "/" + tableName 82 | + ".csv"; 83 | 84 | //cout << "Input to file : " << filePath << endl; 85 | ifstream dataFile(filePath.c_str()); 86 | 87 | int blockStartLineNumber = 88 | tableBlockIterator->second[blockNumberToGetIntoMemory]; 89 | 90 | //TODO: change the line number to offset of the file in the map 91 | string blockDataString; 92 | std::string line; 93 | 94 | //Skipping all the lines before the required block 95 | while (currentLineNumber != blockStartLineNumber) { 96 | getline(dataFile, line); 97 | currentLineNumber++; 98 | } 99 | 100 | int endLineNumber = 101 | tableBlockIterator->second[blockNumberToGetIntoMemory + 1]; 102 | 103 | while (getline(dataFile, line) > 0 && currentLineNumber 104 | != endLineNumber) { 105 | blockDataString.append(line + "\n"); 106 | currentLineNumber++; 107 | } 108 | 109 | blockDataString.resize(blockDataString.length()-1); 110 | 111 | int result = mm->allocate(tableBlockId, blockDataString.c_str(), 112 | blockDataString.length()); 113 | 114 | dataFile.close(); 115 | 116 | switch (result) { 117 | case PAGE_SIZE_EXCEEDED: 118 | return ""; 119 | case PAGE_NOT_REPLACED: 120 | //cout << "HIT " << tableBlockId->tableBlockNumber << endl; 121 | cout << "HIT" << endl; 122 | break; 123 | default: 124 | //cout << "MISS " << tableBlockId->tableBlockNumber << endl; 125 | cout << "MISS " << result << endl; 126 | break; 127 | } 128 | } else { 129 | //cout << "HIT " << tableBlockId->tableBlockNumber << endl; 130 | cout << "HIT" << endl; 131 | mm->touch(tableBlockId); 132 | } 133 | 134 | 135 | //mm->traverseList(); 136 | 137 | return mm->getRecordForBlock(tableBlockId, recordId, 138 | tableBlockIterator->second[blockNumberToGetIntoMemory]); 139 | } 140 | 141 | void DBSystem::insertRecord(string tableName, string record) { 142 | 143 | //cout << "Insert : " << tableName << " and record : " << record << endl; 144 | MemoryModel *mm = MemoryModel::getInstance(Configurations::numberOfPages, 145 | Configurations::pageSize); 146 | 147 | string filePath = Configurations::pathForData + "/" + tableName + ".csv"; 148 | 149 | //cout << "Ouput to file : " << filePath << endl; 150 | std::ofstream outfile; 151 | outfile.open(filePath.c_str() , std::ios_base::app); 152 | outfile << record << "\n"; 153 | outfile.flush(); 154 | 155 | TableBlockMapIterator tableBlockIterator = 156 | Configurations::tableBlocks.find(tableName); 157 | 158 | Configurations::tableBlocks.erase(tableBlockIterator); 159 | populateDBInfo(tableName); 160 | 161 | tableBlockIterator = Configurations::tableBlocks.find(tableName); 162 | int lastBlockNumber = Configurations::tableBlocks[tableName].size()-1; 163 | int blockStartLineNumber = tableBlockIterator->second[lastBlockNumber]; 164 | 165 | //cout << "Last block of table is numbered : " << lastBlockNumber << endl; 166 | //cout << "Start line numb " << blockStartLineNumber << endl; 167 | 168 | TableBlockId * tableBlockId = new TableBlockId(tableName, 169 | lastBlockNumber); 170 | 171 | if (mm->isPresent(tableBlockId) ) { 172 | //cout << "Block already present in memory." << endl; 173 | string blockData = mm->getBlockData(tableBlockId); 174 | mm->allocate(tableBlockId, blockData.c_str() , blockData.length()); 175 | } else { 176 | //cout << "Block not present in memory." << endl; 177 | // get the last block from file create the block of data and then allocate 178 | 179 | int currentLineNumber = 0; 180 | ifstream dataFile(filePath.c_str()); 181 | 182 | int blockStartLineNumber = tableBlockIterator->second[lastBlockNumber]; 183 | 184 | //TODO: change the line number to offset of the file in the map 185 | string blockDataString; 186 | std::string line; 187 | 188 | //Skipping all the lines before the required block 189 | while (currentLineNumber != blockStartLineNumber) { 190 | getline(dataFile, line); 191 | currentLineNumber++; 192 | } 193 | 194 | int endLineNumber = tableBlockIterator->second[lastBlockNumber + 1]; 195 | 196 | while (getline(dataFile, line) > 0 && currentLineNumber 197 | != endLineNumber) { 198 | blockDataString.append(line + "\n"); 199 | currentLineNumber++; 200 | } 201 | 202 | blockDataString.resize(blockDataString.length()-1); 203 | 204 | //cout << "Block to be allocated " << blockDataString << endl; 205 | //cout << "Block to be allocated - length " << blockDataString.length() << endl; 206 | 207 | dataFile.close(); 208 | 209 | //mm->touch(new TableBlockId(tableName , lastBlockNumber-1)); 210 | mm->allocate(tableBlockId, blockDataString.c_str(), 211 | blockDataString.length()); 212 | 213 | } 214 | 215 | //mm->traverseList(); 216 | 217 | } 218 | 219 | void DBSystem::populateDBInfo(string tableName) { 220 | 221 | string filePath = Configurations::pathForData + "/" + tableName + ".csv"; 222 | 223 | int count_of_bytes = 0; 224 | int current_block_number = 0; 225 | int current_line_number = 0; 226 | 227 | map tableBlockLineNumberMap; 228 | 229 | ifstream file(filePath.c_str()); 230 | string str; 231 | while (std::getline(file, str)) { 232 | 233 | int countNewLine = 1; 234 | int count = str.length(); 235 | 236 | // If counting newline make record go to next page and removing it make it get appended the current page 237 | // then include the newline. 238 | // otherwise exclude it. 239 | if ((count_of_bytes + count + countNewLine) > Configurations::pageSize 240 | && (count_of_bytes + count - countNewLine) 241 | <= Configurations::pageSize) { 242 | count = count; 243 | } else { 244 | count += countNewLine; 245 | } 246 | 247 | //int count = str.length() + 1; 248 | /*int count = str.length();*/ 249 | 250 | if ((count_of_bytes + count) <= Configurations::pageSize) { 251 | if (tableBlockLineNumberMap.find(current_block_number) 252 | == tableBlockLineNumberMap.end()) { 253 | tableBlockLineNumberMap[current_block_number] 254 | = current_line_number; 255 | } 256 | 257 | count_of_bytes += count; 258 | 259 | } else { 260 | current_block_number++; 261 | count_of_bytes = count; 262 | tableBlockLineNumberMap[current_block_number] = current_line_number; 263 | } 264 | current_line_number++; 265 | } 266 | Configurations::tableBlocks[tableName] = tableBlockLineNumberMap; 267 | } 268 | 269 | void DBSystem::populateDBInfo() { 270 | 271 | for (TableMapIterator tableMapEntry = Configurations::tables.begin(); tableMapEntry 272 | != Configurations::tables.end(); tableMapEntry++) { 273 | 274 | populateDBInfo((string) tableMapEntry->first); 275 | } 276 | 277 | for (TableBlockMapIterator iterator = Configurations::tableBlocks.begin() ; iterator 278 | != Configurations::tableBlocks.end() ; iterator++) { 279 | cout << "Table Name : " << iterator->first << endl; 280 | map m = iterator->second; 281 | for (map::iterator itr = m.begin() ; itr != m.end() ; itr++) { 282 | cout << "Block number : " << itr->first << " line number : " 283 | << itr->second << endl; 284 | } 285 | } 286 | } 287 | 288 | /*int main() { 289 | 290 | DBSystem dbSystem; 291 | dbSystem.readConfig(Configurations::CONFIG_FILE_PATH); 292 | 293 | dbSystem.populateDBInfo(); 294 | 295 | dbSystem.getRecord("countries", 0); 296 | dbSystem.getRecord("countries", 1); 297 | dbSystem.getRecord("countries", 2); 298 | dbSystem.getRecord("countries", 1); 299 | dbSystem.getRecord("countries", 2); 300 | dbSystem.getRecord("countries", 2); 301 | dbSystem.getRecord("countries", 3); 302 | dbSystem.getRecord("countries", 9); 303 | dbSystem.getRecord("countries", 39); 304 | dbSystem.getRecord("countries", 28); 305 | dbSystem.getRecord("countries", 1); 306 | dbSystem.getRecord("countries", 30); 307 | dbSystem.getRecord("countries", 38); 308 | dbSystem.getRecord("countries", 39); 309 | dbSystem.getRecord("countries", 31); 310 | dbSystem.insertRecord("countries", "record"); 311 | dbSystem.getRecord("countries", 42); 312 | dbSystem.getRecord("countries", 28); 313 | 314 | return 0; 315 | }*/ --------------------------------------------------------------------------------