Bugfixes for OASYS.

This commit is contained in:
Sears Russell 2005-03-01 07:32:02 +00:00
parent 3b88909c5f
commit 3e5f7aea8a
10 changed files with 116 additions and 18 deletions

View file

@ -16,7 +16,7 @@ AC_PROG_LN_S
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
## Need AC_PROG_LIBTOOL ## Need AC_PROG_LIBTOOL
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_PROG_RANLIB #AC_PROG_RANLIB
# Checks for libraries. # Checks for libraries.

View file

@ -55,5 +55,5 @@ terms specified in this license.
#define __NOOP_H__ #define __NOOP_H__
Operation getNoop(); Operation getNoop();
int noop(int xid, Page *p, lsn_t lsn, recordid rid, const void *dat);
#endif #endif

View file

@ -73,7 +73,12 @@ void redoUpdate(const LogEntry * e) {
if(e->LSN > pageLSN) { if(e->LSN > pageLSN) {
DEBUG("OPERATION Redo, %ld > %ld {%d %d %ld}\n", e->LSN, pageLSN, rid.page, rid.slot, rid.size); DEBUG("OPERATION Redo, %ld > %ld {%d %d %ld}\n", e->LSN, pageLSN, rid.page, rid.slot, rid.size);
doUpdate(e, p); // doUpdate(e, p);
// Need to check the id field to find out what the _REDO_ action is for this log type.
// contrast with doUpdate(), which doesn't use the .id field.
operationsTable[operationsTable[e->contents.update.funcID].id]
.run(e->xid, p, e->LSN, e->contents.update.rid, getUpdateArgs(e));
} else { } else {
DEBUG("OPERATION Skipping redo, %ld <= %ld {%d %d %ld}\n", e->LSN, pageLSN, rid.page, rid.slot, rid.size); DEBUG("OPERATION Skipping redo, %ld <= %ld {%d %d %ld}\n", e->LSN, pageLSN, rid.page, rid.slot, rid.size);
} }
@ -82,17 +87,20 @@ void redoUpdate(const LogEntry * e) {
} else if(e->type == CLRLOG) { } else if(e->type == CLRLOG) {
LogEntry * f = readLSNEntry(e->contents.clr.thisUpdateLSN); LogEntry * f = readLSNEntry(e->contents.clr.thisUpdateLSN);
recordid rid = f->contents.update.rid; recordid rid = f->contents.update.rid;
Page * p; Page * p = NULL;
try {
p = loadPage(e->xid, rid.page);
} end;
assert(rid.page == e->contents.update.rid.page); /* @todo Should this always hold? */
int isNullRid = !memcmp(&rid, &NULLRID, sizeof(recordid));
if(!isNullRid) {
try {
p = loadPage(e->xid, rid.page);
} end;
}
// assert(rid.page == e->contents.update.rid.page); /* @todo Should this always hold? */
/* See if the page contains the result of the undo that this CLR is supposed to perform. If it /* See if the page contains the result of the undo that this CLR is supposed to perform. If it
doesn't, then undo the original operation. */ doesn't, then undo the original operation. */
/* if(f->LSN > pageReadLSN(e->contents.update.rid.page)) { */ /* if(f->LSN > pageReadLSN(e->contents.update.rid.page)) { */
if(f->LSN > pageReadLSN(p)) { if(isNullRid || f->LSN > pageReadLSN(p)) {
DEBUG("OPERATION Undoing for clr, %ld {%d %d %ld}\n", f->LSN, rid.page, rid.slot, rid.size); DEBUG("OPERATION Undoing for clr, %ld {%d %d %ld}\n", f->LSN, rid.page, rid.slot, rid.size);
undoUpdate(f, p, e->LSN); undoUpdate(f, p, e->LSN);

View file

@ -8,6 +8,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <lladd/operations/noop.h>
static pthread_mutex_t linear_hash_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; static pthread_mutex_t linear_hash_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
@ -60,9 +61,11 @@ compensated_function recordid ThashCreate(int xid, int keySize, int valueSize) {
recordid rid = TpagedListAlloc(xid); recordid rid = TpagedListAlloc(xid);
bucket.slot = i; bucket.slot = i;
Tset(xid, bucket, &rid); Tset(xid, bucket, &rid);
// printf("paged list alloced at rid {%d %d %d}\n", rid.page, rid.slot, rid.size);
} end_ret(NULLRID); } end_ret(NULLRID);
} }
} else { } else {
byte * entry = calloc(1, lhh.buckets.size); byte * entry = calloc(1, lhh.buckets.size);
for(i = 0; i < HASH_INIT_ARRAY_LIST_COUNT; i++) { for(i = 0; i < HASH_INIT_ARRAY_LIST_COUNT; i++) {
@ -108,6 +111,8 @@ compensated_function static int operateInsert(int xid, Page *p, lsn_t lsn, reco
int keySize = args->keySize; int keySize = args->keySize;
int valueSize = args->valueSize; int valueSize = args->valueSize;
assert(valueSize >= 0);
byte * key = (byte*)(args+1); byte * key = (byte*)(args+1);
byte * value = ((byte*)(args+1))+ keySize; byte * value = ((byte*)(args+1))+ keySize;
begin_action_ret(pthread_mutex_unlock, &linear_hash_mutex, compensation_error()) { begin_action_ret(pthread_mutex_unlock, &linear_hash_mutex, compensation_error()) {
@ -131,19 +136,23 @@ compensated_function static int operateRemove(int xid, Page *p, lsn_t lsn, reco
} }
Operation getLinearHashInsert() { Operation getLinearHashInsert() {
Operation o = { Operation o = {
OPERATION_NOOP, // OPERATION_LINEAR_HASH_INSERT,
OPERATION_NOOP,
SIZEIS_PAGEID, SIZEIS_PAGEID,
OPERATION_LINEAR_HASH_REMOVE, OPERATION_LINEAR_HASH_REMOVE,
&operateInsert &operateInsert
// &noop
}; };
return o; return o;
} }
Operation getLinearHashRemove() { Operation getLinearHashRemove() {
Operation o = { Operation o = {
OPERATION_NOOP, // OPERATION_LINEAR_HASH_REMOVE,
OPERATION_NOOP,
SIZEIS_PAGEID, SIZEIS_PAGEID,
OPERATION_LINEAR_HASH_INSERT, OPERATION_LINEAR_HASH_INSERT,
&operateRemove &operateRemove
//&noop
}; };
return o; return o;
} }
@ -155,7 +164,7 @@ compensated_function int ThashInsert(int xid, recordid hashHeader, const byte* k
arg->hashHeader = hashHeader; arg->hashHeader = hashHeader;
arg->keySize = keySize; arg->keySize = keySize;
memcpy(arg+1, key, keySize); memcpy(arg+1, key, keySize);
int ret; int ret;
/** @todo MEMORY LEAK arg, handle on pthread_cancel.. */ /** @todo MEMORY LEAK arg, handle on pthread_cancel.. */
@ -387,9 +396,13 @@ lladd_hash_iterator * ThashIterator(int xid, recordid hashHeader, int keySize, i
it->bucket.slot = 0; it->bucket.slot = 0;
it->keySize = keySize; it->keySize = keySize;
it->valueSize = valueSize; it->valueSize = valueSize;
assert(keySize == lhh.keySize);
assert(valueSize == lhh.valueSize);
if(keySize == VARIABLE_LENGTH || valueSize == VARIABLE_LENGTH) { if(keySize == VARIABLE_LENGTH || valueSize == VARIABLE_LENGTH) {
it->it = NULL; it->it = NULL;
it->pit= TpagedListIterator(xid, it->bucket); recordid bucketList;
Tread(xid, it->bucket, &bucketList);
it->pit= TpagedListIterator(xid, bucketList);
} else { } else {
it->pit = NULL; it->pit = NULL;
it->it = TlinkedListIterator(xid, it->bucket, it->keySize, it->valueSize); it->it = TlinkedListIterator(xid, it->bucket, it->keySize, it->valueSize);

View file

@ -48,7 +48,7 @@ terms specified in this license.
#include <lladd/operations.h> #include <lladd/operations.h>
#include "../page.h" #include "../page.h"
static int operate(int xid, Page *p, lsn_t lsn, recordid rid, const void *dat) { int noop(int xid, Page *p, lsn_t lsn, recordid rid, const void *dat) {
/* If p is null, then this is a logical no-op that spans pages, so do nothing. /* If p is null, then this is a logical no-op that spans pages, so do nothing.
Otherwise, write the LSN to the appropriate page (to keep recovery happy) Otherwise, write the LSN to the appropriate page (to keep recovery happy)
and return */ and return */
@ -61,7 +61,7 @@ Operation getNoop() {
OPERATION_NOOP, OPERATION_NOOP,
0, 0,
OPERATION_NOOP, OPERATION_NOOP,
&operate &noop
}; };
return o; return o;
} }

View file

@ -196,6 +196,7 @@ compensated_function int TpagedListMove(int xid, recordid start_list, recordid e
compensated_function lladd_pagedList_iterator * TpagedListIterator(int xid, recordid list) { compensated_function lladd_pagedList_iterator * TpagedListIterator(int xid, recordid list) {
pagedListHeader header; pagedListHeader header;
assert(list.size == sizeof(pagedListHeader));
try_ret(NULL) { try_ret(NULL) {
Tread(xid, list, &header); Tread(xid, list, &header);
} end_ret(NULL); } end_ret(NULL);
@ -206,7 +207,7 @@ compensated_function lladd_pagedList_iterator * TpagedListIterator(int xid, reco
it->entryRid = list; it->entryRid = list;
// printf("slot <- %d\n", header.thisPage); // printf("slot <- %d\n", header.thisPage);
it->entryRid.slot = header.thisPage; it->entryRid.slot = header.thisPage;
return it; return it;
} }

View file

@ -78,7 +78,15 @@ void setupOperationsTable() {
operationsTable[OPERATION_LINEAR_HASH_INSERT] = getLinearHashInsert(); operationsTable[OPERATION_LINEAR_HASH_INSERT] = getLinearHashInsert();
operationsTable[OPERATION_LINEAR_HASH_REMOVE] = getLinearHashRemove(); operationsTable[OPERATION_LINEAR_HASH_REMOVE] = getLinearHashRemove();
int i;
/* for(i = 0; i <= OPERATION_LINEAR_HASH_REMOVE; i++) {
if(operationsTable[i].id != i) {
printf("mismatch %d -> %d\n", i, operationsTable[i].id);
}
}
*/
} }

View file

@ -311,6 +311,53 @@ START_TEST(linearHashNTAIteratortest) {
Tdeinit(); Tdeinit();
} END_TEST } END_TEST
START_TEST(emptyHashIterator) {
Tinit();
int xid = Tbegin();
recordid hash = ThashCreate(xid, sizeof(int), sizeof(recordid));
lladd_hash_iterator * it = ThashIterator(xid, hash, sizeof(int), sizeof(recordid));
byte * key;
byte * value;
int keySize;
int valueSize;
while(ThashNext(xid, it, &key, &keySize, &value, &valueSize)) {
abort();
}
Tabort(xid);
Tdeinit();
} END_TEST
START_TEST(emptyHashIterator2) {
Tinit();
int xid = Tbegin();
recordid hash = ThashCreate(xid, sizeof(int), VARIABLE_LENGTH);
lladd_hash_iterator * it = ThashIterator(xid, hash, sizeof(int), VARIABLE_LENGTH);
byte * key;
byte * value;
int keySize;
int valueSize;
while(ThashNext(xid, it, &key, &keySize, &value, &valueSize)) {
abort();
}
Tabort(xid);
Tdeinit();
} END_TEST
Suite * check_suite(void) { Suite * check_suite(void) {
Suite *s = suite_create("linearHashNTA"); Suite *s = suite_create("linearHashNTA");
/* Begin a new test */ /* Begin a new test */
@ -318,6 +365,8 @@ Suite * check_suite(void) {
/* Sub tests are added, one per line, here */ /* Sub tests are added, one per line, here */
tcase_add_test(tc, emptyHashIterator);
tcase_add_test(tc, emptyHashIterator2);
tcase_add_test(tc, linearHashNTAVariableSizetest); tcase_add_test(tc, linearHashNTAVariableSizetest);
tcase_add_test(tc, linearHashNTAIteratortest); tcase_add_test(tc, linearHashNTAIteratortest);
tcase_add_test(tc, linearHashNTAtest); tcase_add_test(tc, linearHashNTAtest);

View file

@ -51,6 +51,23 @@ terms specified in this license.
#define LOG_NAME "check_pageOrientedListNTA.log" #define LOG_NAME "check_pageOrientedListNTA.log"
/** @test */ /** @test */
#define NUM_ENTRIES 3000 #define NUM_ENTRIES 3000
START_TEST(emptyIterator) {
Tinit();
int xid = Tbegin();
recordid list = TpagedListAlloc(xid);
lladd_pagedList_iterator * it = TpagedListIterator(xid, list);
int keySize;
int valueSize;
int * key = 0;
recordid * value = 0;
while(TpagedListNext(xid, it, (byte**)&key, &keySize, (byte**)&value, &valueSize)) {
abort();
}
Tcommit(xid);
} END_TEST
START_TEST(pagedListCheck) { START_TEST(pagedListCheck) {
Tinit(); Tinit();
@ -182,6 +199,7 @@ Suite * check_suite(void) {
/* Sub tests are added, one per line, here */ /* Sub tests are added, one per line, here */
tcase_add_test(tc, emptyIterator);
tcase_add_test(tc, pagedListCheck); tcase_add_test(tc, pagedListCheck);
/* --------------------------------------------- */ /* --------------------------------------------- */

View file

@ -482,6 +482,7 @@ START_TEST (recovery_multiple_xacts) {
fail_unless(j2 == 2, NULL); fail_unless(j2 == 2, NULL);
fail_unless(j3 == 4, NULL); fail_unless(j3 == 4, NULL);
fail_unless(j4 == 4, NULL); fail_unless(j4 == 4, NULL);
assert(j4 == 4);
Tdeinit(); Tdeinit();
} END_TEST } END_TEST