The logger now calls fwrite half as often as it used to. This could be improved significantly, but some latching details internal to the logger need to be worked out first.

This commit is contained in:
Sears Russell 2004-10-18 19:19:10 +00:00
parent ec1276f26f
commit c850ce3a51
2 changed files with 48 additions and 22 deletions

View file

@ -51,6 +51,8 @@ terms specified in this license.
#include <stdio.h>
#include <lladd/bufferManager.h>
byte * logBuffer = 0;
/**
@todo Should the log file be global?
*/
@ -77,7 +79,8 @@ static rwl * flushedLSN_lock;
@see writeLogEntry
*/
static lsn_t nextAvailableLSN = 0;
static lsn_t writtenLSN_val = 0;
static int bufferedSize = 0;
/**
Invariant: writeLogEntry() must be able to atomicly read
nextAvailableLSN, and then update it. (This lock does not have to
@ -141,6 +144,9 @@ int openLogWriter() {
nextAvailableLSN = 0;
bufferedSize = 0;
writtenLSN_val= 0;
/* maxLSNEncountered = sizeof(lsn_t);
writeLogEntryIsReady = 0; */
@ -196,8 +202,11 @@ int openLogWriter() {
LSN encountered so far to the end of the log.
*/
int flushLog();
int writeLogEntry(LogEntry * e) {
int nmemb;
const long size = sizeofLogEntry(e);
if(e->type == UPDATELOG) {
@ -248,39 +257,52 @@ int writeLogEntry(LogEntry * e) {
/* We have the write lock, so no one else can call fseek behind our back. */
/* flockfile(log); */ /* Prevent other threads from calling fseek... */
fseek(log, nextAvailableLSN - global_offset, SEEK_SET);
nextAvailableLSN += (size + sizeof(long));
int oldBufferedSize = bufferedSize;
bufferedSize += (size + sizeof(long));
fseek(log, writtenLSN_val /*nextAvailableLSN*/ - global_offset, SEEK_SET);
/* Print out the size of this log entry. (not including this item.) */
nmemb = fwrite(&size, sizeof(long), 1, log);
if(nmemb != 1) {
perror("writeLog couldn't write next log entry size!");
assert(0);
return FILE_WRITE_ERROR;
logBuffer = realloc(logBuffer, size + sizeof(long));
if(! logBuffer) {
abort();
}
nmemb = fwrite(e, size, 1, log);
memcpy(logBuffer + oldBufferedSize, &size, sizeof(long));
memcpy(logBuffer + oldBufferedSize + sizeof(long), e, size);
if(nmemb != 1) {
perror("writeLog couldn't write next log entry!");
assert(0);
return FILE_WRITE_ERROR;
}
flushLog();
/* funlockfile(log); */
pthread_mutex_unlock(&log_write_mutex);
writeunlock(log_read_lock);
/* We're done. */
return 0;
}
/**
Preliminary version of a function that will write multiple log
entries at once. It turns out that there are some nasty
interactions between write() calls and readLSN, and locking, so
this currently only writes one entry at a time. (If this function
weren't designed to bundle log entries together, it would not make
such heavy use of global variables...) */
static int flushLog() {
if (!logBuffer) { return 0;}
int nmemb = fwrite(logBuffer, bufferedSize, 1, log);
writtenLSN_val += bufferedSize;
bufferedSize = 0;
if(nmemb != 1) {
perror("writeLog couldn't write next log entry!");
assert(0);
return FILE_WRITE_ERROR;
}
return 0;
}
void syncLog() {
lsn_t newFlushedLSN;
newFlushedLSN = myFseek(log, 0, SEEK_END);
/* Wait to set the static variable until after the flush returns. */
@ -459,6 +481,7 @@ int truncateLog(lsn_t LSN) {
*/
pthread_mutex_lock(&log_write_mutex);
lh = getLSNHandle(LSN);

View file

@ -59,7 +59,10 @@ terms specified in this license.
* performance.
*
* @todo Everything in this file cores on failure (no error handling yet)
* @todo All of the logWriter calls should be reentrant.
* @todo All of the logWriter calls should be reentrant. (aren't they?)
* @todo logWriter currently calls fwrite once per log entry. This may be a
* significant bottleneck. What is the most efficient way to write out
* log entries will still correctly supporing readLSN?
*
* $Id$
*