2006-04-12 01:40:47 +00:00
|
|
|
#include "inMemoryLog.h"
|
2006-07-25 01:06:01 +00:00
|
|
|
#include "../latches.h"
|
2006-04-12 01:40:47 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
|
|
|
static rwl * flushedLSN_lock;
|
|
|
|
static lsn_t nextAvailableLSN;
|
|
|
|
static lsn_t globalOffset;
|
|
|
|
static rwl * globalOffset_lock;
|
|
|
|
static LogEntry ** buffer;
|
|
|
|
static lsn_t bufferLen;
|
|
|
|
int open_InMemoryLog() {
|
|
|
|
flushedLSN_lock = initlock();
|
|
|
|
globalOffset_lock = initlock();
|
|
|
|
globalOffset = 0;
|
|
|
|
nextAvailableLSN = 0;
|
|
|
|
buffer = malloc(4096 * 1024 * sizeof (LogEntry *));
|
|
|
|
bufferLen =4096 * 1024;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int writeLogEntry_InMemoryLog(LogEntry *e) {
|
|
|
|
writelock(flushedLSN_lock, 0);
|
|
|
|
lsn_t bufferOffset;
|
|
|
|
|
|
|
|
int done = 0;
|
|
|
|
do{
|
2006-09-27 20:30:12 +00:00
|
|
|
writelock(globalOffset_lock,0);
|
2006-04-12 01:40:47 +00:00
|
|
|
bufferOffset = nextAvailableLSN - globalOffset;
|
|
|
|
if(bufferOffset > bufferLen) {
|
2006-09-27 20:30:12 +00:00
|
|
|
bufferLen *= 2;
|
|
|
|
buffer = realloc(buffer, bufferLen);
|
2006-04-12 01:40:47 +00:00
|
|
|
} else {
|
|
|
|
done = 1;
|
|
|
|
}
|
|
|
|
} while (!done);
|
|
|
|
|
|
|
|
|
|
|
|
e->LSN = nextAvailableLSN;
|
|
|
|
|
2006-09-27 20:30:12 +00:00
|
|
|
LogEntry * cpy = malloc(sizeofLogEntry(e));
|
|
|
|
memcpy(cpy, e, sizeofLogEntry(e));
|
|
|
|
|
2006-04-12 01:40:47 +00:00
|
|
|
// printf ("lsn: %ld\n", e->LSN);
|
2006-09-27 20:30:12 +00:00
|
|
|
buffer[bufferOffset] = cpy;
|
2006-04-12 01:40:47 +00:00
|
|
|
|
|
|
|
// printf("lsn: %ld type: %d\n", e->LSN, e->type);
|
|
|
|
nextAvailableLSN++;
|
|
|
|
|
|
|
|
unlock(globalOffset_lock);
|
|
|
|
unlock(flushedLSN_lock);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
lsn_t flushedLSN_InMemoryLog() {
|
|
|
|
return nextAvailableLSN;
|
|
|
|
}
|
|
|
|
|
2006-09-27 20:30:12 +00:00
|
|
|
void syncLog_InMemoryLog() {
|
|
|
|
// no-op
|
|
|
|
}
|
|
|
|
|
|
|
|
lsn_t nextEntry_InMemoryLog(const LogEntry * e) {
|
|
|
|
return e->LSN + 1;
|
|
|
|
}
|
|
|
|
|
2006-04-12 01:40:47 +00:00
|
|
|
int truncateLog_InMemoryLog(lsn_t lsn) {
|
2006-09-27 20:30:12 +00:00
|
|
|
writelock(flushedLSN_lock,1);
|
|
|
|
writelock(globalOffset_lock,1);
|
|
|
|
|
|
|
|
assert(lsn <= nextAvailableLSN);
|
|
|
|
|
|
|
|
|
|
|
|
if(lsn > globalOffset) {
|
|
|
|
for(int i = globalOffset; i < lsn; i++) {
|
|
|
|
free(buffer[i - globalOffset]);
|
|
|
|
}
|
|
|
|
assert((lsn-globalOffset) + (nextAvailableLSN -lsn) < bufferLen);
|
|
|
|
memmove(&(buffer[0]), &(buffer[lsn - globalOffset]), sizeof(LogEntry*) * (nextAvailableLSN - lsn));
|
|
|
|
globalOffset = lsn;
|
|
|
|
}
|
|
|
|
|
|
|
|
writeunlock(globalOffset_lock);
|
|
|
|
writeunlock(flushedLSN_lock);
|
|
|
|
|
|
|
|
return 0;
|
2006-04-12 01:40:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
lsn_t firstLogEntry_InMemoryLog() {
|
|
|
|
return globalOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void close_InMemoryLog() {
|
|
|
|
if(buffer) {
|
|
|
|
lsn_t firstEmptyOffset = nextAvailableLSN-globalOffset;
|
|
|
|
for(lsn_t i = 0; i < firstEmptyOffset; i++) {
|
|
|
|
assert(buffer[i]->LSN == i+globalOffset);
|
|
|
|
free(buffer[i]);
|
|
|
|
}
|
|
|
|
free(buffer);
|
|
|
|
nextAvailableLSN = 0;
|
|
|
|
globalOffset = 0;
|
|
|
|
bufferLen = 0;
|
|
|
|
buffer = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-09-27 20:30:12 +00:00
|
|
|
LogEntry * readLSNEntry_InMemoryLog(lsn_t lsn) {
|
|
|
|
// printf("lsn: %ld\n", lsn);
|
|
|
|
if(lsn >= nextAvailableLSN) { return 0; }
|
|
|
|
assert(lsn-globalOffset >= 0 && lsn-globalOffset< bufferLen);
|
2006-04-12 01:40:47 +00:00
|
|
|
readlock(globalOffset_lock, 0);
|
2006-09-27 20:30:12 +00:00
|
|
|
LogEntry * ptr = buffer[lsn - globalOffset];
|
2006-04-12 01:40:47 +00:00
|
|
|
unlock(globalOffset_lock);
|
|
|
|
assert(ptr);
|
2006-09-27 20:30:12 +00:00
|
|
|
assert(ptr->LSN == lsn);
|
|
|
|
|
|
|
|
LogEntry * ret = malloc(sizeofLogEntry(ptr));
|
|
|
|
|
|
|
|
memcpy(ret, ptr, sizeofLogEntry(ptr));
|
|
|
|
|
2006-04-12 01:40:47 +00:00
|
|
|
//printf("lsn: %ld prevlsn: %ld\n", ptr->LSN, ptr->prevLSN);
|
2006-09-27 20:30:12 +00:00
|
|
|
return ret;
|
2006-04-12 01:40:47 +00:00
|
|
|
}
|
2006-10-04 04:38:21 +00:00
|
|
|
long sizeofInternalLogEntry_InMemoryLog(const LogEntry * e) {
|
|
|
|
abort();
|
|
|
|
}
|