diff --git a/src/stasis/logger/logHandle.c b/src/stasis/logger/logHandle.c index a5f5350..2532865 100644 --- a/src/stasis/logger/logHandle.c +++ b/src/stasis/logger/logHandle.c @@ -40,10 +40,9 @@ permission to use and distribute the software in accordance with the terms specified in this license. ---*/ -#include - #include +#include #include struct LogHandle { @@ -51,41 +50,33 @@ struct LogHandle { lsn_t next_offset; /** The LSN of the log entry that we would return if previous is called. */ lsn_t prev_offset; - guard_fcn_t* guard; - void* guard_state; + /** The log this iterator traverses. */ stasis_log_t* log; }; /** - Sets the next and prev field of h, but does not set h.file_offset. - That should probably be set before calling this function. -*/ + Position the iterator to point at a log entry. + @param h the iterator to be repositioned. This call sets the + next_offset and prev_offset field. + + @param e the log record the iterator point to. next_offset + and prev_offset are derived from e. +*/ static void set_offsets(LogHandle * h, const LogEntry * e); -/*-------------------------------------------------------*/ - LogHandle* getLogHandle(stasis_log_t* log) { - - lsn_t lsn = log->truncation_point(log); - - return getGuardedHandle(log, lsn, NULL, NULL); + return getLSNHandle(log, log->truncation_point(log)); } LogHandle* getLSNHandle(stasis_log_t * log, lsn_t lsn) { - return getGuardedHandle(log, lsn, NULL, NULL); -} - -LogHandle* getGuardedHandle(stasis_log_t* log, lsn_t lsn, - guard_fcn_t * guard, void * guard_state) { LogHandle* ret = malloc(sizeof(*ret)); ret->next_offset = lsn; ret->prev_offset = lsn; - ret->guard = guard; - ret->guard_state = guard_state; ret->log = log; return ret; } + void freeLogHandle(LogHandle* lh) { free(lh); } @@ -94,15 +85,6 @@ const LogEntry * nextInLog(LogHandle * h) { if(ret != NULL) { set_offsets(h, ret); } - - if(h->guard) { - if(!(h->guard(ret, h->guard_state))) { - freeLogEntry(ret); - ret = NULL; - } - } - - return ret; } @@ -111,17 +93,8 @@ const LogEntry * previousInTransaction(LogHandle * h) { if(h->prev_offset > 0) { ret = h->log->read_entry(h->log, h->prev_offset); set_offsets(h, ret); - - if(h->guard) { - if(!h->guard(ret, h->guard_state)) { - freeLogEntry(ret); - ret = NULL; - } - } } - return ret; - } static void set_offsets(LogHandle * h, const LogEntry * e) { diff --git a/src/stasis/logger/logger2.c b/src/stasis/logger/logger2.c index 26cd920..14ed3fb 100644 --- a/src/stasis/logger/logger2.c +++ b/src/stasis/logger/logger2.c @@ -165,11 +165,9 @@ lsn_t LogDummyCLR(stasis_log_t* log, int xid, lsn_t prevLSN, return ret; } -static void groupCommit(stasis_log_t* log, lsn_t lsn); - lsn_t LogTransCommit(stasis_log_t* log, TransactionLog * l) { lsn_t lsn = LogTransCommon(log, l, XCOMMIT); - groupCommit(log, lsn); + LogForce(log, lsn, LOG_FORCE_COMMIT); return lsn; } @@ -178,10 +176,12 @@ lsn_t LogTransAbort(stasis_log_t* log, TransactionLog * l) { } lsn_t LogTransPrepare(stasis_log_t* log, TransactionLog * l) { lsn_t lsn = LogTransCommonPrepare(log, l); - groupCommit(log, lsn); + LogForce(log, lsn, LOG_FORCE_COMMIT); return lsn; } +static void groupCommit(stasis_log_t* log, lsn_t lsn); + void LogForce(stasis_log_t* log, lsn_t lsn, stasis_log_force_mode_t mode) { if(mode == LOG_FORCE_COMMIT) { diff --git a/stasis/logger/logHandle.h b/stasis/logger/logHandle.h index 873a301..a7abd15 100644 --- a/stasis/logger/logHandle.h +++ b/stasis/logger/logHandle.h @@ -50,60 +50,48 @@ BEGIN_C_DECLS typedef struct LogHandle LogHandle; /** - @file - A simple data structure that allows forward iterations over - the log, and also allows reverse iterations. Forward iterations - are used for redo, and return every log entry, in its original - order. Reverse iterations are used for undo, and are transaction - specific. They follow the prevLSN. (or the next entry to be - undone stored in any CLR's that are encountered.) + @file - logHandle is useful for read only access to the log. + Iterator for forward and reverse iterations over the log. Forward + iterations are used for redo and return each log entry in log + order. Reverse iterations are used for undo, and return each entry + in a particular transaction. They follow the prevLSN field, + skipping any undo entries that have been marked complete. @see logWriter.h For write access to the log. - @see logger2.h for the typedef of the logHandle struct - - $Id$ + @see logger.h For the api provided by log implementations. */ -/** Returns a logHandle pointing at the first log entry in the log. */ +/** + Allocate a logHandle pointing at the first log entry in the log. +*/ LogHandle* getLogHandle(stasis_log_t* log); -/** Returns a logHandle pointing at lsn. */ +/** + Allocate a logHandle pointing at a particular lsn. +*/ LogHandle* getLSNHandle(stasis_log_t* log, lsn_t lsn); -/** Returns a 'guarded log handle'. This handle executes a callback - function on each entry it encounters. If the guard returns 0, - then it's iterator terminates. Otherwise, it behaves normally. */ -LogHandle* getGuardedHandle(stasis_log_t* log, lsn_t lsn, - guard_fcn_t * f, void * guard_state); - +/** + Free any resources associated with a LogHandle object. +*/ void freeLogHandle(LogHandle* lh); -/** +/** @return a pointer to the next log entry in the log, or NULL if at EOF. - */ const LogEntry * nextInLog(LogHandle * h); -/** - Returns a pointer to the previous log entry in this - transaction. This is used to undo transactions. If the logHandle - is a guarded handle, the handle returns null. - - The guard is useful for Tprepare, partial rollback, and probably - any reasonable lock manager implementations. +/** + Returns a pointer to the previous log entry in this transaction. If we encounter a CLR, that means that everything after the clr's - undoNextLSN has already been undone. In that case, we can skip - all intervening log entries (including CLR's), since they contain - 'stale' data. + prevLSN has already been undone. Therefore, we skip all + intervening log entries (including CLR's), since they contain + obsolete data. - @return NULL if there is no previous LogEntry for this - transaction, or if the guard indicates that we're done by returning 0. + @return NULL if there is no previous LogEntry for this transaction */ const LogEntry * previousInTransaction(LogHandle * h); -/* -void closeHandle(LogHandle h); -*/ + END_C_DECLS #endif diff --git a/stasis/transactional.h b/stasis/transactional.h index 0d5aa8a..f67cf47 100644 --- a/stasis/transactional.h +++ b/stasis/transactional.h @@ -277,8 +277,9 @@ terms specified in this license. Stasis components can be classified as follows: - I/O utilities (file handles, OS compatibility wrappers) - - Write ahead logging component interfaces (logger.h, logger/inMemoryLog.h logger/logEntry.h logger/logger2.h logger/logHandle.h logger/logMemory.h logger/logWriter.h) - - Write ahead logging component implementations (hash based buffer manager, in memory log, etc...) + - Log interfaces (logger/logger2.c logger/logEntry.c logger/logHandle.c) and implementations (logger/logWriter.c logger/inMemoryLog.c) + - Buffer management + - Recovery - Page formats and associated operations (page/slotted.c page/fixed.c) - Application visible methods (Talloc, Tset, ThashInsert, etc)