Adaptor between the pageFile interface and stasis_handle_t

This commit is contained in:
Sears Russell 2007-03-13 08:40:31 +00:00
parent 6e749b93a4
commit 4e6330492c
2 changed files with 126 additions and 0 deletions

55
lladd/pageHandle.h Normal file
View file

@ -0,0 +1,55 @@
#include <lladd/bufferPool.h>
#include <lladd/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;
/**
Read a page from disk. This bypassess the cache, and should only be
called by bufferManager and blobManager. To retrieve a page under
normal circumstances, use loadPage() instead.
Operation implementors and normal users should never need to call
this routine.
@param ret A page struct, with id set correctly. The rest of this
struct will be overwritten by pageMap. This method assumes that no
concurrent calls will be passed the same value of ret.
@see bufferManager.c for the implementation of pageRead.
@todo pageRead and pageWrite should be static, but pageCache needs
to call them.
*/
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()
automatically, so in general, other pages could be written back
as well...)
*/
extern void (*forcePageFile)();
/**
Force the page file to disk, then close it.
*/
extern void (*closePageFile)();
void pageHandleOpen(stasis_handle_t * handle);

71
src/lladd/pageHandle.c Normal file
View file

@ -0,0 +1,71 @@
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <lladd/io/handle.h>
#include <lladd/pageHandle.h>
#include <lladd/bufferPool.h>
#include <lladd/logger/logger2.h>
#include <lladd/truncation.h>
void (*pageWrite)(Page * dat);
void (*pageRead)(Page * ret);
void (*forcePageFile)();
void (*closePageFile)();
int printedForceWarning = 0;
static stasis_handle_t * h;
/**
@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
out, or forcing the log too early?
*/
static void phWrite(Page * ret) {
assert(ret->LSN == pageReadLSN(ret));
if(!ret->dirty) { return; }
LogForce(ret->LSN);
int err = h->write(h, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
if(err) {
printf("Couldn't write to page file: %s\n", strerror(err));
fflush(stdout);
abort();
}
dirtyPages_remove(ret);
}
static void phRead(Page * ret) {
int err = h->read(h, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
if(err) {
if(err == EDOM) {
// tried to read off end of file...
memset(ret->memAddr, 0, PAGE_SIZE);
} else {
printf("Couldn't read from page file: %s\n", strerror(err));
fflush(stdout);
abort();
}
}
ret->dirty = 0;
ret->LSN = *lsn_ptr(ret);
}
static void phForce() {
if(!printedForceWarning) {
printf("Warning! pageHandle can't force the page file yet!\n");
fflush(stdout);
}
}
static void phClose() {
int err = h->close(h);
if(err) {
printf("Couldn't close page file: %s\n", strerror(err));
fflush(stdout);
abort();
}
}
void pageHandleOpen(stasis_handle_t * handle) {
pageWrite = phWrite;
pageRead = phRead;
forcePageFile = phForce;
closePageFile = phClose;
h = handle;
}