/* * pb, pe为当前递归处理部分的前序部分的子串起止点,pe为最后一个字符的下标+1 * mb, me同理 */ Node *doRecover(char *pre, char *mid, int pb, int pe, int mb, int me) { if (pe > pb) { // 注意这里别漏了递归终止条件判断 Node *subtreeRoot = new Node; subtreeRoot->data = pre[pb]; int mr; for (mr = mb; mr < me; ++mr) { if (mid[mr] == pre[pb]) { break; } } subtreeRoot->l = doRecover(pre, mid, pb + 1, pb + 1 + (mr - mb), mb, // 算准边界是这道题唯一的难点 mr); subtreeRoot->r = doRecover(pre, mid, pb + 1 + (mr - mb), pe, mr + 1, me); return subtreeRoot; } else { return NULL; } }
/**************************************************************************** Desc: This routine checks to see if it is OK for another FDB to use a file. If so, it increments the file's use counter. NOTE: This routine assumes that the global mutex is NOT locked. ****************************************************************************/ RCODE F_Database::physOpen( F_Db * pDb, const char * pszFilePath, const char * pszRflDir, const char * pszPassword, FLMUINT uiOpenFlags, FLMBOOL bNewDatabase, // Is this a new F_Database object? IF_RestoreClient * pRestoreObj, IF_RestoreStatus * pRestoreStatus) { RCODE rc = NE_XFLM_OK; // See if we need to read in the database header. If the database was // already open (bNewDatabase == FALSE), we don't need to again. if( bNewDatabase) { // Read in the database header. if (RC_BAD( rc = readDbHdr( pszFilePath, pDb->m_pDbStats, (FLMBYTE *)pszPassword, (uiOpenFlags & XFLM_ALLOW_LIMITED_MODE) ? TRUE : FALSE))) { goto Exit; } // Allocate the pRfl object. Could not do this until this point // because we need to have the version number, block size, etc. // setup in the database header. flmAssert( !m_pRfl); if ((m_pRfl = f_new F_Rfl) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if (RC_BAD( rc = m_pRfl->setup( this, pszRflDir))) { goto Exit; } } // We must have exclusive access. Create a lock file for that // purpose, if there is not already a lock file. if (!m_pLockFileHdl) { if (RC_BAD( rc = getExclAccess( pszFilePath))) { goto Exit; } } // Do a recovery to ensure a consistent database // state before going any further. The FO_DONT_REDO_LOG // flag is used ONLY by the VIEW program. if (bNewDatabase && !(uiOpenFlags & XFLM_DONT_REDO_LOG)) { if (RC_BAD( rc = doRecover( pDb, pRestoreObj, pRestoreStatus))) { goto Exit; } } Exit: if (RC_BAD( rc)) { (void)pDb->m_pSFileHdl->releaseFiles(); } return( rc); }
Node *BinaryTree_recover(char *pre, char *mid) { int length = strlen(pre); return doRecover(pre, mid, 0, length, 0, length); }
//============================================================================= // METHOD : SPELLcontroller::executeCommand() //============================================================================= void SPELLcontroller::executeCommand( const ExecutorCommand& cmd ) { // If a (repeatable) command is being executed, discard this one if (isCommandPending() && (cmd.id != CMD_ABORT) && (cmd.id != CMD_FINISH) && (cmd.id != CMD_INTERRUPT) && (cmd.id != CMD_PAUSE) && (cmd.id != CMD_CLOSE)) { LOG_WARN("Discarding command " + cmd.id); return; } LOG_INFO("Now executing command " + cmd.id); startCommandProcessing(); if (cmd.id == CMD_ABORT) { doAbort(); } else if (cmd.id == CMD_FINISH) { doFinish(); } else if (cmd.id == CMD_ACTION) { doUserAction(); } else if (cmd.id == CMD_STEP) { doStep( false ); } else if (cmd.id == CMD_STEP_OVER) { doStep( true ); } else if (cmd.id == CMD_RUN) { doPlay(); } else if (cmd.id == CMD_SKIP) { doSkip(); } else if (cmd.id == CMD_GOTO) { if (cmd.earg == "line") { DEBUG("[C] Processing go-to-line " + cmd.arg); try { int line = STRI(cmd.arg); doGoto( line ); } catch(...) {}; } else if (cmd.earg == "label") { DEBUG("[C] Processing go-to-label " + cmd.arg); doGoto( cmd.arg ); } else { SPELLexecutor::instance().getCIF().error("Unable to process Go-To command, no target information", LanguageConstants::SCOPE_SYS ); } } else if (cmd.id == CMD_PAUSE) { doPause(); } else if (cmd.id == CMD_INTERRUPT) { doInterrupt(); } else if (cmd.id == CMD_SCRIPT) { /** \todo determine when to override */ doScript(cmd.arg,false); } else if (cmd.id == CMD_CLOSE) { m_recover = false; m_reload = false; doClose(); } else if (cmd.id == CMD_RELOAD) { doReload(); } else if (cmd.id == CMD_RECOVER) { doRecover(); } else { LOG_ERROR("[C] UNRECOGNISED COMMAND: " + cmd.id) } m_mailbox.commandProcessed(); // The command has finished, release the dispatcher setCommandFinished(); DEBUG("[C] Command execution finished " + cmd.id); //TEMPORARILY DISABLED: it creates deadlocks. // notifyCommandToCore( cmd.id ); }