From 55b0ddf1b676d0c67d92f93084bb1bdddd58602c Mon Sep 17 00:00:00 2001 From: Sears Russell Date: Mon, 6 Dec 2004 01:20:48 +0000 Subject: [PATCH] Fixed nasty bug that was causing the LLADD header to be lost (!!) --- src/lladd/bufferManager.c | 2 +- src/lladd/operations/alloc.c | 8 +-- src/lladd/operations/pageOperations.c | 86 ++++++++++++++++----------- src/lladd/page/slotted.c | 13 ++-- test/lladd/Makefile.am | 2 +- test/lladd/check_operations.c | 38 ++++++++++-- 6 files changed, 100 insertions(+), 49 deletions(-) diff --git a/src/lladd/bufferManager.c b/src/lladd/bufferManager.c index d2e445e..2cbbcd2 100644 --- a/src/lladd/bufferManager.c +++ b/src/lladd/bufferManager.c @@ -103,7 +103,7 @@ void bufDeinit() { for( p = (Page*)pblHtFirst( activePages ); p; p = (Page*)pblHtNext(activePages)) { - pblHtRemove( activePages, 0, 0 ); +// pblHtRemove( activePages, 0, 0 ); DEBUG("+"); /** @todo No one seems to set the dirty flag... */ /*if(p->dirty && (ret = pageWrite(p)/ *flushPage(*p)* /)) { diff --git a/src/lladd/operations/alloc.c b/src/lladd/operations/alloc.c index 684cf53..c79ddc1 100644 --- a/src/lladd/operations/alloc.c +++ b/src/lladd/operations/alloc.c @@ -35,12 +35,12 @@ static int operate(int xid, Page * p, lsn_t lsn, recordid rid, const void * dat) { /* * @ todo Currently, Talloc() needs to clean up the page type (for recovery). Should this be elsewhere? */ - /* if(*page_type_ptr(p) == UNINITIALIZED_PAGE) { + /* if(*page_type_ptr(p) == UNINITIALIZED_PAGE) { *page_type_ptr(p) = SLOTTED_PAGE; - } */ - - /* assert(*page_type_ptr(p) == SLOTTED_PAGE); */ + } + assert(*page_type_ptr(p) == SLOTTED_PAGE); */ + if(rid.size >= BLOB_THRESHOLD_SIZE) { allocBlob(xid, p, lsn, rid); } else { diff --git a/src/lladd/operations/pageOperations.c b/src/lladd/operations/pageOperations.c index 3db95cf..015cc91 100644 --- a/src/lladd/operations/pageOperations.c +++ b/src/lladd/operations/pageOperations.c @@ -8,7 +8,9 @@ #include "../page/header.h" #include "../pageFile.h" +#ifdef REUSE_PAGES static int freelist; +#endif static int freepage; static pthread_mutex_t pageAllocMutex; @@ -41,11 +43,11 @@ typedef struct { int after; } update_tuple; -int __update_freespace(int xid, Page * p, lsn_t lsn, recordid r, const void * d) { +int __update_freepage(int xid, Page * p, lsn_t lsn, recordid r, const void * d) { assert(r.page == 0); const update_tuple * t = d; - /* printf("freespace %d -> %d\n", t->before, t->after); - fflush(NULL); */ + /* printf("freepage %d -> %d\n", t->before, t->after); + fflush(NULL); */ * headerFreepage_ptr(p) = t->after; freepage = t->after; pageWriteLSN(p, lsn); @@ -56,8 +58,8 @@ int __update_freespace_inverse(int xid, Page * p, lsn_t lsn, recordid r, const v #ifdef REUSE_PAGES assert(r.page == 0); const update_tuple * t = d; - /* printf("freespace %d <- %d\n", t->before, t->after); - fflush(NULL); */ +/* ("freespace %d <- %d\n", t->before, t->after); + fflush(NULL); */ * headerFreepage_ptr(p) = t->before; freepage = t->before; @@ -65,6 +67,7 @@ int __update_freespace_inverse(int xid, Page * p, lsn_t lsn, recordid r, const v pageWriteLSN(p, lsn); return 0; } +#ifdef REUSE_PAGES /** @todo need to hold mutex here... */ int __update_freelist(int xid, Page * p, lsn_t lsn, recordid r, const void * d) { assert(r.page == 0); @@ -72,7 +75,7 @@ int __update_freelist(int xid, Page * p, lsn_t lsn, recordid r, const void * d) const update_tuple * t = d; /* printf("freelist %d -> %d\n", t->before, t->after); - fflush(NULL); */ + fflush(NULL); */ * headerFreepagelist_ptr(p) = t->after; freelist = t->after; @@ -83,19 +86,19 @@ int __update_freelist_inverse(int xid, Page * p, lsn_t lsn, recordid r, const vo assert(r.page == 0); const update_tuple * t = d; - /* printf("freelist %d <- %d\n", t->before, t->after); - fflush(NULL); */ +/* printf("freelist %d <- %d\n", t->before, t->after); + fflush(NULL); */ * headerFreepagelist_ptr(p) = t->before; freelist = t->before; pageWriteLSN(p, lsn); return 0; } - +#endif int __free_page(int xid, Page * p, lsn_t lsn, recordid r, const void * d) { const int * successor = d; - /* printf("Unallocing page %d\n", r.page); - fflush(NULL); */ + /*printf("Unallocing page %d\n", r.page); + fflush(NULL); */ memset(p->memAddr, 0, PAGE_SIZE); *page_type_ptr(p) = LLADD_FREE_PAGE; *nextfreepage_ptr(p) = *successor; @@ -130,28 +133,35 @@ int TpageSet(int xid, int pageid, byte * memAddr) { since it needs to perform raw, synchronous I/O on the pagefile for bootstrapping purposes. */ void pageOperationsInit() { - Page p; +/* Page p; p.rwlatch = initlock(); p.loadlatch = initlock(); assert(!posix_memalign((void **)&(p.memAddr), PAGE_SIZE, PAGE_SIZE)); - p.id = 0; + p.id = 0;*/ - pageRead(&p); + Page * p = loadPage(0); + + // pageRead(&p); - if(*page_type_ptr(&p) != LLADD_HEADER_PAGE) { - headerPageInitialize(&p); - pageWrite(&p); + if(*page_type_ptr(p) != LLADD_HEADER_PAGE) { + /*printf("Writing new LLADD header\n"); fflush(NULL); */ + headerPageInitialize(p); + // pageWrite(p); + } else { + /*printf("Found LLADD header.\n"); fflush(NULL);*/ } - - freelist = *headerFreepagelist_ptr(&p); - freepage = *headerFreepage_ptr(&p); +#ifdef REUSE_PAGES + freelist = *headerFreepagelist_ptr(p); +#endif + freepage = *headerFreepage_ptr(p); assert(freepage); /* free(p.memAddr); */ - deletelock(p.loadlatch); - deletelock(p.rwlatch); + //deletelock(p.loadlatch); + //deletelock(p.rwlatch); + releasePage(p); pthread_mutex_init(&pageAllocMutex, NULL); @@ -208,12 +218,12 @@ int TpageDealloc(int xid, int pageid) { t.before = freelist; -#endif +//#endif Tupdate(xid, rid, &freelist, OPERATION_FREE_PAGE); -#ifdef REUSE_PAGES +//#ifdef REUSE_PAGES t.after = pageid; freelist = pageid; @@ -238,6 +248,7 @@ int TpageAlloc(int xid /*, int type */) { pthread_mutex_lock(&pageAllocMutex); int newpage; + /*printf("TpageAlloc\n"); fflush(NULL); */ #ifdef REUSE_PAGES if(freelist) { @@ -267,14 +278,16 @@ int TpageAlloc(int xid /*, int type */) { } else { #endif - /* printf("Allocing new page: %d\n", freepage); - fflush(NULL); */ + /*printf("Allocing new page: %d\n", freepage); + fflush(NULL); */ t.before = freepage; newpage = freepage; freepage++; t.after = freepage; - /* Don't need to touch the new page. */ + + /*printf("next freepage: %d\n", freepage); */ + /* Don't need to touch the new page. */ rid.page = 0; Tupdate(xid, rid, &t, OPERATION_UPDATE_FREESPACE); @@ -285,7 +298,7 @@ int TpageAlloc(int xid /*, int type */) { #endif pthread_mutex_unlock(&pageAllocMutex); - + /*printf("TpageAlloc alloced page %d\n", newpage); fflush(NULL); */ return newpage; } @@ -344,7 +357,7 @@ Operation getUpdateFreespace() { OPERATION_UPDATE_FREESPACE, sizeof(update_tuple), /* OPERATION_UPDATE_FREESPACE_INVERSE, */ OPERATION_NOOP, - &__update_freespace + &__update_freepage }; return o; } @@ -359,14 +372,17 @@ Operation getUpdateFreespaceInverse() { return o; } - Operation getUpdateFreelist() { Operation o = { OPERATION_UPDATE_FREELIST, sizeof(update_tuple), OPERATION_NOOP, +#ifdef REUSE_PAGES &__update_freelist - }; +#else + NULL +#endif + }; return o; } @@ -375,8 +391,12 @@ Operation getUpdateFreelistInverse() { OPERATION_UPDATE_FREELIST_INVERSE, sizeof(update_tuple), OPERATION_UPDATE_FREELIST, +#ifdef REUSE_PAGES &__update_freelist_inverse - }; +#else + NULL +#endif + }; return o; } @@ -447,5 +467,3 @@ Operation getPageSet() { }; return o; } - - diff --git a/src/lladd/page/slotted.c b/src/lladd/page/slotted.c index f4a085f..e81af54 100644 --- a/src/lladd/page/slotted.c +++ b/src/lladd/page/slotted.c @@ -44,7 +44,7 @@ static void slottedCompact(Page * page) { numSlots = *numslots_ptr(page); for (i = 0; i < numSlots; i++) { - /* printf("i = %d\n", i); */ + /* ("i = %d\n", i); */ if (isValidSlot(page, i)) { /* printf("copying %d\n", i); fflush(NULL); */ @@ -115,7 +115,7 @@ static void slottedCompact(Page * page) { /*static pthread_mutex_t lastFreepage_mutex; */ - static unsigned int lastFreepage = -1; + static unsigned int lastFreepage = -10; void slottedPageInit() { /*pthread_mutex_init(&lastFreepage_mutex , NULL); */ @@ -128,8 +128,8 @@ void slottedPageDeinit() { void slottedPageInitialize(Page * page) { - /* printf("Initializing page %d\n", page->id); - fflush(NULL); */ + /*printf("Initializing page %d\n", page->id); + fflush(NULL); */ memset(page->memAddr, 0, PAGE_SIZE); *page_type_ptr(page) = SLOTTED_PAGE; *freespace_ptr(page) = 0; @@ -168,9 +168,11 @@ recordid slottedPreRalloc(int xid, long size, Page ** pp) { /* pthread_mutex_lock(&lastFreepage_mutex); */ /** @todo is ((unsigned int) foo) == -1 portable? Gotta love C.*/ + /*printf("lastFreepage %d\n", lastFreepage); fflush(NULL); */ if(lastFreepage == -1) { lastFreepage = TpageAlloc(xid/*, SLOTTED_PAGE*/); *pp = loadPage(lastFreepage); + assert(*page_type_ptr(*pp) == UNINITIALIZED_PAGE); slottedPageInitialize(*pp); } else { *pp = loadPage(lastFreepage); @@ -206,7 +208,8 @@ recordid slottedRawRalloc(Page * page, int size) { rid.slot = *numslots_ptr(page); rid.size = size; - /* new way */ + /* new way - The freelist_ptr points to the first free slot number, which + is the head of a linked list of free slot numbers.*/ if(*freelist_ptr(page) != INVALID_SLOT) { rid.slot = *freelist_ptr(page); *freelist_ptr(page) = *slot_length_ptr(page, rid.slot); diff --git a/test/lladd/Makefile.am b/test/lladd/Makefile.am index 6198a76..b9983cb 100644 --- a/test/lladd/Makefile.am +++ b/test/lladd/Makefile.am @@ -1,7 +1,7 @@ INCLUDES = @CHECK_CFLAGS@ if HAVE_CHECK ## Had to disable check_lht because lht needs to be rewritten. -TESTS = check_logEntry check_logWriter check_page check_operations check_transactional2 check_recovery check_blobRecovery check_bufferManager check_indirect check_lladdhash check_pageOperations check_linearHash check_logicalLinearHash +TESTS = check_logEntry check_logWriter check_page check_operations check_transactional2 check_recovery check_blobRecovery check_bufferManager check_indirect check_lladdhash check_pageOperations check_linearHash check_logicalLinearHash check_header else TESTS = endif diff --git a/test/lladd/check_operations.c b/test/lladd/check_operations.c index e45f393..8c86f1b 100644 --- a/test/lladd/check_operations.c +++ b/test/lladd/check_operations.c @@ -339,21 +339,30 @@ START_TEST(operation_nestedTopAction) { int xid= Tbegin(); int *dat; - dat == malloc(sizeof(int)); + //printf("W"); fflush(NULL); + dat = malloc(sizeof(int)); recordid rid1 = Talloc(xid, sizeof(int)); + // printf("{%d,%d,%d}\n", rid1.page, rid1.slot, rid1.size); fflush(NULL); recordid rid2 = Talloc(xid, sizeof(int)); + // printf("{%d,%d,%d}\n", rid2.page, rid2.slot, rid2.size); fflush(NULL); recordid rid3 = Talloc(xid, sizeof(int)); +// printf("{%d,%d,%d}\n", rid3.page, rid3.slot, rid3.size); fflush(NULL); recordid rid4 = Talloc(xid, sizeof(int)); + //printf("{%d,%d,%d}\n", rid4.page, rid4.slot, rid4.size); fflush(NULL); + // printf("E"); fflush(NULL); *dat = 1; Tset(xid, rid1, dat); *dat = 2; Tset(xid, rid2, dat); + // printf("F"); fflush(NULL); *dat = 3; Tset(xid, rid3, dat); + // printf("G"); fflush(NULL); *dat = 4; Tset(xid, rid4, dat); + // printf("H"); fflush(NULL); Tcommit(xid); - + // printf("A"); fflush(NULL); xid = Tbegin(); // Loser xact. *dat = 10; @@ -367,7 +376,7 @@ START_TEST(operation_nestedTopAction) { Tset(xid, rid3, dat); TendNestedTopAction(xid); - + // printf("B"); fflush(NULL); *dat = 40; Tset(xid, rid4, dat); @@ -379,7 +388,7 @@ START_TEST(operation_nestedTopAction) { int dat2; int dat3; int dat4; - + // printf("C"); fflush(NULL); Tread(xid, rid1, &dat1); Tread(xid, rid2, &dat2); Tread(xid, rid3, &dat3); @@ -505,6 +514,26 @@ START_TEST(operation_set_range) { Tcommit(xid); } END_TEST + +START_TEST(operation_alloc_test) { + Tinit(); + + int xid = Tbegin(); + recordid rid1 = Talloc(xid, 100); + Tcommit(xid); + xid = Tbegin(); + recordid rid2 = Talloc(xid, 100); + Tcommit(xid); + + printf("rid1={%d,%d,%d} rid2={%d,%d,%d}\n", + rid1.page, rid1.slot, rid1.size, + rid2.page, rid2.slot, rid2.size); + + + + Tdeinit(); +} END_TEST + #define ARRAY_LIST_CHECK_ITER 10000 START_TEST(operation_array_list) { @@ -602,6 +631,7 @@ Suite * check_suite(void) { tcase_add_test(tc, operation_instant_set); tcase_add_test(tc, operation_set_range); tcase_add_test(tc, operation_prepare); + tcase_add_test(tc, operation_alloc_test); tcase_add_test(tc, operation_array_list); /* --------------------------------------------- */ tcase_add_checked_fixture(tc, setup, teardown);