本文整理汇总了C++中LogRecord类的典型用法代码示例。如果您正苦于以下问题:C++ LogRecord类的具体用法?C++ LogRecord怎么用?C++ LogRecord使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了LogRecord类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: printLog
void printLog( const char *path, StoreManager* sm)
{
int fd;
off_t fpos;
int err=0;
LogRecord* lr;
WriteRecord* wr;
fd = ::open( path, O_RDONLY);
::lseek(fd, 0 ,SEEK_SET);
LogIO::getFilePos( fd, fpos );
printf("\npocztaek czytania : %ld\n",fpos);
while( (err = LogRecord::readLogRecordForward(lr, fd, sm)) == 0 )
{
int lt;
lr->getType(lt);
printf("\n|%d| \n",lt);
if(lt == WRITE_LOG_REC_TYPE)
{
wr = (WriteRecord*) lr;
if(wr->oldVal == NULL)
printf("oldVal == NULL ");
else
{
printf("oldVal = %s ",((wr->oldVal)->toString()).c_str());
}
printf("\n");
}
delete lr;
}
close(fd);
printf("\nerr=%d\n",err);
}
示例2: if
/*
* 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;
}
示例3: publish
/* FUNCTION: publish */
void LogHandlerWidget::publish(LogRecord logRecord) {
if (logRecord.getLogLevel() >= logLevel) {
//mutex.lock();
QString color = "";
QString bgcolor = "";
if (logRecord.getLogLevel() == 3)
bgcolor = "yellow";
if (logRecord.getLogLevel() == 4) {
bgcolor = "orange";
}
QString level =
QString("%1").arg(LogLevelNames[logRecord.getLogLevel()], 7);
level.replace(QString(" "), QString(" "));
QString source =
logRecord.getSource().length() == 0 ?
"" : logRecord.getSource().append(": ").c_str();
QString message =
QString("<table border=0 cellspacing=0 cellpadding=0><tr><td><font color=grey>%1 </font></td><td bgcolor=%2><font type=courier color=%3>[<code>%4</code>] </font></td><td bgcolor=%2><font color=%3>%5 %6</font></td></tr></table>")
.arg(logRecord.getDateTime()
.toString("yyyy-MM-dd hh:mm:ss.zzz"))
.arg(bgcolor).arg(color)
.arg(level)
.arg(source)
.arg(logRecord.getMessage().c_str());
textEdit->insertHtml(message);
textEdit->ensureCursorVisible();
if (logRecord.getLogLevel() > 2)
emit raiseWidget();
//mutex.unlock();
}
}
示例4: equals
bool LogRecordI::equals(const Object& object) const
{
LogRecord b;
if (object->instanceOf(b))
{
return toString()->equals(b->toString());
}
else
{
return false;
}
}
示例5:
void
Transaction::InTransactionListKeysWithOpType( int op_type, std::list<std::string> &new_keys )
{
LogRecord *log;
ordered_op_log.Rewind();
while( (log = ordered_op_log.Next()) ) {
if( log->get_op_type() == op_type ) {
new_keys.push_back( log->get_key() );
}
}
}
示例6: LogRecord
void Logger::log(const Level& level, std::string message, bool addRC) const {
if (isLoggable(level)) {
LogRecord* lr = new LogRecord(level, message, _name);
# if defined(__linux) || defined(__unix) || defined(__APPLE__)
pthread_mutex_lock(&Logger::lock);
#endif
if (onRecord != NULL) {
onRecord(lr);
delete lr;
} else {
Logger::logWrite(lr->toString(), addRC);
delete lr;
}
# if defined(__linux) || defined(__unix) || defined(__APPLE__)
pthread_mutex_unlock(&Logger::lock);
#endif
}
}
示例7: isLoggable
bool Handler::isLoggable( const LogRecord& record ) const {
if( this->level.intValue() == Level::OFF.intValue() ) {
return false;
} else if( record.getLevel().intValue() >= this->level.intValue()) {
return NULL == this->filter || this->filter->isLoggable( record );
}
return false;
}
示例8: hkey
bool
ClassAdLog::AdExistsInTableOrTransaction(const char *key)
{
bool adexists = false;
// first see if it exists in the "commited" hashtable
HashKey hkey(key);
ClassAd *ad = NULL;
table.lookup(hkey, ad);
if ( ad ) {
adexists = true;
}
// if there is no pending transaction, we're done
if (!active_transaction) {
return adexists;
}
// see what is going on in any current transaction
for (LogRecord *log = active_transaction->FirstEntry(key); log;
log = active_transaction->NextEntry())
{
switch (log->get_op_type()) {
case CondorLogOp_NewClassAd: {
adexists = true;
break;
}
case CondorLogOp_DestroyClassAd: {
adexists = false;
break;
}
default:
break;
}
}
return adexists;
}
示例9: main
int main(int argc, char* argv[]){
if(argc != 2){
cout<< "Usage: " << argv[0] << " <conf>" << endl;
return -1;
}
string conf(argv[1]);
if(NULL == FileService::Instance(conf)){
cout << "FileService::Instance faild" << endl;
return -1;
}
FileService::Load();
//MemoryPool
Memorypool::Instance();
//Threadpool
Threadpool::Instance();
//ActiveQueue
ActiveQueue<Request> *activeq = new ActiveQueue<Request>();
if(NULL == activeq){
cout << "New ActiveQueue failed" << endl;
return -1;
}
//Logrecord
LogRecord log;
log.set_type(17);
log.set_server("manager");
log.set_process("linkd");
log.set_message("Hello world\n");
int len = log.ByteSize();
char *buf = new char[len];
*buf = 0;
log.SerializeToArray(buf, len);
Trace("TRACE SerializeToArray: buf=%p, len=%d", buf, len);
// Scheduler
Scheduler *sch = new Scheduler(activeq);
if(NULL == sch){
cout << "New Scheduler failed" << endl;
return -1;
}
//start
Threadpool::Instance().schedule(boost::bind(&Scheduler::Dispatch, sch));
int i = 0;
while( i < 10){
Request *req = Memorypool::Instance().construct(buf, len);
activeq->Enqueue(req);
sleep(1);
i++;
}
Threadpool::Instance().wait();
return -1;
}
示例10: assert
//.........这里部分代码省略.........
int32_t numCols = -1;
// See if we can do better by using an index instead
TableIndex *index = table->primaryKeyIndex();
if (index != NULL) {
// First construct tuple for primary key
keydata = new char[index->getKeySchema()->tupleLength()];
keyTuple = new TableTuple(keydata, index->getKeySchema());
for (int i = 0; i < index->getKeySchema()->columnCount(); i++) {
keyTuple->setNValue(i, beforeImage->getNValue(index->getColumnIndices()[i]));
}
// no before image need be recorded, just the primary key
beforeImage = NULL;
}
// Set the modified column list
numCols = m_inputTargetMapSize;
modifiedCols.resize(m_inputTargetMapSize, -1);
for (int map_ctr = 0; map_ctr < m_inputTargetMapSize; map_ctr++) {
// can't use column-id directly, otherwise we would go over vector bounds
int pos = m_inputTargetMap[map_ctr].first - 1;
modifiedCols.at(pos)
= m_inputTargetMap[map_ctr].second;
}
// Next, let the input tuple be the diff after image
afterImage = &m_inputTuple;
LogRecord *logrecord = new LogRecord(computeTimeStamp(),
LogRecord::T_UPDATE,// this is an update record
LogRecord::T_FORWARD,// the system is running normally
-1,// XXX: prevLSN must be fetched from table!
m_engine->getExecutorContext()->currentTxnId() ,// txn id
m_engine->getSiteId(),// which execution site
m_targetTable->name(),// the table affected
keyTuple,// primary key
numCols,
(numCols > 0) ? &modifiedCols : NULL,
beforeImage,
afterImage
);
size_t logrecordLength = logrecord->getEstimatedLength();
char *logrecordBuffer = new char[logrecordLength];
FallbackSerializeOutput output;
output.initializeWithPosition(logrecordBuffer, logrecordLength, 0);
logrecord->serializeTo(output);
LogManager* m_logManager = this->m_engine->getLogManager();
Logger m_ariesLogger = m_logManager->getAriesLogger();
//VOLT_WARN("m_logManager : %p AriesLogger : %p",&m_logManager, &m_ariesLogger);
const Logger *logger = m_logManager->getThreadLogger(LOGGERID_MM_ARIES);
logger->log(LOGLEVEL_INFO, output.data(), output.position());
delete[] logrecordBuffer;
logrecordBuffer = NULL;
delete logrecord;
logrecord = NULL;
if (keydata != NULL) {
delete[] keydata;
keydata = NULL;
}
if (keyTuple != NULL) {
delete keyTuple;
keyTuple = NULL;
}
}
}
#endif
if (!m_targetTable->updateTuple(tempTuple, m_targetTuple,
m_updatesIndexes)) {
VOLT_INFO("Failed to update tuple from table '%s'",
m_targetTable->name().c_str());
return false;
}
}
VOLT_TRACE("TARGET TABLE - AFTER: %s\n", m_targetTable->debug().c_str());
// TODO lets output result table here, not in result executor. same thing in
// delete/insert
// add to the planfragments count of modified tuples
m_engine->m_tuplesModified += m_inputTable->activeTupleCount();
return true;
}
示例11: strdup
int
ClassAdLog::ExamineTransaction(const char *key, const char *name, char *&val, ClassAd* &ad)
{
bool AdDeleted=false, ValDeleted=false, ValFound=false;
int attrsAdded = 0;
if (!active_transaction) return 0;
for (LogRecord *log = active_transaction->FirstEntry(key); log;
log = active_transaction->NextEntry()) {
switch (log->get_op_type()) {
case CondorLogOp_NewClassAd: {
if (AdDeleted) { // check to see if ad is created after a delete
AdDeleted = false;
}
break;
}
case CondorLogOp_DestroyClassAd: {
AdDeleted = true;
if ( ad ) {
delete ad;
ad = NULL;
attrsAdded = 0;
}
break;
}
case CondorLogOp_SetAttribute: {
char const *lname = ((LogSetAttribute *)log)->get_name();
if (name && strcasecmp(lname, name) == 0) {
if (ValFound) {
free(val);
}
val = strdup(((LogSetAttribute *)log)->get_value());
ValFound = true;
ValDeleted = false;
}
if (!name) {
if ( !ad ) {
ad = new ClassAd;
ASSERT(ad);
}
if (val) {
free(val);
val = NULL;
}
ExprTree* expr = ((LogSetAttribute *)log)->get_expr();
if (expr) {
expr = expr->Copy();
ad->Insert(lname, expr, false);
} else {
val = strdup(((LogSetAttribute *)log)->get_value());
ad->AssignExpr(lname, val);
}
attrsAdded++;
}
break;
}
case CondorLogOp_DeleteAttribute: {
char const *lname = ((LogDeleteAttribute *)log)->get_name();
if (name && strcasecmp(lname, name) == 0) {
if (ValFound) {
free(val);
}
ValFound = false;
ValDeleted = true;
}
if (!name) {
if (ad) {
ad->Delete(lname);
attrsAdded--;
}
}
break;
}
default:
break;
}
}
if ( name ) {
if (AdDeleted || ValDeleted) return -1;
if (ValFound) return 1;
return 0;
} else {
if (attrsAdded < 0 ) {
return 0;
}
return attrsAdded;
}
}
示例12: addLogDetails
am_status_t LogService::addLogDetails(const std::string& logName,
const LogRecord& record,
const std::string& loggedByTokenID)
{
ScopeLock scopeLock(mLock);
char logLevel[32];
am_status_t status = AM_SUCCESS;
char *msg = NULL;
std::string message = record.getLogMessage();
//The encoded log message needs to be in multiple of 4 bytes.
msg = (char *)malloc(((message.size() * 4/3 + 1)/4+1)*4 + 4);
if(msg != NULL) {
encode_base64(message.c_str(), message.size(), msg);
} else {
status = AM_NO_MEMORY;
}
if (status == AM_SUCCESS) {
if(!remoteBodyChunkListInitialized) {
const std::size_t NUM_EXTRA_CHUNKS = 50;
remoteRequest = new Request(*this, requestPrefixChunk,
logRequestPrefixChunk, NUM_EXTRA_CHUNKS);
if (remoteRequest != NULL) {
remoteBodyChunkList = remoteRequest->getBodyChunkList();
remoteBodyChunkListInitialized = true;
}
}
if(bufferCount >= 1) {
remoteBodyChunkList.push_back(additionalRequestPrefixChunk);
BodyChunk temp;
char serviceIdBuf[1024];
if (remoteRequest != NULL) {
remoteRequest->getNextServiceRequestIdAsString(
serviceIdBuf, sizeof(serviceIdBuf));
}
temp.data = serviceIdBuf;
remoteBodyChunkList.push_back(temp);
}
sprintf(logLevel, "%d", record.getLogLevel());
remoteBodyChunkList.push_back(logLogPrefixChunk);
remoteBodyChunkList.push_back(BodyChunk(logName));
remoteBodyChunkList.push_back(logSidPrefixChunk);
remoteBodyChunkList.push_back(BodyChunk(loggedByTokenID));
remoteBodyChunkList.push_back(logLogSuffixChunk);
remoteBodyChunkList.push_back(logRecordPrefixChunk);
remoteBodyChunkList.push_back(logLevelPrefixChunk);
remoteBodyChunkList.push_back(BodyChunk(std::string(logLevel)));
remoteBodyChunkList.push_back(logLevelSuffixChunk);
remoteBodyChunkList.push_back(logRecMsgPrefixChunk);
std::string t_mesg(msg);
free(msg);
Utils::expandEntityRefs(t_mesg);
remoteBodyChunkList.push_back(BodyChunk(t_mesg));
remoteBodyChunkList.push_back(logRecMsgSuffixChunk);
remoteBodyChunkList.push_back(logInfoMapPrefixChunk);
const Properties &properties = record.getLogInfo();
Properties::const_iterator iter = properties.begin();
for(; iter != properties.end(); iter++) {
const Properties::key_type &k_iter = iter->first;
const Properties::mapped_type &v_iter = iter->second;
std::string keyStr("");
keyStr = k_iter.c_str();
std::string valueStr("");
valueStr = v_iter.c_str();
remoteBodyChunkList.push_back(logInfoKeyPrefixChunk);
remoteBodyChunkList.push_back(BodyChunk(keyStr));
remoteBodyChunkList.push_back(logInfoKeySuffixChunk);
remoteBodyChunkList.push_back(logInfoValuePrefixChunk);
remoteBodyChunkList.push_back(BodyChunk(valueStr));
remoteBodyChunkList.push_back(logInfoValueSuffixChunk);
}
remoteBodyChunkList.push_back(logInfoMapSuffixChunk);
remoteBodyChunkList.push_back(logRecordSuffixChunk);
remoteBodyChunkList.push_back(requestSuffixChunk);
bufferCount++;
} else {
status = AM_NO_MEMORY;
}
return status;
}
示例13: assert
bool DeleteExecutor::p_execute(const NValueArray ¶ms, ReadWriteTracker *tracker) {
assert(m_targetTable);
if (m_truncate) {
VOLT_TRACE("truncating table %s...", m_targetTable->name().c_str());
// count the truncated tuples as deleted
m_engine->m_tuplesModified += m_inputTable->activeTupleCount();
#ifdef ARIES
if(m_engine->isARIESEnabled()){
// no need of persistency check, m_targetTable is
// always persistent for deletes
LogRecord *logrecord = new LogRecord(computeTimeStamp(),
LogRecord::T_TRUNCATE,// this is a truncate record
LogRecord::T_FORWARD,// the system is running normally
-1,// XXX: prevLSN must be fetched from table!
m_engine->getExecutorContext()->currentTxnId() ,// txn id
m_engine->getSiteId(),// which execution site
m_targetTable->name(),// the table affected
NULL,// primary key irrelevant
-1,// irrelevant numCols
NULL,// list of modified cols irrelevant
NULL,// before image irrelevant
NULL// after image irrelevant
);
size_t logrecordLength = logrecord->getEstimatedLength();
char *logrecordBuffer = new char[logrecordLength];
FallbackSerializeOutput output;
output.initializeWithPosition(logrecordBuffer, logrecordLength, 0);
logrecord->serializeTo(output);
LogManager* m_logManager = this->m_engine->getLogManager();
Logger m_ariesLogger = m_logManager->getAriesLogger();
//VOLT_WARN("m_logManager : %p AriesLogger : %p",&m_logManager, &m_ariesLogger);
const Logger *logger = m_logManager->getThreadLogger(LOGGERID_MM_ARIES);
logger->log(LOGLEVEL_INFO, output.data(), output.position());
delete[] logrecordBuffer;
logrecordBuffer = NULL;
delete logrecord;
logrecord = NULL;
}
#endif
//m_engine->context().incrementTuples(m_targetTable->activeTupleCount());
// actually delete all the tuples
m_targetTable->deleteAllTuples(true);
return true;
}
// XXX : ARIES : Not sure if else is needed ?
assert(m_inputTable);
assert(m_inputTuple.sizeInValues() == m_inputTable->columnCount());
assert(m_targetTuple.sizeInValues() == m_targetTable->columnCount());
TableIterator inputIterator(m_inputTable);
while (inputIterator.next(m_inputTuple)) {
//
// OPTIMIZATION: Single-Sited Query Plans
// If our beloved DeletePlanNode is apart of a single-site query plan,
// then the first column in the input table will be the address of a
// tuple on the target table that we will want to blow away. This saves
// us the trouble of having to do an index lookup
//
void *targetAddress = m_inputTuple.getNValue(0).castAsAddress();
m_targetTuple.move(targetAddress);
// Read/Write Set Tracking
if (tracker != NULL) {
tracker->markTupleWritten(m_targetTable, &m_targetTuple);
}
#ifdef ARIES
if(m_engine->isARIESEnabled()){
// no need of persistency check, m_targetTable is
// always persistent for deletes
// before image -- target is tuple to be deleted.
TableTuple *beforeImage = &m_targetTuple;
TableTuple *keyTuple = NULL;
char *keydata = NULL;
// See if we use an index instead
TableIndex *index = m_targetTable->primaryKeyIndex();
if (index != NULL) {
// First construct tuple for primary key
keydata = new char[index->getKeySchema()->tupleLength()];
keyTuple = new TableTuple(keydata, index->getKeySchema());
for (int i = 0; i < index->getKeySchema()->columnCount(); i++) {
keyTuple->setNValue(i, beforeImage->getNValue(index->getColumnIndices()[i]));
//.........这里部分代码省略.........
示例14: while
/*
* If no txnum is specified, run the undo phase of ARIES.
* If a txnum is provided, abort that transaction.
* Hint: the logic is very similar for these two tasks!
*/
void LogMgr::undo(vector <LogRecord*> log, int txnum)
{
set<int> ToUndo;
if (txnum == NULL_TX)
{
for (auto txn : tx_table)
{
if (txn.second.status == U && txn.second.lastLSN != -1)
ToUndo.insert(txn.second.lastLSN);
}
}
else
{
ToUndo.insert(tx_table[txnum].lastLSN);
}
while (!ToUndo.empty())
{
int L = *(ToUndo.rbegin());
LogRecord *record = nullptr;
for (auto rec : log)
{
if (rec->getLSN() == L)
{
record = rec;
break;
}
}
if (!record)
{
return;
}
// If it is an update, write a CLR and undo the action
// And add the prevLSN to the set toUndo
if (record->getType() == UPDATE)
{
UpdateLogRecord *upRecord = (UpdateLogRecord*)record;
int pageLSN = se->getLSN(upRecord->getPageID());
int next = se->nextLSN();
logtail.push_back(new CompensationLogRecord(
next,
getLastLSN(upRecord->getTxID()),
upRecord->getTxID(),
upRecord->getPageID(),
upRecord->getOffset(),
upRecord->getBeforeImage(),
record->getprevLSN()));
tx_table[upRecord->getTxID()].lastLSN = next;
// Undo the action
if (dirty_page_table.find(upRecord->getPageID()) != dirty_page_table.end()
&& pageLSN < record->getLSN()
&& dirty_page_table.find(upRecord->getPageID())->second <= record->getLSN())
{
bool unwritten = se->pageWrite(upRecord->getPageID(), upRecord->getOffset(), upRecord->getBeforeImage(), upRecord->getLSN());
// Return false if Storage Engine got stuck
if (!unwritten)
return;
}
if (record->getprevLSN() != NULL_LSN)
ToUndo.insert(record->getprevLSN());
else
{
int next2 = se->nextLSN();
logtail.push_back(new LogRecord(next2, next, record->getTxID(), END));
tx_table.erase(record->getTxID());
}
}
if (record->getType() == ABORT) {
ToUndo.insert(record->getprevLSN());
}
// If it is a CLR
if (record->getType() == CLR)
{
// If the undoNextLSN value is null, write an end record
if (((CompensationLogRecord*)record)->getUndoNextLSN() == NULL_LSN)
{
int next2 = se->nextLSN();
logtail.push_back(new LogRecord(next2, record->getLSN(), record->getTxID(), END));
tx_table.erase(record->getTxID());
}
else
ToUndo.insert(((CompensationLogRecord*)record)->getUndoNextLSN());
}
ToUndo.erase(L);
//.........这里部分代码省略.........
示例15: syncs
void
Transaction::Commit(FILE* fp, void *data_structure, bool nondurable)
{
LogRecord *log;
/*
We'd like to keep a backup of the job queue log on a local
filesystem in case writes, flushes, or syncs to the standard
job queue log fail. Here's what we do:
1. If there is a LOCAL_QUEUE_BACKUP_DIR parameter that
contains a valid directory name, then we will create a local
backup file in that directory with a unique name. In this
case, we will assume that we might want a backup of the job
queue log. (If not, we will not make a local backup;
proceed to #4.)
2. Every operation we do to the job queue log: writes,
flushes, and syncs, we will also do to the local file. We
will track the first error we see writing to the job queue
log and will stop writing to the actual job queue log -- but
not EXCEPT -- when we encounter the first error.
3. Once we've completed writing log records, we will
unlink the local backup if there were no errors writing the
actual job queue log, *unless* the parameter
LOCAL_XACT_BACKUP_FILTER is set to "ALL".
4. If there was a failure writing the actual job queue log,
we will then report (via EXCEPT) the first error we observed
while writing the actual job queue log, as well as the
location of the local backup file, if we made one.
*/
/* info about a backup: do we keep one? where is it? etc. */
backup_info_t bi;
init_backup_info(&bi, (nondurable || fp == NULL));
/* job queue log is element 0, backup file (if any) is
element 1 */
stream_with_status_t fps[2];
/* fps[0] will be the actual job queue log and fps[1] will be
the local backup. If either file pointer is NULL, then
operations on that stream will be no-ops. */
init_stream_with_status(&(fps[0]), fp);
init_stream_with_status(&(fps[1]), bi.fp);
/*
Do we want to keep local xact backups even if we
successfully wrote them to the actual log?
*/
bool fussy = bi.filt == BF_ALL;
ordered_op_log.Rewind();
// We're seeing sporadic test suite failures where
// CommitTransaction() appears to take a long time to
// execute. Timing the I/O operations will help us
// narrow down the cause
time_t before, after;
/*
We only go through the log once to avoid any interactions
with anything that happens to the log outside of this code
(or with the behavior of Rewind).
*/
while( (log = ordered_op_log.Next()) ) {
for (int i=0; i<2; i++) {
/* This call will only write to a file until it detects
the first error. */
before = time(NULL);
write_with_status(log, &(fps[i]));
after = time(NULL);
if ( (after - before) > 5 ) {
dprintf( D_FULLDEBUG, "Transaction::Commit(): write_with_status() took %ld seconds to run\n", after - before );
}
}
log->Play(data_structure);
}
if( !nondurable ) {
/* Note the change from the above: we always want to flush
and sync the real job queue log, but we will only flush
and sync the local backup if we either (1) observed a
failure writing the log or (2) if we are keeping ALL
backups.
Here, we're operating on the real job queue log.
*/
before = time(NULL);
fflush_with_status(&(fps[0]));
after = time(NULL);
if ( (after - before) > 5 ) {
dprintf( D_FULLDEBUG, "Transaction::Commit(): fflush_with_status() took %ld seconds to run\n", after - before );
}
before = time(NULL);
//.........这里部分代码省略.........