more refactoring; removed static variables from pageHandle.c
This commit is contained in:
parent
a0dd692b2c
commit
651a1a22e5
23 changed files with 264 additions and 222 deletions
|
@ -3,7 +3,7 @@ This software is copyrighted by the Regents of the University of
|
||||||
California, and other parties. The following terms apply to all files
|
California, and other parties. The following terms apply to all files
|
||||||
associated with the software unless explicitly disclaimed in
|
associated with the software unless explicitly disclaimed in
|
||||||
individual files.
|
individual files.
|
||||||
|
|
||||||
The authors hereby grant permission to use, copy, modify, distribute,
|
The authors hereby grant permission to use, copy, modify, distribute,
|
||||||
and license this software and its documentation for any purpose,
|
and license this software and its documentation for any purpose,
|
||||||
provided that existing copyright notices are retained in all copies
|
provided that existing copyright notices are retained in all copies
|
||||||
|
@ -13,20 +13,20 @@ authorized uses. Modifications to this software may be copyrighted by
|
||||||
their authors and need not follow the licensing terms described here,
|
their authors and need not follow the licensing terms described here,
|
||||||
provided that the new terms are clearly indicated on the first page of
|
provided that the new terms are clearly indicated on the first page of
|
||||||
each file where they apply.
|
each file where they apply.
|
||||||
|
|
||||||
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
||||||
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
||||||
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||||||
NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
|
NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
|
||||||
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
|
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
|
||||||
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
|
||||||
GOVERNMENT USE: If you are acquiring this software on behalf of the
|
GOVERNMENT USE: If you are acquiring this software on behalf of the
|
||||||
U.S. government, the Government shall have only "Restricted Rights" in
|
U.S. government, the Government shall have only "Restricted Rights" in
|
||||||
the software and related documentation as defined in the Federal
|
the software and related documentation as defined in the Federal
|
||||||
|
@ -51,7 +51,7 @@ terms specified in this license.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h> // Need _GNU_SOURCE for asprintf
|
#include <stdio.h> // Need _GNU_SOURCE for asprintf
|
||||||
#include <stasis/lhtable.h>
|
#include <stasis/lhtable.h>
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ terms specified in this license.
|
||||||
#undef releasePage
|
#undef releasePage
|
||||||
#undef Page
|
#undef Page
|
||||||
|
|
||||||
#ifdef LONG_TEST
|
#ifdef LONG_TEST
|
||||||
#define PIN_COUNT
|
#define PIN_COUNT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ int pinCount = 0;
|
||||||
|
|
||||||
#ifdef PROFILE_LATCHES_WRITE_ONLY
|
#ifdef PROFILE_LATCHES_WRITE_ONLY
|
||||||
|
|
||||||
compensated_function Page * __profile_loadPage(int xid, pageid_t pageid, char * file, int line) {
|
compensated_function Page * __profile_loadPage(int xid, pageid_t pageid, char * file, int line) {
|
||||||
|
|
||||||
Page * ret = loadPage(xid, pageid);
|
Page * ret = loadPage(xid, pageid);
|
||||||
|
|
||||||
|
@ -111,19 +111,19 @@ compensated_function Page * __profile_loadPage(int xid, pageid_t pageid, char *
|
||||||
char * holder = LH_ENTRY(find)(profile_load_hash, &ret, sizeof(void*));
|
char * holder = LH_ENTRY(find)(profile_load_hash, &ret, sizeof(void*));
|
||||||
int * pins = LH_ENTRY(find)(profile_load_pins_hash, &ret, sizeof(void*));
|
int * pins = LH_ENTRY(find)(profile_load_pins_hash, &ret, sizeof(void*));
|
||||||
|
|
||||||
if(!pins) {
|
if(!pins) {
|
||||||
pins = malloc(sizeof(int));
|
pins = malloc(sizeof(int));
|
||||||
*pins = 0;
|
*pins = 0;
|
||||||
LH_ENTRY(insert)(profile_load_pins_hash, &ret, sizeof(void*), pins);
|
LH_ENTRY(insert)(profile_load_pins_hash, &ret, sizeof(void*), pins);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*pins) {
|
if(*pins) {
|
||||||
assert(holder);
|
assert(holder);
|
||||||
char * newHolder;
|
char * newHolder;
|
||||||
asprintf(&newHolder, "%s\n%s:%d", holder, file, line);
|
asprintf(&newHolder, "%s\n%s:%d", holder, file, line);
|
||||||
free(holder);
|
free(holder);
|
||||||
holder = newHolder;
|
holder = newHolder;
|
||||||
} else {
|
} else {
|
||||||
assert(!holder);
|
assert(!holder);
|
||||||
asprintf(&holder, "%s:%d", file, line);
|
asprintf(&holder, "%s:%d", file, line);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ compensated_function Page * __profile_loadPage(int xid, pageid_t pageid, char *
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
compensated_function void __profile_releasePage(Page * p) {
|
compensated_function void __profile_releasePage(Page * p) {
|
||||||
pthread_mutex_lock(&profile_load_mutex);
|
pthread_mutex_lock(&profile_load_mutex);
|
||||||
|
|
||||||
// int pageid = p->id;
|
// int pageid = p->id;
|
||||||
|
@ -145,10 +145,10 @@ compensated_function void __profile_releasePage(Page * p) {
|
||||||
assert(pins);
|
assert(pins);
|
||||||
|
|
||||||
if(*pins == 1) {
|
if(*pins == 1) {
|
||||||
|
|
||||||
char * holder = LH_ENTRY(remove)(profile_load_hash, &p, sizeof(void*));
|
char * holder = LH_ENTRY(remove)(profile_load_hash, &p, sizeof(void*));
|
||||||
assert(holder);
|
assert(holder);
|
||||||
free(holder);
|
free(holder);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ void (*forcePageRange)(pageid_t start, pageid_t stop) = 0;
|
||||||
void (*stasis_buffer_manager_close)() = 0;
|
void (*stasis_buffer_manager_close)() = 0;
|
||||||
void (*stasis_buffer_manager_simulate_crash)() = 0;
|
void (*stasis_buffer_manager_simulate_crash)() = 0;
|
||||||
|
|
||||||
Page * loadPage(int xid, pageid_t pageid) {
|
Page * loadPage(int xid, pageid_t pageid) {
|
||||||
try_ret(NULL) {
|
try_ret(NULL) {
|
||||||
// This lock is released at Tcommit()
|
// This lock is released at Tcommit()
|
||||||
if(globalLockManager.readLockPage) { globalLockManager.readLockPage(xid, pageid); }
|
if(globalLockManager.readLockPage) { globalLockManager.readLockPage(xid, pageid); }
|
||||||
|
@ -181,7 +181,7 @@ Page * loadPage(int xid, pageid_t pageid) {
|
||||||
return loadPageImpl(xid, pageid);
|
return loadPageImpl(xid, pageid);
|
||||||
|
|
||||||
}
|
}
|
||||||
Page * loadUninitializedPage(int xid, pageid_t pageid) {
|
Page * loadUninitializedPage(int xid, pageid_t pageid) {
|
||||||
try_ret(NULL) {
|
try_ret(NULL) {
|
||||||
// This lock is released at Tcommit()
|
// This lock is released at Tcommit()
|
||||||
if(globalLockManager.readLockPage) { globalLockManager.readLockPage(xid, pageid); }
|
if(globalLockManager.readLockPage) { globalLockManager.readLockPage(xid, pageid); }
|
||||||
|
@ -195,24 +195,25 @@ void releasePage(Page * p) {
|
||||||
releasePageImpl(p);
|
releasePageImpl(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stasis_buffer_manager_open(int type) {
|
int stasis_buffer_manager_open(int type, stasis_page_handle_t * ph) {
|
||||||
bufferManagerType = type;
|
bufferManagerType = type;
|
||||||
static int lastType = 0;
|
static int lastType = 0;
|
||||||
if(type == BUFFER_MANAGER_REOPEN) {
|
if(type == BUFFER_MANAGER_REOPEN) {
|
||||||
type = lastType;
|
type = lastType;
|
||||||
}
|
}
|
||||||
lastType = type;
|
lastType = type;
|
||||||
if(type == BUFFER_MANAGER_DEPRECATED_HASH) {
|
if(type == BUFFER_MANAGER_DEPRECATED_HASH) {
|
||||||
stasis_buffer_manager_deprecated_open();
|
stasis_buffer_manager_deprecated_open(ph);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (type == BUFFER_MANAGER_MEM_ARRAY) {
|
} else if (type == BUFFER_MANAGER_MEM_ARRAY) {
|
||||||
stasis_buffer_manager_mem_array_open();
|
stasis_buffer_manager_mem_array_open();
|
||||||
|
ph->close(ph); // XXX should never have been opened in the first place!
|
||||||
return 0;
|
return 0;
|
||||||
} else if (type == BUFFER_MANAGER_HASH) {
|
} else if (type == BUFFER_MANAGER_HASH) {
|
||||||
stasis_buffer_manager_hash_open();
|
stasis_buffer_manager_hash_open(ph);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// XXX error handling
|
// XXX error handling
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ static replacementPolicy * lru;
|
||||||
|
|
||||||
static stasis_buffer_pool_t * stasis_buffer_pool;
|
static stasis_buffer_pool_t * stasis_buffer_pool;
|
||||||
|
|
||||||
|
static stasis_page_handle_t * page_handle;
|
||||||
|
|
||||||
static int running;
|
static int running;
|
||||||
|
|
||||||
typedef struct LL_ENTRY(node_t) node_t;
|
typedef struct LL_ENTRY(node_t) node_t;
|
||||||
|
@ -110,7 +112,7 @@ inline static Page * writeBackOnePage() {
|
||||||
assert(old == victim);
|
assert(old == victim);
|
||||||
|
|
||||||
// printf("Write(%ld)\n", (long)victim->id);
|
// printf("Write(%ld)\n", (long)victim->id);
|
||||||
pageWrite(victim); /// XXX pageCleanup and pageFlushed might be heavyweight.
|
page_handle->write(page_handle,victim); /// XXX pageCleanup and pageFlushed might be heavyweight.
|
||||||
stasis_page_cleanup(victim);
|
stasis_page_cleanup(victim);
|
||||||
// Make sure that no one mistakenly thinks this is still a live copy.
|
// Make sure that no one mistakenly thinks this is still a live copy.
|
||||||
victim->id = -1;
|
victim->id = -1;
|
||||||
|
@ -269,7 +271,7 @@ static Page * bhLoadPageImpl_helper(int xid, const pageid_t pageid, int uninitia
|
||||||
// try to read this page from disk.
|
// try to read this page from disk.
|
||||||
pthread_mutex_unlock(&mut);
|
pthread_mutex_unlock(&mut);
|
||||||
|
|
||||||
pageRead(ret);
|
page_handle->read(page_handle, ret);
|
||||||
|
|
||||||
pthread_mutex_lock(&mut);
|
pthread_mutex_lock(&mut);
|
||||||
|
|
||||||
|
@ -322,13 +324,13 @@ static void bhReleasePage(Page * p) {
|
||||||
pthread_mutex_unlock(&mut);
|
pthread_mutex_unlock(&mut);
|
||||||
}
|
}
|
||||||
static void bhWriteBackPage(Page * p) {
|
static void bhWriteBackPage(Page * p) {
|
||||||
pageWrite(p);
|
page_handle->write(page_handle, p);
|
||||||
}
|
}
|
||||||
static void bhForcePages() {
|
static void bhForcePages() {
|
||||||
forcePageFile();
|
page_handle->force_file(page_handle);
|
||||||
}
|
}
|
||||||
static void bhForcePageRange(pageid_t start, pageid_t stop) {
|
static void bhForcePageRange(pageid_t start, pageid_t stop) {
|
||||||
forceRangePageFile(start, stop);
|
page_handle->force_range(page_handle, start, stop);
|
||||||
}
|
}
|
||||||
static void bhBufDeinit() {
|
static void bhBufDeinit() {
|
||||||
running = 0;
|
running = 0;
|
||||||
|
@ -340,7 +342,7 @@ static void bhBufDeinit() {
|
||||||
const struct LH_ENTRY(pair_t) * next;
|
const struct LH_ENTRY(pair_t) * next;
|
||||||
LH_ENTRY(openlist)(cachedPages, &iter);
|
LH_ENTRY(openlist)(cachedPages, &iter);
|
||||||
while((next = LH_ENTRY(readlist)(&iter))) {
|
while((next = LH_ENTRY(readlist)(&iter))) {
|
||||||
pageWrite((next->value));
|
page_handle->write(page_handle, (next->value));
|
||||||
stasis_page_cleanup((next->value)); // normally called by writeBackOnePage()
|
stasis_page_cleanup((next->value)); // normally called by writeBackOnePage()
|
||||||
}
|
}
|
||||||
LH_ENTRY(closelist)(&iter);
|
LH_ENTRY(closelist)(&iter);
|
||||||
|
@ -350,6 +352,7 @@ static void bhBufDeinit() {
|
||||||
|
|
||||||
lru->deinit(lru);
|
lru->deinit(lru);
|
||||||
stasis_buffer_pool_deinit(stasis_buffer_pool);
|
stasis_buffer_pool_deinit(stasis_buffer_pool);
|
||||||
|
page_handle->close(page_handle);
|
||||||
}
|
}
|
||||||
static void bhSimulateBufferManagerCrash() {
|
static void bhSimulateBufferManagerCrash() {
|
||||||
running = 0;
|
running = 0;
|
||||||
|
@ -374,10 +377,11 @@ static void bhSimulateBufferManagerCrash() {
|
||||||
|
|
||||||
lru->deinit(lru);
|
lru->deinit(lru);
|
||||||
stasis_buffer_pool_deinit(stasis_buffer_pool);
|
stasis_buffer_pool_deinit(stasis_buffer_pool);
|
||||||
|
page_handle->close(page_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stasis_buffer_manager_hash_open() {
|
void stasis_buffer_manager_hash_open(stasis_page_handle_t * h) {
|
||||||
|
page_handle = h;
|
||||||
assert(!running);
|
assert(!running);
|
||||||
|
|
||||||
#ifdef LONG_RUN
|
#ifdef LONG_RUN
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <stasis/bufferManager.h>
|
#include <stasis/bufferManager.h>
|
||||||
#include <stasis/pageHandle.h>
|
#include <stasis/pageHandle.h>
|
||||||
|
#include <stasis/bufferPool.h>
|
||||||
#include <stasis/bufferManager/legacy/pageFile.h>
|
#include <stasis/bufferManager/legacy/pageFile.h>
|
||||||
#include <stasis/bufferManager/legacy/pageCache.h>
|
#include <stasis/bufferManager/legacy/pageCache.h>
|
||||||
|
|
||||||
|
@ -25,16 +26,28 @@ static compensated_function Page *bufManLoadUninitPage(int xid, pageid_t pageid)
|
||||||
static void bufManReleasePage (Page * p);
|
static void bufManReleasePage (Page * p);
|
||||||
static void bufManSimulateBufferManagerCrash();
|
static void bufManSimulateBufferManagerCrash();
|
||||||
|
|
||||||
|
static stasis_page_handle_t * page_handle;
|
||||||
|
|
||||||
static stasis_buffer_pool_t * stasis_buffer_pool;
|
static stasis_buffer_pool_t * stasis_buffer_pool;
|
||||||
|
|
||||||
int stasis_buffer_manager_deprecated_open() {
|
static void pageWrite_legacyWrapper(Page * p) {
|
||||||
|
page_handle->write(page_handle,p);
|
||||||
|
}
|
||||||
|
static void forcePageFile_legacyWrapper() {
|
||||||
|
page_handle->force_file(page_handle);
|
||||||
|
}
|
||||||
|
static void forceRangePageFile_legacyWrapper(lsn_t start, lsn_t stop) {
|
||||||
|
page_handle->force_range(page_handle, start, stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
int stasis_buffer_manager_deprecated_open(stasis_page_handle_t * ph) {
|
||||||
|
page_handle = ph;
|
||||||
releasePageImpl = bufManReleasePage;
|
releasePageImpl = bufManReleasePage;
|
||||||
loadPageImpl = bufManLoadPage;
|
loadPageImpl = bufManLoadPage;
|
||||||
loadUninitPageImpl = bufManLoadUninitPage;
|
loadUninitPageImpl = bufManLoadUninitPage;
|
||||||
writeBackPage = pageWrite;
|
writeBackPage = pageWrite_legacyWrapper;
|
||||||
forcePages = forcePageFile;
|
forcePages = forcePageFile_legacyWrapper;
|
||||||
forcePageRange = forceRangePageFile;
|
forcePageRange = forceRangePageFile_legacyWrapper;
|
||||||
stasis_buffer_manager_close = bufManBufDeinit;
|
stasis_buffer_manager_close = bufManBufDeinit;
|
||||||
stasis_buffer_manager_simulate_crash = bufManSimulateBufferManagerCrash;
|
stasis_buffer_manager_simulate_crash = bufManSimulateBufferManagerCrash;
|
||||||
|
|
||||||
|
@ -50,7 +63,7 @@ int stasis_buffer_manager_deprecated_open() {
|
||||||
first = stasis_buffer_pool_malloc_page(stasis_buffer_pool);
|
first = stasis_buffer_pool_malloc_page(stasis_buffer_pool);
|
||||||
stasis_buffer_pool_free_page(stasis_buffer_pool, first, 0);
|
stasis_buffer_pool_free_page(stasis_buffer_pool, first, 0);
|
||||||
LH_ENTRY(insert)(activePages, &first->id, sizeof(first->id), first);
|
LH_ENTRY(insert)(activePages, &first->id, sizeof(first->id), first);
|
||||||
pageRead(first);
|
page_handle->read(page_handle, first);
|
||||||
pageCacheInit(first);
|
pageCacheInit(first);
|
||||||
|
|
||||||
int err = pthread_key_create(&lastPage, 0);
|
int err = pthread_key_create(&lastPage, 0);
|
||||||
|
@ -73,7 +86,7 @@ static void bufManBufDeinit() {
|
||||||
LH_ENTRY(openlist(activePages, &iter));
|
LH_ENTRY(openlist(activePages, &iter));
|
||||||
|
|
||||||
while((next = LH_ENTRY(readlist)(&iter))) {
|
while((next = LH_ENTRY(readlist)(&iter))) {
|
||||||
pageWrite((Page*)next->value);
|
page_handle->write(page_handle, (Page*)next->value);
|
||||||
DEBUG("+");
|
DEBUG("+");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +96,10 @@ static void bufManBufDeinit() {
|
||||||
|
|
||||||
pageCacheDeinit();
|
pageCacheDeinit();
|
||||||
|
|
||||||
//closePageFile();
|
|
||||||
|
|
||||||
stasis_buffer_pool_deinit(stasis_buffer_pool);
|
stasis_buffer_pool_deinit(stasis_buffer_pool);
|
||||||
|
|
||||||
|
page_handle->close(page_handle);
|
||||||
|
|
||||||
#ifdef PIN_COUNT
|
#ifdef PIN_COUNT
|
||||||
if(pinCount != 0) {
|
if(pinCount != 0) {
|
||||||
printf("WARNING: At exit, %d pages were still pinned!\n", pinCount);
|
printf("WARNING: At exit, %d pages were still pinned!\n", pinCount);
|
||||||
|
@ -98,10 +111,10 @@ static void bufManBufDeinit() {
|
||||||
Just close file descriptors, don't do any other clean up. (For
|
Just close file descriptors, don't do any other clean up. (For
|
||||||
testing.)
|
testing.)
|
||||||
|
|
||||||
@todo buffer manager should never call closePageFile(); it not longer manages pageFile handles
|
@todo buffer manager should never call close_(); it not longer manages pageFile handles
|
||||||
*/
|
*/
|
||||||
void bufManSimulateBufferManagerCrash() {
|
static void bufManSimulateBufferManagerCrash() {
|
||||||
closePageFile();
|
page_handle->close(page_handle);
|
||||||
#ifdef PIN_COUNT
|
#ifdef PIN_COUNT
|
||||||
pinCount = 0;
|
pinCount = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -259,12 +272,12 @@ static Page* bufManGetPage(pageid_t pageid, int locktype, int uninitialized) {
|
||||||
|
|
||||||
assert(ret != dummy_page);
|
assert(ret != dummy_page);
|
||||||
if(ret->id != -1) {
|
if(ret->id != -1) {
|
||||||
pageWrite(ret);
|
page_handle->write(page_handle, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
stasis_buffer_pool_free_page(stasis_buffer_pool, ret, pageid);
|
stasis_buffer_pool_free_page(stasis_buffer_pool, ret, pageid);
|
||||||
if(!uninitialized) {
|
if(!uninitialized) {
|
||||||
pageRead(ret);
|
page_handle->read(page_handle, ret);
|
||||||
} else {
|
} else {
|
||||||
memset(ret->memAddr, 0, PAGE_SIZE);
|
memset(ret->memAddr, 0, PAGE_SIZE);
|
||||||
ret->dirty = 0;
|
ret->dirty = 0;
|
||||||
|
@ -283,7 +296,7 @@ static Page* bufManGetPage(pageid_t pageid, int locktype, int uninitialized) {
|
||||||
/* @todo Put off putting this back into cache until we're done with
|
/* @todo Put off putting this back into cache until we're done with
|
||||||
it. -- This could cause the cache to empty out if the ratio of
|
it. -- This could cause the cache to empty out if the ratio of
|
||||||
threads to buffer slots is above ~ 1/3, but it decreases the
|
threads to buffer slots is above ~ 1/3, but it decreases the
|
||||||
liklihood of thrashing. */
|
likelihood of thrashing. */
|
||||||
cacheInsertPage(ret);
|
cacheInsertPage(ret);
|
||||||
|
|
||||||
pthread_mutex_unlock(&loadPagePtr_mutex);
|
pthread_mutex_unlock(&loadPagePtr_mutex);
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
This file handles all of the file I/O for pages.
|
This file handles all of the file I/O for pages.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stasis/page.h>
|
|
||||||
|
|
||||||
|
#include <stasis/page.h>
|
||||||
#include <stasis/bufferManager.h>
|
#include <stasis/bufferManager.h>
|
||||||
#include <stasis/pageHandle.h>
|
#include <stasis/pageHandle.h>
|
||||||
|
#include <stasis/truncation.h>
|
||||||
|
|
||||||
#include <stasis/bufferManager/legacy/pageFile.h>
|
#include <stasis/bufferManager/legacy/pageFile.h>
|
||||||
|
#include <stasis/logger/logger2.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stasis/logger/logger2.h>
|
|
||||||
#include <stasis/truncation.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <stdlib.h>
|
||||||
/** For O_DIRECT. It's unclear that this is the correct thing to \#define, but it works under linux. */
|
/** For O_DIRECT. It's unclear that this is the correct thing to \#define, but it works under linux. */
|
||||||
#define __USE_GNU
|
#define __USE_GNU
|
||||||
|
|
||||||
|
@ -28,16 +28,16 @@
|
||||||
|
|
||||||
static int stable = -1;
|
static int stable = -1;
|
||||||
static pthread_mutex_t stable_mutex;
|
static pthread_mutex_t stable_mutex;
|
||||||
static void pfForcePageFile();
|
static void pfForcePageFile(stasis_page_handle_t* h);
|
||||||
static void pfClosePageFile();
|
static void pfClosePageFile(stasis_page_handle_t* h);
|
||||||
static void pfForceRangePageFile(lsn_t start, lsn_t stop) ;
|
static void pfForceRangePageFile(stasis_page_handle_t* h, lsn_t start, lsn_t stop) ;
|
||||||
inline static pageid_t myLseekNoLock(int f, pageid_t offset, int whence);
|
inline static pageid_t myLseekNoLock(int f, pageid_t offset, int whence);
|
||||||
|
|
||||||
static int oldOffset = -1;
|
static int oldOffset = -1;
|
||||||
|
|
||||||
int pageFile_isDurable = 1;
|
int pageFile_isDurable = 1;
|
||||||
|
|
||||||
static void pfPageRead(Page *ret) {
|
static void pfPageRead(stasis_page_handle_t * h, Page *ret) {
|
||||||
|
|
||||||
pageid_t pageoffset;
|
pageid_t pageoffset;
|
||||||
pageid_t offset;
|
pageid_t offset;
|
||||||
|
@ -46,7 +46,7 @@ static void pfPageRead(Page *ret) {
|
||||||
pthread_mutex_lock(&stable_mutex);
|
pthread_mutex_lock(&stable_mutex);
|
||||||
|
|
||||||
|
|
||||||
if(oldOffset != pageoffset) {
|
if(oldOffset != pageoffset) {
|
||||||
offset = myLseekNoLock(stable, pageoffset, SEEK_SET);
|
offset = myLseekNoLock(stable, pageoffset, SEEK_SET);
|
||||||
assert(offset == pageoffset);
|
assert(offset == pageoffset);
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,7 +60,7 @@ static void pfPageRead(Page *ret) {
|
||||||
if(read_size != PAGE_SIZE) {
|
if(read_size != PAGE_SIZE) {
|
||||||
if (!read_size) { /* Past EOF... */
|
if (!read_size) { /* Past EOF... */
|
||||||
memset(ret->memAddr, 0, PAGE_SIZE); // The file will be extended when we write to the new page.
|
memset(ret->memAddr, 0, PAGE_SIZE); // The file will be extended when we write to the new page.
|
||||||
} else if(read_size == -1) {
|
} else if(read_size == -1) {
|
||||||
perror("pageFile.c couldn't read");
|
perror("pageFile.c couldn't read");
|
||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
abort();
|
abort();
|
||||||
|
@ -78,13 +78,13 @@ static void pfPageRead(Page *ret) {
|
||||||
}
|
}
|
||||||
/** @todo need to sync the page file to disk occasionally, so that the
|
/** @todo need to sync the page file to disk occasionally, so that the
|
||||||
dirty page table can be kept up to date. */
|
dirty page table can be kept up to date. */
|
||||||
static void pfPageWrite(Page * ret) {
|
static void pfPageWrite(stasis_page_handle_t * h, Page * ret) {
|
||||||
/** If the page is clean, there's no reason to write it out. */
|
/** If the page is clean, there's no reason to write it out. */
|
||||||
assert(ret->dirty == dirtyPages_isDirty(ret));
|
assert(ret->dirty == dirtyPages_isDirty(ret));
|
||||||
if(!ret->dirty) {
|
if(!ret->dirty) {
|
||||||
// if(!dirtyPages_isDirty(ret)) {
|
// if(!dirtyPages_isDirty(ret)) {
|
||||||
DEBUG(" =^)~ ");
|
DEBUG(" =^)~ ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pageid_t pageoffset = ret->id * PAGE_SIZE;
|
pageid_t pageoffset = ret->id * PAGE_SIZE;
|
||||||
pageid_t offset ;
|
pageid_t offset ;
|
||||||
|
@ -133,12 +133,13 @@ static void pfPageWrite(Page * ret) {
|
||||||
//#define PAGE_FILE_O_DIRECT
|
//#define PAGE_FILE_O_DIRECT
|
||||||
|
|
||||||
/** @todo O_DIRECT is broken in older linuxes (eg 2.4). The build script should disable it on such platforms. */
|
/** @todo O_DIRECT is broken in older linuxes (eg 2.4). The build script should disable it on such platforms. */
|
||||||
void openPageFile() {
|
stasis_page_handle_t* openPageFile() {
|
||||||
pageRead = pfPageRead;
|
stasis_page_handle_t * ret = malloc(sizeof(*ret));
|
||||||
pageWrite = pfPageWrite;
|
ret->read = pfPageRead;
|
||||||
forcePageFile = pfForcePageFile;
|
ret->write = pfPageWrite;
|
||||||
forceRangePageFile = pfForceRangePageFile;
|
ret->force_file = pfForcePageFile;
|
||||||
closePageFile = pfClosePageFile;
|
ret->force_range = pfForceRangePageFile;
|
||||||
|
ret->close = pfClosePageFile;
|
||||||
|
|
||||||
DEBUG("Opening storefile.\n");
|
DEBUG("Opening storefile.\n");
|
||||||
|
|
||||||
|
@ -149,7 +150,7 @@ void openPageFile() {
|
||||||
stable = open (stasis_store_file_name,
|
stable = open (stasis_store_file_name,
|
||||||
O_CREAT | O_RDWR, FILE_PERM);
|
O_CREAT | O_RDWR, FILE_PERM);
|
||||||
#endif
|
#endif
|
||||||
if(!pageFile_isDurable) {
|
if(!pageFile_isDurable) {
|
||||||
fprintf(stderr, "\n**********\n");
|
fprintf(stderr, "\n**********\n");
|
||||||
fprintf (stderr, "pageFile.c: pageFile_isDurable==0; the page file will not force writes to disk.\n");
|
fprintf (stderr, "pageFile.c: pageFile_isDurable==0; the page file will not force writes to disk.\n");
|
||||||
fprintf (stderr, " Transactions will not be durable if the system crashes.\n**********\n");
|
fprintf (stderr, " Transactions will not be durable if the system crashes.\n**********\n");
|
||||||
|
@ -159,13 +160,13 @@ void openPageFile() {
|
||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_init(&stable_mutex, NULL);
|
|
||||||
|
|
||||||
|
pthread_mutex_init(&stable_mutex, NULL);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pfForcePageFile() {
|
static void pfForcePageFile(stasis_page_handle_t * h) {
|
||||||
if(pageFile_isDurable) {
|
if(pageFile_isDurable) {
|
||||||
#ifndef PAGE_FILE_O_DIRECT
|
#ifndef PAGE_FILE_O_DIRECT
|
||||||
#ifdef HAVE_FDATASYNC
|
#ifdef HAVE_FDATASYNC
|
||||||
fdatasync(stable);
|
fdatasync(stable);
|
||||||
|
@ -176,7 +177,7 @@ static void pfForcePageFile() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pfForceRangePageFile(lsn_t start, lsn_t stop) {
|
static void pfForceRangePageFile(stasis_page_handle_t * h, lsn_t start, lsn_t stop) {
|
||||||
if(pageFile_isDurable) {
|
if(pageFile_isDurable) {
|
||||||
#ifdef HAVE_SYNC_FILE_RANGE
|
#ifdef HAVE_SYNC_FILE_RANGE
|
||||||
int ret = sync_file_range(stable, start, stop,
|
int ret = sync_file_range(stable, start, stop,
|
||||||
|
@ -193,15 +194,15 @@ static void pfForceRangePageFile(lsn_t start, lsn_t stop) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void pfClosePageFile() {
|
static void pfClosePageFile(stasis_page_handle_t * h) {
|
||||||
assert(stable != -1);
|
assert(stable != -1);
|
||||||
forcePageFile();
|
h->force_file(h);
|
||||||
DEBUG("Closing storefile\n");
|
DEBUG("Closing storefile\n");
|
||||||
|
|
||||||
int ret = close(stable);
|
int ret = close(stable);
|
||||||
|
|
||||||
|
|
||||||
if(-1 == ret) {
|
if(-1 == ret) {
|
||||||
perror("Couldn't close storefile.");
|
perror("Couldn't close storefile.");
|
||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
abort();
|
abort();
|
||||||
|
|
|
@ -5,12 +5,18 @@
|
||||||
* Author: sears
|
* Author: sears
|
||||||
*/
|
*/
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stasis/common.h>
|
||||||
|
#include <stasis/constants.h>
|
||||||
|
#include <stasis/flags.h>
|
||||||
|
#include <stasis/io/handle.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <stasis/io/handle.h>
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
// @todo this factory stuff doesn't really belong here...
|
// @todo this factory stuff doesn't really belong here...
|
||||||
static stasis_handle_t * fast_factory(lsn_t off, lsn_t len, void * ignored) {
|
static stasis_handle_t * fast_factory(lsn_t off, lsn_t len, void * ignored) {
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
|
#include "config.h"
|
||||||
|
#include <stasis/common.h>
|
||||||
|
#include <stasis/constants.h>
|
||||||
#include <stasis/io/handle.h>
|
#include <stasis/io/handle.h>
|
||||||
|
#include <stasis/linkedlist.h>
|
||||||
#include <stasis/redblack.h>
|
#include <stasis/redblack.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -6,7 +10,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stasis/linkedlist.h>
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file
|
@file
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#define _XOPEN_SOURCE 600
|
#define _XOPEN_SOURCE 600
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include <config.h>
|
||||||
#include <stasis/page.h>
|
#include <stasis/page.h>
|
||||||
|
#include <stasis/logger/logEntry.h>
|
||||||
#include <stasis/operations/pageOperations.h>
|
#include <stasis/operations/pageOperations.h>
|
||||||
|
#include <stasis/operations/regions.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ int TpageSetRange(int xid, pageid_t page, int offset, const void * memAddr, int
|
||||||
/** @todo region sizes should be dynamic. */
|
/** @todo region sizes should be dynamic. */
|
||||||
#define TALLOC_PAGE_REGION_SIZE 128 // 512K
|
#define TALLOC_PAGE_REGION_SIZE 128 // 512K
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This calls loadPage and releasePage directly, and bypasses the
|
This calls loadPage and releasePage directly, and bypasses the
|
||||||
logger.
|
logger.
|
||||||
*/
|
*/
|
||||||
|
@ -86,7 +88,7 @@ compensated_function void pageOperationsInit() {
|
||||||
recordid rid = {0, 0, sizeof(boundary_tag)};
|
recordid rid = {0, 0, sizeof(boundary_tag)};
|
||||||
// Need to find a region with some free pages in it.
|
// Need to find a region with some free pages in it.
|
||||||
Tread(-1, rid, &t);
|
Tread(-1, rid, &t);
|
||||||
|
|
||||||
|
|
||||||
pthread_mutex_init(&pageAllocMutex, NULL);
|
pthread_mutex_init(&pageAllocMutex, NULL);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +118,7 @@ compensated_function pageid_t TpageAllocMany(int xid, int count) {
|
||||||
return TregionAlloc(xid, count, STORAGE_MANAGER_NAIVE_PAGE_ALLOC);
|
return TregionAlloc(xid, count, STORAGE_MANAGER_NAIVE_PAGE_ALLOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TpageGetType(int xid, pageid_t page) {
|
int TpageGetType(int xid, pageid_t page) {
|
||||||
Page * p = loadPage(xid, page);
|
Page * p = loadPage(xid, page);
|
||||||
int ret = *stasis_page_type_ptr(p);
|
int ret = *stasis_page_type_ptr(p);
|
||||||
releasePage(p);
|
releasePage(p);
|
||||||
|
@ -132,11 +134,11 @@ int TpageGetType(int xid, pageid_t page) {
|
||||||
load page to be used, and update in-memory data. (obtains lock on loaded page)
|
load page to be used, and update in-memory data. (obtains lock on loaded page)
|
||||||
T update() the page, zeroing it, and saving the old successor in the log.
|
T update() the page, zeroing it, and saving the old successor in the log.
|
||||||
relase the page (avoid deadlock in next step)
|
relase the page (avoid deadlock in next step)
|
||||||
T update() LLADD's header page (the first in the store file) with a new copy of
|
T update() LLADD's header page (the first in the store file) with a new copy of
|
||||||
the in-memory data, saving old version in the log.
|
the in-memory data, saving old version in the log.
|
||||||
release mutex
|
release mutex
|
||||||
|
|
||||||
Free:
|
Free:
|
||||||
|
|
||||||
obtain mutex
|
obtain mutex
|
||||||
determine the current head of the freelist using in-memory data
|
determine the current head of the freelist using in-memory data
|
||||||
|
@ -151,8 +153,8 @@ int TpageGetType(int xid, pageid_t page) {
|
||||||
and setting the successor pointer. This operation physically logs
|
and setting the successor pointer. This operation physically logs
|
||||||
a whole page, which makes it expensive. Doing so is necessary in
|
a whole page, which makes it expensive. Doing so is necessary in
|
||||||
general, but it is possible that application specific logic could
|
general, but it is possible that application specific logic could
|
||||||
avoid the physical logging here.
|
avoid the physical logging here.
|
||||||
|
|
||||||
Instead, we should just record the fact that the page was freed
|
Instead, we should just record the fact that the page was freed
|
||||||
somewhere. That way, we don't need to read the page in, or write
|
somewhere. That way, we don't need to read the page in, or write
|
||||||
out information about it. If we lock the page against
|
out information about it. If we lock the page against
|
||||||
|
@ -215,8 +217,8 @@ static int op_initialize_page(const LogEntry* e, Page* p) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
stasis_operation_impl stasis_op_impl_page_initialize() {
|
stasis_operation_impl stasis_op_impl_page_initialize() {
|
||||||
stasis_operation_impl o = {
|
stasis_operation_impl o = {
|
||||||
OPERATION_INITIALIZE_PAGE,
|
OPERATION_INITIALIZE_PAGE,
|
||||||
OPERATION_INITIALIZE_PAGE,
|
OPERATION_INITIALIZE_PAGE,
|
||||||
OPERATION_NOOP,
|
OPERATION_NOOP,
|
||||||
|
|
|
@ -9,21 +9,12 @@
|
||||||
|
|
||||||
#include <stasis/page.h>
|
#include <stasis/page.h>
|
||||||
|
|
||||||
void (*pageWrite)(Page * dat);
|
|
||||||
void (*pageRead)(Page * ret);
|
|
||||||
void (*forcePageFile)();
|
|
||||||
void (*forceRangePageFile)();
|
|
||||||
void (*closePageFile)();
|
|
||||||
|
|
||||||
int printedForceWarning = 0;
|
|
||||||
|
|
||||||
static stasis_handle_t * h;
|
|
||||||
/**
|
/**
|
||||||
@todo Make sure this doesn't need to be atomic. (It isn't!) Can
|
@todo Make sure this doesn't need to be atomic. (It isn't!) Can
|
||||||
we get in trouble by setting the page clean after it's written
|
we get in trouble by setting the page clean after it's written
|
||||||
out, or forcing the log too early?
|
out, or forcing the log too early?
|
||||||
*/
|
*/
|
||||||
static void phWrite(Page * ret) {
|
static void phWrite(stasis_page_handle_t * ph, Page * ret) {
|
||||||
if(!ret->dirty) { return; }
|
if(!ret->dirty) { return; }
|
||||||
// This lock is only held to make the page implementation happy. We should
|
// This lock is only held to make the page implementation happy. We should
|
||||||
// implicitly have exclusive access to the page before this function is called,
|
// implicitly have exclusive access to the page before this function is called,
|
||||||
|
@ -31,7 +22,7 @@ static void phWrite(Page * ret) {
|
||||||
writelock(ret->rwlatch,0);
|
writelock(ret->rwlatch,0);
|
||||||
stasis_page_flushed(ret);
|
stasis_page_flushed(ret);
|
||||||
LogForce(stasis_log_file, ret->LSN, LOG_FORCE_WAL);
|
LogForce(stasis_log_file, ret->LSN, LOG_FORCE_WAL);
|
||||||
int err = h->write(h, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
|
int err = ((stasis_handle_t*)ph->impl)->write(ph->impl, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
|
||||||
if(err) {
|
if(err) {
|
||||||
printf("Couldn't write to page file: %s\n", strerror(err));
|
printf("Couldn't write to page file: %s\n", strerror(err));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -40,9 +31,9 @@ static void phWrite(Page * ret) {
|
||||||
dirtyPages_remove(ret);
|
dirtyPages_remove(ret);
|
||||||
unlock(ret->rwlatch);
|
unlock(ret->rwlatch);
|
||||||
}
|
}
|
||||||
static void phRead(Page * ret) {
|
static void phRead(stasis_page_handle_t * ph, Page * ret) {
|
||||||
writelock(ret->rwlatch,0);
|
writelock(ret->rwlatch,0);
|
||||||
int err = h->read(h, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
|
int err = ((stasis_handle_t*)ph->impl)->read(ph->impl, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
|
||||||
if(err) {
|
if(err) {
|
||||||
if(err == EDOM) {
|
if(err == EDOM) {
|
||||||
// tried to read off end of file...
|
// tried to read off end of file...
|
||||||
|
@ -57,30 +48,32 @@ static void phRead(Page * ret) {
|
||||||
stasis_page_loaded(ret);
|
stasis_page_loaded(ret);
|
||||||
unlock(ret->rwlatch);
|
unlock(ret->rwlatch);
|
||||||
}
|
}
|
||||||
static void phForce() {
|
static void phForce(stasis_page_handle_t * ph) {
|
||||||
int err = h->force(h);
|
int err = ((stasis_handle_t*)ph->impl)->force(ph->impl);
|
||||||
assert(!err);
|
assert(!err);
|
||||||
}
|
}
|
||||||
static void phForceRange(lsn_t start, lsn_t stop) {
|
static void phForceRange(stasis_page_handle_t * ph, lsn_t start, lsn_t stop) {
|
||||||
int err = h->force_range(h,start,stop);
|
int err = ((stasis_handle_t*)ph->impl)->force_range(ph->impl,start,stop);
|
||||||
assert(!err);
|
assert(!err);
|
||||||
}
|
}
|
||||||
static void phClose() {
|
static void phClose(stasis_page_handle_t * ph) {
|
||||||
int err = h->close(h);
|
int err = ((stasis_handle_t*)ph->impl)->close(ph->impl);
|
||||||
DEBUG("Closing pageHandle\n");
|
DEBUG("Closing pageHandle\n");
|
||||||
if(err) {
|
if(err) {
|
||||||
printf("Couldn't close page file: %s\n", strerror(err));
|
printf("Couldn't close page file: %s\n", strerror(err));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
free(ph);
|
||||||
}
|
}
|
||||||
|
stasis_page_handle_t * stasis_page_handle_open(stasis_handle_t * handle) {
|
||||||
void pageHandleOpen(stasis_handle_t * handle) {
|
|
||||||
DEBUG("Using pageHandle implementation\n");
|
DEBUG("Using pageHandle implementation\n");
|
||||||
pageWrite = phWrite;
|
stasis_page_handle_t * ret = malloc(sizeof(*ret));
|
||||||
pageRead = phRead;
|
ret->write = phWrite;
|
||||||
forcePageFile = phForce;
|
ret->read = phRead;
|
||||||
forceRangePageFile = phForceRange;
|
ret->force_file = phForce;
|
||||||
closePageFile = phClose;
|
ret->force_range = phForceRange;
|
||||||
h = handle;
|
ret->close = phClose;
|
||||||
|
ret->impl = handle;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <stasis/truncation.h>
|
#include <stasis/truncation.h>
|
||||||
#include <stasis/io/handle.h>
|
#include <stasis/io/handle.h>
|
||||||
#include <stasis/blobManager.h> // XXX remove this, move Tread() to set.c
|
#include <stasis/blobManager.h> // XXX remove this, move Tread() to set.c
|
||||||
//#include <stdio.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ void stasis_transaction_table_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Tinit() {
|
int Tinit() {
|
||||||
pthread_mutex_init(&stasis_transaction_table_mutex, NULL);
|
pthread_mutex_init(&stasis_transaction_table_mutex, NULL);
|
||||||
stasis_initted = 1;
|
stasis_initted = 1;
|
||||||
stasis_transaction_table_num_active = 0;
|
stasis_transaction_table_num_active = 0;
|
||||||
|
|
||||||
compensations_init();
|
compensations_init();
|
||||||
|
@ -60,26 +60,28 @@ int Tinit() {
|
||||||
stasis_transaction_table_init();
|
stasis_transaction_table_init();
|
||||||
stasis_operation_table_init();
|
stasis_operation_table_init();
|
||||||
dirtyPagesInit();
|
dirtyPagesInit();
|
||||||
if(LOG_TO_FILE == stasis_log_type) {
|
|
||||||
stasis_log_file = stasis_log_safe_writes_open(stasis_log_file_name,
|
|
||||||
stasis_log_file_mode,
|
|
||||||
stasis_log_file_permissions);
|
|
||||||
} else if(LOG_TO_MEMORY == stasis_log_type) {
|
|
||||||
stasis_log_file = stasis_log_impl_in_memory_open();
|
|
||||||
} else {
|
|
||||||
assert(stasis_log_file != NULL);
|
|
||||||
}
|
|
||||||
stasis_page_init();
|
|
||||||
|
|
||||||
|
if(LOG_TO_FILE == stasis_log_type) {
|
||||||
|
stasis_log_file = stasis_log_safe_writes_open(stasis_log_file_name,
|
||||||
|
stasis_log_file_mode,
|
||||||
|
stasis_log_file_permissions);
|
||||||
|
} else if(LOG_TO_MEMORY == stasis_log_type) {
|
||||||
|
stasis_log_file = stasis_log_impl_in_memory_open();
|
||||||
|
} else {
|
||||||
|
assert(stasis_log_file != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
stasis_page_init();
|
||||||
|
stasis_page_handle_t * page_handle;
|
||||||
if(bufferManagerFileHandleType == BUFFER_MANAGER_FILE_HANDLE_DEPRECATED) {
|
if(bufferManagerFileHandleType == BUFFER_MANAGER_FILE_HANDLE_DEPRECATED) {
|
||||||
printf("\nWarning: Using old I/O routines (with known bugs).\n");
|
printf("\nWarning: Using old I/O routines (with known bugs).\n");
|
||||||
openPageFile();
|
page_handle = openPageFile();
|
||||||
} else {
|
} else {
|
||||||
stasis_handle_t * h = stasis_handle_open(stasis_store_file_name);
|
stasis_handle_t * h = stasis_handle_open(stasis_store_file_name);
|
||||||
// XXX should not be global.
|
// XXX should not be global.
|
||||||
pageHandleOpen(h);
|
page_handle = stasis_page_handle_open(h);
|
||||||
}
|
}
|
||||||
stasis_buffer_manager_open(bufferManagerType);
|
stasis_buffer_manager_open(bufferManagerType, page_handle);
|
||||||
DEBUG("Buffer manager type = %d\n", bufferManagerType);
|
DEBUG("Buffer manager type = %d\n", bufferManagerType);
|
||||||
pageOperationsInit();
|
pageOperationsInit();
|
||||||
TallocInit();
|
TallocInit();
|
||||||
|
@ -347,7 +349,6 @@ int Tdeinit() {
|
||||||
TallocDeinit();
|
TallocDeinit();
|
||||||
stasis_buffer_manager_close();
|
stasis_buffer_manager_close();
|
||||||
DEBUG("Closing page file tdeinit\n");
|
DEBUG("Closing page file tdeinit\n");
|
||||||
closePageFile();
|
|
||||||
stasis_page_deinit();
|
stasis_page_deinit();
|
||||||
stasis_log_file->close(stasis_log_file);
|
stasis_log_file->close(stasis_log_file);
|
||||||
dirtyPagesDeinit();
|
dirtyPagesDeinit();
|
||||||
|
@ -364,7 +365,7 @@ int TuncleanShutdown() {
|
||||||
stasis_truncation_deinit();
|
stasis_truncation_deinit();
|
||||||
TnaiveHashDeinit();
|
TnaiveHashDeinit();
|
||||||
stasis_buffer_manager_simulate_crash();
|
stasis_buffer_manager_simulate_crash();
|
||||||
// XXX: closePageFile?
|
// XXX: close_file?
|
||||||
stasis_page_deinit();
|
stasis_page_deinit();
|
||||||
stasis_log_file->close(stasis_log_file);
|
stasis_log_file->close(stasis_log_file);
|
||||||
stasis_transaction_table_num_active = 0;
|
stasis_transaction_table_num_active = 0;
|
||||||
|
|
|
@ -76,14 +76,11 @@ terms specified in this license.
|
||||||
@ingroup BUFFER_MANAGER
|
@ingroup BUFFER_MANAGER
|
||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stasis/transactional.h>
|
|
||||||
|
|
||||||
#ifndef __BUFFERMANAGER_H__
|
#ifndef __BUFFERMANAGER_H__
|
||||||
#define __BUFFERMANAGER_H__
|
#define __BUFFERMANAGER_H__
|
||||||
|
|
||||||
BEGIN_C_DECLS
|
BEGIN_C_DECLS
|
||||||
|
#include <stasis/pageHandle.h>
|
||||||
/**
|
/**
|
||||||
* Obtain a pointer to a page from the buffer manager. The page will
|
* Obtain a pointer to a page from the buffer manager. The page will
|
||||||
* be pinned, and the pointer valid until releasePage is called.
|
* be pinned, and the pointer valid until releasePage is called.
|
||||||
|
@ -148,7 +145,7 @@ extern void (*forcePages)();
|
||||||
extern void (*forcePageRange)(pageid_t start, pageid_t stop);
|
extern void (*forcePageRange)(pageid_t start, pageid_t stop);
|
||||||
extern void (*stasis_buffer_manager_simulate_crash)();
|
extern void (*stasis_buffer_manager_simulate_crash)();
|
||||||
|
|
||||||
int stasis_buffer_manager_open(int type);
|
int stasis_buffer_manager_open(int type, stasis_page_handle_t* ph);
|
||||||
/**
|
/**
|
||||||
* will write out any dirty pages, assumes that there are no running
|
* will write out any dirty pages, assumes that there are no running
|
||||||
* transactions
|
* transactions
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
void stasis_buffer_manager_hash_open();
|
#ifndef STASIS_BUFFERMANAGER_BUFFERHASH_H
|
||||||
|
#define STASIS_BUFFERMANAGER_BUFFERHASH_H
|
||||||
|
#include <stasis/pageHandle.h>
|
||||||
|
void stasis_buffer_manager_hash_open(stasis_page_handle_t* ph);
|
||||||
|
#endif //STASIS_BUFFERMANAGER_BUFFERHASH_H
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#ifndef __STASIS_BUFFERMANAGER_LEGACY_LEGACYBUFFERMANAGER_H
|
#ifndef STASIS_BUFFERMANAGER_LEGACY_LEGACYBUFFERMANAGER_H
|
||||||
#define __STASIS_BUFFERMANAGER_LEGACY_LEGACYBUFFERMANAGER_H
|
#define STASIS_BUFFERMANAGER_LEGACY_LEGACYBUFFERMANAGER_H
|
||||||
int stasis_buffer_manager_deprecated_open();
|
#include <stasis/pageHandle.h>
|
||||||
#endif//__STASIS_BUFFERMANAGER_LEGACY_LEGACYBUFFERMANAGER_H
|
int stasis_buffer_manager_deprecated_open(stasis_page_handle_t * ph);
|
||||||
|
#endif//STASIS_BUFFERMANAGER_LEGACY_LEGACYBUFFERMANAGER_H
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
Implements lladd's caching policy. Looks up pageid in the cache.
|
Implements lladd's caching policy. Looks up pageid in the cache.
|
||||||
If pageid doesn't exist, then allocate a new slot for it. If
|
If pageid doesn't exist, then allocate a new slot for it. If
|
||||||
there are no new slots, then callback into bufferManager's
|
there are no new slots, then callback into bufferManager's
|
||||||
pageRead() function. Eventually, this could be extended to
|
read_page() function. Eventually, this could be extended to
|
||||||
support application specific caching schemes.
|
support application specific caching schemes.
|
||||||
|
|
||||||
If you would like to implement your own caching policy, implement
|
If you would like to implement your own caching policy, implement
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
The implementation of this module does not need to be threadsafe.
|
The implementation of this module does not need to be threadsafe.
|
||||||
|
|
||||||
@param first The caller should manually read this page by calling
|
@param first The caller should manually read this page by calling
|
||||||
pageRead() before calling pageCacheInit.
|
read_page() before calling pageCacheInit.
|
||||||
|
|
||||||
@todo pageCacheInit should not take a page as a parameter.
|
@todo pageCacheInit should not take a page as a parameter.
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#ifndef __PAGE_FILE_H
|
#ifndef __PAGE_FILE_H
|
||||||
#define __PAGE_FILE_H
|
#define __PAGE_FILE_H
|
||||||
|
|
||||||
void openPageFile();
|
#include <stasis/pageHandle.h>
|
||||||
|
|
||||||
|
stasis_page_handle_t* openPageFile();
|
||||||
|
|
||||||
#endif /* __PAGE_FILE_H */
|
#endif /* __PAGE_FILE_H */
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include <stasis/transactional.h>
|
|
||||||
|
|
||||||
#ifndef IO_HANDLE_H
|
#ifndef IO_HANDLE_H
|
||||||
#define IO_HANDLE_H
|
#define IO_HANDLE_H
|
||||||
|
#include <stasis/common.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
stasis_handle() is a macro that prepends a unique prefix to the its
|
stasis_handle() is a macro that prepends a unique prefix to the its
|
||||||
|
|
|
@ -75,7 +75,7 @@ terms specified in this license.
|
||||||
/** @{ */
|
/** @{ */
|
||||||
#ifndef __ARRAY_LIST_H
|
#ifndef __ARRAY_LIST_H
|
||||||
#define __ARRAY_LIST_H
|
#define __ARRAY_LIST_H
|
||||||
|
#include <stasis/operations.h>
|
||||||
/** Allocate a new array list.
|
/** Allocate a new array list.
|
||||||
|
|
||||||
@param xid The transaction allocating the new arrayList.
|
@param xid The transaction allocating the new arrayList.
|
||||||
|
@ -108,7 +108,7 @@ compensated_function int TarrayListExtend(int xid, recordid rid, int slots);
|
||||||
@param rid the recordid pointing to the ArrayList.
|
@param rid the recordid pointing to the ArrayList.
|
||||||
@return The number of items stored in the ArrayList.
|
@return The number of items stored in the ArrayList.
|
||||||
*/
|
*/
|
||||||
compensated_function int TarrayListLength(int xid, recordid rid);
|
compensated_function int TarrayListLength(int xid, recordid rid);
|
||||||
|
|
||||||
/** Used by Tread() and Tset() to map from arrayList index to recordid. */
|
/** Used by Tread() and Tset() to map from arrayList index to recordid. */
|
||||||
recordid dereferenceArrayListRid(int xid, Page * p, int offset);
|
recordid dereferenceArrayListRid(int xid, Page * p, int offset);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "stasis/bufferManager.h"
|
#include "stasis/bufferManager.h"
|
||||||
#include "stasis/page/compression/compression.h"
|
#include "stasis/page/compression/compression.h"
|
||||||
#include "stasis/page/compression/tuple.h"
|
#include "stasis/page/compression/tuple.h"
|
||||||
|
#include "stasis/operations.h"
|
||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class gcIterator {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
at_end_=true;
|
at_end_=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
explicit gcIterator()
|
explicit gcIterator()
|
||||||
: i_(0),
|
: i_(0),
|
||||||
|
@ -682,7 +682,7 @@ class versioningIterator {
|
||||||
toByteArray<SET,ROW>(stlSetIterator<SET,ROW> * const t);
|
toByteArray<SET,ROW>(stlSetIterator<SET,ROW> * const t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class SET,class ROW>
|
template <class SET,class ROW>
|
||||||
inline const byte * toByteArray(stlSetIterator<SET,ROW> * const t) {
|
inline const byte * toByteArray(stlSetIterator<SET,ROW> * const t) {
|
||||||
return (*(t->it_)).toByteArray();
|
return (*(t->it_)).toByteArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,12 @@ terms specified in this license.
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* Provides raw access to entire pages.
|
* Provides raw access to entire pages.
|
||||||
*
|
*
|
||||||
* LLADD's pages are PAGE_SIZE bytes long. Currently, two integers are
|
* LLADD's pages are PAGE_SIZE bytes long. Currently, two integers are
|
||||||
* reserved for the LSN and the page type. providing PAGE_SIZE-8 bytes
|
* reserved for the LSN and the page type. providing PAGE_SIZE-8 bytes
|
||||||
* of usable space.
|
* of usable space.
|
||||||
*
|
*
|
||||||
* @ingroup OPERATIONS
|
* @ingroup OPERATIONS
|
||||||
|
@ -54,11 +54,10 @@ terms specified in this license.
|
||||||
* @see page.h
|
* @see page.h
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __PAGE_OPERATIONS_H__
|
#ifndef __PAGE_OPERATIONS_H__
|
||||||
#define __PAGE_OPERATIONS_H__
|
#define __PAGE_OPERATIONS_H__
|
||||||
|
#include <stasis/operations.h>
|
||||||
|
|
||||||
compensated_function pageid_t TpageAlloc(int xid);
|
compensated_function pageid_t TpageAlloc(int xid);
|
||||||
compensated_function pageid_t TfixedPageAlloc(int xid, int size);
|
compensated_function pageid_t TfixedPageAlloc(int xid, int size);
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef STASIS_OPERATIONS_REGIONS_H
|
||||||
|
#define STASIS_OPERATIONS_REGIONS_H
|
||||||
|
#include <stasis/operations.h>
|
||||||
/**
|
/**
|
||||||
Allocates and deallocates regions of pages. The page before each
|
Allocates and deallocates regions of pages. The page before each
|
||||||
region is of type BOUNDARY_TAG. All regions except the last one in
|
region is of type BOUNDARY_TAG. All regions except the last one in
|
||||||
|
@ -9,7 +12,7 @@
|
||||||
a newly allocated region are undefined.
|
a newly allocated region are undefined.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct boundary_tag {
|
typedef struct boundary_tag {
|
||||||
pageid_t size;
|
pageid_t size;
|
||||||
pageid_t prev_size;
|
pageid_t prev_size;
|
||||||
int status;
|
int status;
|
||||||
|
@ -51,3 +54,4 @@ stasis_operation_impl stasis_op_impl_region_dealloc_inverse();
|
||||||
void fsckRegions(int xid);
|
void fsckRegions(int xid);
|
||||||
|
|
||||||
// XXX need callbacks to handle transaction commit/abort.
|
// XXX need callbacks to handle transaction commit/abort.
|
||||||
|
#endif
|
||||||
|
|
|
@ -88,8 +88,8 @@ terms specified in this license.
|
||||||
|
|
||||||
Page implementations are free to define their own access methods
|
Page implementations are free to define their own access methods
|
||||||
and APIs. However, Stasis's record oriented page interface
|
and APIs. However, Stasis's record oriented page interface
|
||||||
provides a default set of methods for page access.
|
provides a default set of methods for page access.
|
||||||
|
|
||||||
@see PAGE_RECORD_INTERFACE
|
@see PAGE_RECORD_INTERFACE
|
||||||
|
|
||||||
@todo Page deallocators should call stasis_page_cleanup()
|
@todo Page deallocators should call stasis_page_cleanup()
|
||||||
|
@ -102,8 +102,10 @@ terms specified in this license.
|
||||||
#define __PAGE_H__
|
#define __PAGE_H__
|
||||||
|
|
||||||
#include <stasis/common.h>
|
#include <stasis/common.h>
|
||||||
|
#include <stasis/constants.h>
|
||||||
#include <stasis/latches.h>
|
#include <stasis/latches.h>
|
||||||
#include <stasis/transactional.h>
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
BEGIN_C_DECLS
|
BEGIN_C_DECLS
|
||||||
|
|
||||||
|
@ -182,7 +184,7 @@ struct Page_s {
|
||||||
Read from a record Read lock
|
Read from a record Read lock
|
||||||
|
|
||||||
|
|
||||||
@see rwlatch, getPage(), pageRalloc(), pageRead()
|
@see rwlatch, getPage(), pageRalloc(), read_page()
|
||||||
|
|
||||||
*/
|
*/
|
||||||
rwl * loadlatch;
|
rwl * loadlatch;
|
||||||
|
@ -337,8 +339,8 @@ lsn_t stasis_page_lsn_read(const Page * page);
|
||||||
stasis_page_type_ptr(), for example:
|
stasis_page_type_ptr(), for example:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
int * stasis_page_type_ptr(Page *p) {
|
int * stasis_page_type_ptr(Page *p) {
|
||||||
return ( (int*)stasis_page_lsn_ptr(Page *p) ) - 1;
|
return ( (int*)stasis_page_lsn_ptr(Page *p) ) - 1;
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
@ -487,7 +489,7 @@ static const size_t USABLE_SIZE_OF_PAGE = (PAGE_SIZE - sizeof(lsn_t) - sizeof(in
|
||||||
|
|
||||||
@return The length of the record in bytes.
|
@return The length of the record in bytes.
|
||||||
*/
|
*/
|
||||||
static inline size_t
|
static inline size_t
|
||||||
stasis_record_type_to_size(ssize_t type) {
|
stasis_record_type_to_size(ssize_t type) {
|
||||||
if(type >= 0) {
|
if(type >= 0) {
|
||||||
return type;
|
return type;
|
||||||
|
|
|
@ -1,57 +1,66 @@
|
||||||
#include <stasis/bufferPool.h>
|
#ifndef STASIS_PAGEHANDLE_H
|
||||||
|
#define STASIS_PAGEHANDLE_H
|
||||||
|
#include <stasis/page.h>
|
||||||
#include <stasis/io/handle.h>
|
#include <stasis/io/handle.h>
|
||||||
/**
|
|
||||||
* Write page to disk, including correct LSN. Doing so may require a
|
|
||||||
* call to logSync(). There is not much that can be done to avoid
|
|
||||||
* this call right now. In the future, it might make sense to check
|
|
||||||
* to see if some other page can be kicked, in order to avoid the log
|
|
||||||
* flush.
|
|
||||||
*
|
|
||||||
* This funciton is automatically called immediately before a page is
|
|
||||||
* evicted from cache. Operation implementors, and normal users
|
|
||||||
* should never have to call this routine.
|
|
||||||
*
|
|
||||||
* @see bufferManager.c for the implementation of pageWrite
|
|
||||||
*
|
|
||||||
* @param dat The page to be flushed to disk. No concurrent calls
|
|
||||||
* may have the same value of dat.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
extern void (*pageWrite)(Page * dat);
|
|
||||||
|
|
||||||
extern int pageFile_isDurable;
|
typedef struct stasis_page_handle_t {
|
||||||
|
/**
|
||||||
|
* Write page to disk, including correct LSN. Doing so may require a
|
||||||
|
* call to logSync(). There is not much that can be done to avoid
|
||||||
|
* this call right now. In the future, it might make sense to check
|
||||||
|
* to see if some other page can be kicked, in order to avoid the log
|
||||||
|
* flush.
|
||||||
|
*
|
||||||
|
* This function is automatically called immediately before a page is
|
||||||
|
* evicted from cache. Operation implementors, and normal users
|
||||||
|
* should never have to call this routine.
|
||||||
|
*
|
||||||
|
* @see bufferManager.c for the implementation of pageWrite
|
||||||
|
*
|
||||||
|
* @param dat The page to be flushed to disk. No concurrent calls
|
||||||
|
* may have the same value of dat.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void (*write)(struct stasis_page_handle_t* ph, Page * dat);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Read a page from disk. This bypassess the cache, and should only be
|
Read a page from disk. This bypasses the cache, and should only be
|
||||||
called by bufferManager and blobManager. To retrieve a page under
|
called by bufferManager and blobManager. To retrieve a page under
|
||||||
normal circumstances, use loadPage() instead.
|
normal circumstances, use loadPage() instead.
|
||||||
|
|
||||||
Operation implementors and normal users should never need to call
|
Operation implementors and normal users should never need to call
|
||||||
this routine.
|
this routine.
|
||||||
|
|
||||||
@param ret A page struct, with id set correctly. The rest of this
|
@param ret A page struct, with id set correctly. The rest of this
|
||||||
struct will be overwritten by pageMap. This method assumes that no
|
struct will be overwritten by pageMap. This method assumes that no
|
||||||
concurrent calls will be passed the same value of ret.
|
concurrent calls will be passed the same value of ret.
|
||||||
|
|
||||||
@see bufferManager.c for the implementation of pageRead.
|
|
||||||
|
|
||||||
@todo pageRead and pageWrite should be stored in a struct returned by
|
@see bufferManager.c for the implementation of read_page.
|
||||||
an initailizer, not in global function pointers.
|
|
||||||
*/
|
|
||||||
extern void (*pageRead)(Page * ret);
|
|
||||||
/**
|
|
||||||
Force the page file to disk. Pages that have had pageWrite()
|
|
||||||
called on them are guaranteed to be on disk after this returns.
|
|
||||||
|
|
||||||
(Note that bufferManager implementations typically call pageWrite()
|
@todo read_page and pageWrite should be stored in a struct returned by
|
||||||
automatically, so in general, other pages could be written back
|
an initializer, not in global function pointers.
|
||||||
as well...)
|
*/
|
||||||
*/
|
void (*read)(struct stasis_page_handle_t* ph, Page * ret);
|
||||||
extern void (*forcePageFile)();
|
/**
|
||||||
extern void (*forceRangePageFile)();
|
Force the page file to disk. Pages that have had pageWrite()
|
||||||
/**
|
called on them are guaranteed to be on disk after this returns.
|
||||||
Force the page file to disk, then close it.
|
|
||||||
*/
|
|
||||||
extern void (*closePageFile)();
|
|
||||||
|
|
||||||
void pageHandleOpen(stasis_handle_t * handle);
|
(Note that bufferManager implementations typically call pageWrite()
|
||||||
|
automatically, so in general, other pages could be written back
|
||||||
|
as well...)
|
||||||
|
*/
|
||||||
|
void (*force_file)(struct stasis_page_handle_t* ph);
|
||||||
|
void (*force_range)(struct stasis_page_handle_t* ph, lsn_t start, lsn_t stop);
|
||||||
|
/**
|
||||||
|
Force the page file to disk, then close it.
|
||||||
|
*/
|
||||||
|
void (*close)(struct stasis_page_handle_t* ph);
|
||||||
|
/**
|
||||||
|
* Pointer to implementation-specific state.
|
||||||
|
*/
|
||||||
|
void * impl;
|
||||||
|
} stasis_page_handle_t;
|
||||||
|
|
||||||
|
stasis_page_handle_t * stasis_page_handle_open(struct stasis_handle_t * handle);
|
||||||
|
|
||||||
|
#endif //STASIS_PAGEHANDLE_H
|
||||||
|
|
|
@ -42,7 +42,7 @@ terms specified in this license.
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
#include "../check_includes.h"
|
#include "../check_includes.h"
|
||||||
|
#include <stasis/transactional.h>
|
||||||
#include <stasis/bufferManager.h>
|
#include <stasis/bufferManager.h>
|
||||||
#include <stasis/page.h>
|
#include <stasis/page.h>
|
||||||
#include <stasis/page/indirect.h>
|
#include <stasis/page/indirect.h>
|
||||||
|
|
|
@ -42,7 +42,8 @@ terms specified in this license.
|
||||||
#include "../check_includes.h"
|
#include "../check_includes.h"
|
||||||
|
|
||||||
#include <stasis/io/handle.h>
|
#include <stasis/io/handle.h>
|
||||||
|
#include <stasis/constants.h>
|
||||||
|
#include <stasis/flags.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
Loading…
Reference in a new issue