CatalogManager::CatalogManager() { cm_delegate = this; BufferManager* bufmgr = BufferManager::getInstance(); Pager* pager; if(access("minisql.frm", R_OK)!=0) { bufmgr->createFile("minisql.frm"); cm_catRoot = cm_catNodeMgr.newEmptyNode(); cm_catNodeMgr.setRootNode(cm_catRoot); cm_catRoot->strval = new char[32]; strncpy(cm_catRoot->strval, "MINISQL v0.01", 32*sizeof(char)); } else { cm_catRoot = cm_catNodeMgr.newEmptyNode(); cm_catNodeMgr.setRootNode(cm_catRoot); pager = bufmgr->getPager("minisql.frm"); if(pager->getNPages() == 0) { cm_catRoot->strval = new char[32]; strncpy(cm_catRoot->strval, "MINISQL v0.01", 32*sizeof(char)); } else { // File exists and not empty size_t const_offset = sizeof(int)*6 + sizeof(double); size_t var_offset=0; unsigned char* block0 = bufmgr->getblock(pager, 0, BUFFER_FLAG_NONDIRTY); memcpy((char*)&(cm_catRoot->operation), block0, sizeof(int) ); cm_catRoot->strval = new char[CAT_NAME_MAXSIZE]; memcpy(cm_catRoot->strval, block0+sizeof(int), CAT_NAME_MAXSIZE); memcpy((char*)&(cm_catRoot->numval), block0+2*sizeof(int), sizeof(double)); var_offset = sizeof(int)+sizeof(double)+CAT_NAME_MAXSIZE; // If not empty but corrupted .frm -> Corrupted db -> clean all if(strcmp(cm_catRoot->strval, "MINISQL v0.01")!=0) { system("rm *.db"); system("rm *.frm"); system("rm *.idx"); cm_catNodeMgr.clean(); m_columndef.clean(); bufmgr->createFile("minisql.frm"); cm_catRoot = cm_catNodeMgr.newEmptyNode(); cm_catNodeMgr.setRootNode(cm_catRoot); cm_catRoot->strval = new char[32]; strncpy(cm_catRoot->strval, "MINISQL v0.01", 32*sizeof(char)); } else { BlockPtr bPtr; memcpy(&bPtr, block0+var_offset, sizeof(BlockPtr)); Node* node = cm_catRoot; Node* left = nullptr; unsigned char* block; vector<NodePair> bPtrStack; while(bPtr.lBlock!=CAT_FLAG_NONBLOCK || !bPtrStack.empty()) { while(bPtr.lBlock!=CAT_FLAG_NONBLOCK) { block = bufmgr->getblock(pager, bPtr.lBlock, BUFFER_FLAG_NONDIRTY); var_offset = bPtr.lOffset; left = cm_catNodeMgr.newEmptyNode(); // nodeMap[left] = count++; node->leftSon = left; node = left; left->strval = new char[CAT_NAME_MAXSIZE]; memcpy((char*)&left->operation, block+var_offset, sizeof(int)); var_offset += sizeof(int); memcpy((left->strval), block+var_offset, CAT_NAME_MAXSIZE); var_offset += CAT_NAME_MAXSIZE; memcpy((char*)&left->numval, block+var_offset, sizeof(double)); var_offset += sizeof(double); memcpy(&bPtr, block+var_offset, sizeof(BlockPtr)); bPtrStack.push_back(NodePair(left, bPtr)); } while(bPtr.rBlock == CAT_FLAG_NONBLOCK && !bPtrStack.empty()){ bPtrStack.pop_back(); if(!bPtrStack.empty()){ bPtr = bPtrStack.back().second; node = bPtrStack.back().first; } } if(bPtr.rBlock != CAT_FLAG_NONBLOCK) { bPtrStack.pop_back(); block = bufmgr->getblock(pager, bPtr.rBlock, BUFFER_FLAG_NONDIRTY); var_offset = bPtr.rOffset; left = cm_catNodeMgr.newEmptyNode(); // nodeMap[left] = count++; node->rightSon = left; node = left; left->strval = new char[CAT_NAME_MAXSIZE]; memcpy((char*)&left->operation, block+var_offset, sizeof(int)); var_offset += sizeof(int); memcpy((left->strval), block+var_offset, CAT_NAME_MAXSIZE); var_offset += CAT_NAME_MAXSIZE; memcpy((char*)&left->numval, block+var_offset, sizeof(double)); var_offset += sizeof(double); memcpy(&bPtr, block+var_offset, sizeof(BlockPtr)); bPtrStack.push_back(NodePair(left, bPtr)); } } } } // File exists and not empty } }
CatalogManager::~CatalogManager() { size_t const_offset = sizeof(int)*5 + sizeof(double) + CAT_NAME_MAXSIZE; size_t var_offset=0; Node* node = cm_catRoot; int nodeCount=0; NodePosMap nodeMap; vector<Node*> tStack; while(node!=nullptr||!tStack.empty()) { if(node!=nullptr) { nodeMap[node] = nodeCount++; if(node->rightSon!=nullptr) { tStack.push_back(node->rightSon); } node = node->leftSon; } else { node = tStack.back(); tStack.pop_back(); } } BufferManager* bufmgr = BufferManager::getInstance(); unsigned char* block; Pager* pager = bufmgr->getPager("minisql.frm"); int blockNumber, blockOffset, nodePerBlock; BlockPtr bPtr; nodePerBlock = BLOCK_SIZE / const_offset; node = cm_catRoot; while( node!=nullptr || !tStack.empty() ) { if(node!=nullptr) { blockNumber = nodeMap[node] / nodePerBlock; blockOffset = (nodeMap[node]%nodePerBlock)*const_offset; while(blockNumber>=pager->getNPages()) { bufmgr->newblock(pager, BUFFER_FLAG_NONDIRTY); } block = bufmgr->getblock(pager, blockNumber, BUFFER_FLAG_DIRTY); if(node->leftSon) { bPtr.lBlock = nodeMap[node->leftSon] / nodePerBlock; bPtr.lOffset = (nodeMap[node->leftSon]%nodePerBlock)*const_offset; } else { bPtr.lBlock = bPtr.lOffset = CAT_FLAG_NONBLOCK; } if(node->rightSon) { bPtr.rBlock = nodeMap[node->rightSon] / nodePerBlock; bPtr.rOffset = (nodeMap[node->rightSon]%nodePerBlock)*const_offset; } else { bPtr.rBlock = bPtr.rOffset = CAT_FLAG_NONBLOCK; } var_offset = blockOffset; memcpy(block + var_offset, &node->operation, sizeof(int)); var_offset+=sizeof(int); if(node->strval){ memcpy(block + var_offset, node->strval, CAT_NAME_MAXSIZE); var_offset+=CAT_NAME_MAXSIZE; } else{ memset(block + var_offset, 0, CAT_NAME_MAXSIZE); var_offset += CAT_NAME_MAXSIZE; } memcpy(block + var_offset, &node->numval, sizeof(double)); var_offset+=sizeof(double); memcpy(block + var_offset, &bPtr, sizeof(BlockPtr)); if(node->rightSon!=nullptr) { tStack.push_back(node->rightSon); } node = node->leftSon; } else { node = tStack.back(); tStack.pop_back(); } } cm_catNodeMgr.clean(); m_columndef.clean(); }