/* * Run the redo phase of ARIES. * If the StorageEngine stops responding, return false. * Else when redo phase is complete, return true. */ bool LogMgr::redo(vector <LogRecord*> log) { TxType tType; int lsn, pageID, offset, nextLsn; string afterImage; for(auto it = log.begin(); it != log.end(); it++) { LogRecord *logPointer = *it; tType = logPointer->getType(); lsn = logPointer->getLSN(); if ( tType == UPDATE ) { UpdateLogRecord * updateLogPointer = dynamic_cast<UpdateLogRecord *>(logPointer); pageID = updateLogPointer->getPageID(); afterImage = updateLogPointer->getAfterImage(); offset = updateLogPointer->getOffset(); } else if ( tType == CLR ) { CompensationLogRecord * compensationLogPointer = dynamic_cast<CompensationLogRecord *>(logPointer); pageID = compensationLogPointer->getPageID(); afterImage = compensationLogPointer->getAfterImage(); offset = compensationLogPointer->getOffset(); } if ( dirty_page_table.find(pageID) == dirty_page_table.end() ) { continue; } if( dirty_page_table[pageID] <= lsn && se->getLSN(pageID) < lsn ) { if( !(se->pageWrite(pageID, offset, afterImage, lsn)) ) { return false; } } } vector <int> txToErase; for ( auto it = tx_table.begin(); it != tx_table.end(); it++ ) { if( it->second.status == C && it->first != NULL_TX ) { nextLsn = se->nextLSN(); logtail.push_back(new LogRecord(nextLsn, it->second.lastLSN, it->first, END)); txToErase.push_back(it->first); } } for ( int i = 0; i < txToErase.size(); i++ ) { tx_table.erase(txToErase[i]); } return true; }
/* * Run the redo phase of ARIES. * If the StorageEngine stops responding, return false. * Else when redo phase is complete, return true. */ bool LogMgr::redo(vector <LogRecord*> log){ //first find the oldest update in the dirty-table int oldest_lsn = INT_MAX; map<int,int>::iterator it; for(it = dirty_page_table.begin(); it!=dirty_page_table.end(); it++){ if(it->second < oldest_lsn){ oldest_lsn = it->second; } } // iterate through the log for(int i = oldest_lsn; i<log.size() ; i++){ TxType t = log[i]->getType(); if(t == UPDATE || t == CLR){ if(t == UPDATE){ // if this is update UpdateLogRecord * updLog = (UpdateLogRecord * ) log[i]; int pageID = updLog->getPageID(); //check the constraint it = dirty_page_table.find(pageID); //if the pageID is int the dirty page if(it !=dirty_page_table.end()){ // check if the reclsn is samller then the lsn int lsn = updLog->getLSN(); int reclsn = dirty_page_table[pageID]; if(reclsn <= lsn){ //check the page lsn is samller than the lsn int pageLSN = se->getLSN(pageID); if(pageLSN < lsn){ // redo things if(se->pageWrite(pageID,updLog->getOffset(),updLog->getAfterImage(),lsn)){ }else{ return false; } } } } } else{ // if this is clr CompensationLogRecord * clrLog = (CompensationLogRecord *) log[i]; int pageID = clrLog->getPageID(); it = dirty_page_table.find(pageID); if(it != dirty_page_table.end()){ int lsn = clrLog->getLSN(); int reclsn = dirty_page_table[pageID]; if(reclsn <= lsn){ int pageLSN = se->getLSN(pageID); if(pageLSN < lsn){ if(se->pageWrite(pageID,clrLog->getOffset(),clrLog->getAfterImage(),lsn)){ }else{ return false; } } } } } } } // write end type record for C type map<int ,txTableEntry>::iterator tit; for(tit = tx_table.begin(); tit != tx_table.end(); tit++){ if(tit->second.status == C){ LogRecord* eLR = new LogRecord(se->nextLSN(),tit->second.lastLSN,tit->first,TxType::END); logtail.push_back(eLR); tx_table.erase(tit); } } return false; }