Bugfixes for OASYS.
This commit is contained in:
parent
3b88909c5f
commit
3e5f7aea8a
10 changed files with 116 additions and 18 deletions
|
@ -16,7 +16,7 @@ AC_PROG_LN_S
|
|||
AC_PROG_MAKE_SET
|
||||
## Need AC_PROG_LIBTOOL
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_RANLIB
|
||||
#AC_PROG_RANLIB
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
|
|
|
@ -55,5 +55,5 @@ terms specified in this license.
|
|||
#define __NOOP_H__
|
||||
|
||||
Operation getNoop();
|
||||
|
||||
int noop(int xid, Page *p, lsn_t lsn, recordid rid, const void *dat);
|
||||
#endif
|
||||
|
|
|
@ -73,7 +73,12 @@ void redoUpdate(const LogEntry * e) {
|
|||
|
||||
if(e->LSN > pageLSN) {
|
||||
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 {
|
||||
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) {
|
||||
LogEntry * f = readLSNEntry(e->contents.clr.thisUpdateLSN);
|
||||
recordid rid = f->contents.update.rid;
|
||||
Page * p;
|
||||
try {
|
||||
p = loadPage(e->xid, rid.page);
|
||||
} end;
|
||||
|
||||
assert(rid.page == e->contents.update.rid.page); /* @todo Should this always hold? */
|
||||
Page * p = NULL;
|
||||
|
||||
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
|
||||
doesn't, then undo the original operation. */
|
||||
/* 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);
|
||||
undoUpdate(f, p, e->LSN);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <lladd/operations/noop.h>
|
||||
|
||||
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);
|
||||
bucket.slot = i;
|
||||
Tset(xid, bucket, &rid);
|
||||
// printf("paged list alloced at rid {%d %d %d}\n", rid.page, rid.slot, rid.size);
|
||||
} end_ret(NULLRID);
|
||||
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
byte * entry = calloc(1, lhh.buckets.size);
|
||||
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 valueSize = args->valueSize;
|
||||
|
||||
assert(valueSize >= 0);
|
||||
|
||||
byte * key = (byte*)(args+1);
|
||||
byte * value = ((byte*)(args+1))+ keySize;
|
||||
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 o = {
|
||||
OPERATION_NOOP,
|
||||
// OPERATION_LINEAR_HASH_INSERT,
|
||||
OPERATION_NOOP,
|
||||
SIZEIS_PAGEID,
|
||||
OPERATION_LINEAR_HASH_REMOVE,
|
||||
&operateInsert
|
||||
// &noop
|
||||
};
|
||||
return o;
|
||||
}
|
||||
Operation getLinearHashRemove() {
|
||||
Operation o = {
|
||||
OPERATION_NOOP,
|
||||
// OPERATION_LINEAR_HASH_REMOVE,
|
||||
OPERATION_NOOP,
|
||||
SIZEIS_PAGEID,
|
||||
OPERATION_LINEAR_HASH_INSERT,
|
||||
&operateRemove
|
||||
//&noop
|
||||
};
|
||||
return o;
|
||||
}
|
||||
|
@ -155,7 +164,7 @@ compensated_function int ThashInsert(int xid, recordid hashHeader, const byte* k
|
|||
arg->hashHeader = hashHeader;
|
||||
arg->keySize = keySize;
|
||||
memcpy(arg+1, key, keySize);
|
||||
|
||||
|
||||
int ret;
|
||||
|
||||
/** @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->keySize = keySize;
|
||||
it->valueSize = valueSize;
|
||||
assert(keySize == lhh.keySize);
|
||||
assert(valueSize == lhh.valueSize);
|
||||
if(keySize == VARIABLE_LENGTH || valueSize == VARIABLE_LENGTH) {
|
||||
it->it = NULL;
|
||||
it->pit= TpagedListIterator(xid, it->bucket);
|
||||
recordid bucketList;
|
||||
Tread(xid, it->bucket, &bucketList);
|
||||
it->pit= TpagedListIterator(xid, bucketList);
|
||||
} else {
|
||||
it->pit = NULL;
|
||||
it->it = TlinkedListIterator(xid, it->bucket, it->keySize, it->valueSize);
|
||||
|
|
|
@ -48,7 +48,7 @@ terms specified in this license.
|
|||
#include <lladd/operations.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.
|
||||
Otherwise, write the LSN to the appropriate page (to keep recovery happy)
|
||||
and return */
|
||||
|
@ -61,7 +61,7 @@ Operation getNoop() {
|
|||
OPERATION_NOOP,
|
||||
0,
|
||||
OPERATION_NOOP,
|
||||
&operate
|
||||
&noop
|
||||
};
|
||||
return o;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
pagedListHeader header;
|
||||
assert(list.size == sizeof(pagedListHeader));
|
||||
try_ret(NULL) {
|
||||
Tread(xid, list, &header);
|
||||
} end_ret(NULL);
|
||||
|
@ -206,7 +207,7 @@ compensated_function lladd_pagedList_iterator * TpagedListIterator(int xid, reco
|
|||
it->entryRid = list;
|
||||
// printf("slot <- %d\n", header.thisPage);
|
||||
it->entryRid.slot = header.thisPage;
|
||||
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,15 @@ void setupOperationsTable() {
|
|||
|
||||
operationsTable[OPERATION_LINEAR_HASH_INSERT] = getLinearHashInsert();
|
||||
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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -311,6 +311,53 @@ START_TEST(linearHashNTAIteratortest) {
|
|||
Tdeinit();
|
||||
} 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 *s = suite_create("linearHashNTA");
|
||||
/* Begin a new test */
|
||||
|
@ -318,6 +365,8 @@ Suite * check_suite(void) {
|
|||
|
||||
|
||||
/* 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, linearHashNTAIteratortest);
|
||||
tcase_add_test(tc, linearHashNTAtest);
|
||||
|
|
|
@ -51,6 +51,23 @@ terms specified in this license.
|
|||
#define LOG_NAME "check_pageOrientedListNTA.log"
|
||||
/** @test */
|
||||
#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) {
|
||||
Tinit();
|
||||
|
||||
|
@ -182,6 +199,7 @@ Suite * check_suite(void) {
|
|||
|
||||
/* Sub tests are added, one per line, here */
|
||||
|
||||
tcase_add_test(tc, emptyIterator);
|
||||
tcase_add_test(tc, pagedListCheck);
|
||||
|
||||
/* --------------------------------------------- */
|
||||
|
|
|
@ -482,6 +482,7 @@ START_TEST (recovery_multiple_xacts) {
|
|||
fail_unless(j2 == 2, NULL);
|
||||
fail_unless(j3 == 4, NULL);
|
||||
fail_unless(j4 == 4, NULL);
|
||||
assert(j4 == 4);
|
||||
Tdeinit();
|
||||
} END_TEST
|
||||
|
||||
|
|
Loading…
Reference in a new issue