stasis-aries-wal/src/stasis/page/fixed.c

171 lines
4.5 KiB
C
Raw Normal View History

2007-06-07 21:53:09 +00:00
#include <assert.h>
#include "../page.h"
#include "fixed.h"
2007-06-07 21:53:09 +00:00
/** @todo should page implementations provide readLSN / writeLSN??? */
#include <stasis/truncation.h>
2007-06-07 21:53:09 +00:00
int fixedRecordsPerPage(size_t size) {
return (USABLE_SIZE_OF_PAGE - 2*sizeof(short)) / size;
}
/** @todo CORRECTNESS Locking for fixedPageInitialize? (should hold writelock)*/
void fixedPageInitialize(Page * page, size_t size, int count) {
2007-06-07 21:53:09 +00:00
assertlocked(page->rwlatch);
// XXX fixed page asserts it's been given an UNINITIALIZED_PAGE... Why doesn't that crash?
assert(*page_type_ptr(page) == UNINITIALIZED_PAGE);
*page_type_ptr(page) = FIXED_PAGE;
*recordsize_ptr(page) = size;
2007-06-07 21:53:09 +00:00
assert(count <= fixedRecordsPerPage(size));
*recordcount_ptr(page)= count;
}
2007-06-07 21:53:09 +00:00
static int checkRidWarnedAboutUninitializedKludge = 0;
static void checkRid(Page * page, recordid rid) {
assertlocked(page->rwlatch);
2007-06-07 21:53:09 +00:00
if(! *page_type_ptr(page)) {
if(!checkRidWarnedAboutUninitializedKludge) {
checkRidWarnedAboutUninitializedKludge = 1;
printf("KLUDGE detected in checkRid. Fix it ASAP\n");
fflush(stdout);
}
fixedPageInitialize(page, rid.size, fixedRecordsPerPage(rid.size));
}
assert(page->id == rid.page);
assert(*recordsize_ptr(page) == rid.size);
assert(fixedRecordsPerPage(rid.size) > rid.slot);
}
2007-06-07 21:53:09 +00:00
//-------------- New API below this line
static const byte* fixedRead(int xid, Page *p, recordid rid) {
assertlocked(p->rwlatch);
checkRid(p, rid);
assert(rid.slot < *recordcount_ptr(p));
return fixed_record_ptr(p, rid.slot);
}
2007-06-07 21:53:09 +00:00
static byte* fixedWrite(int xid, Page *p, recordid rid) {
assertlocked(p->rwlatch);
checkRid(p, rid);
assert(rid.slot < *recordcount_ptr(p));
return fixed_record_ptr(p, rid.slot);
}
2007-06-07 21:53:09 +00:00
static int fixedGetType(int xid, Page *p, recordid rid) {
assertlocked(p->rwlatch);
// checkRid(p, rid);
if(rid.slot < *recordcount_ptr(p)) {
int type = *recordsize_ptr(p);
if(type > 0) {
type = NORMAL_SLOT;
}
return type;
} else {
2007-06-07 21:53:09 +00:00
return INVALID_SLOT;
}
}
2007-06-07 21:53:09 +00:00
static void fixedSetType(int xid, Page *p, recordid rid, int type) {
assertlocked(p->rwlatch);
checkRid(p,rid);
assert(rid.slot < *recordcount_ptr(p));
assert(physical_slot_length(type) == physical_slot_length(*recordsize_ptr(p)));
*recordsize_ptr(p) = rid.size;
}
static int fixedGetLength(int xid, Page *p, recordid rid) {
assertlocked(p->rwlatch);
assert(*page_type_ptr(p));
return rid.slot > *recordcount_ptr(p) ?
2007-06-07 21:53:09 +00:00
INVALID_SLOT : physical_slot_length(*recordsize_ptr(p));
}
static int notSupported(int xid, Page * p) { return 0; }
2007-06-07 21:53:09 +00:00
static int fixedFreespace(int xid, Page * p) {
assertlocked(p->rwlatch);
if(fixedRecordsPerPage(*recordsize_ptr(p)) > *recordcount_ptr(p)) {
// Return the size of a slot; that's the biggest record we can take.
return physical_slot_length(*recordsize_ptr(p));
} else {
2007-06-07 21:53:09 +00:00
// Page full; return zero.
return 0;
}
}
2007-06-07 21:53:09 +00:00
static void fixedCompact(Page * p) {
// no-op
}
static recordid fixedPreAlloc(int xid, Page *p, int size) {
assertlocked(p->rwlatch);
if(fixedRecordsPerPage(*recordsize_ptr(p)) > *recordcount_ptr(p)) {
recordid rid;
rid.page = p->id;
rid.slot = *recordcount_ptr(p);
rid.size = *recordsize_ptr(p);
return rid;
} else {
return NULLRID;
}
}
2007-06-07 21:53:09 +00:00
static void fixedPostAlloc(int xid, Page *p, recordid rid) {
assertlocked(p->rwlatch);
assert(*recordcount_ptr(p) == rid.slot);
assert(*recordsize_ptr(p) == rid.size);
(*recordcount_ptr(p))++;
}
2007-06-07 21:53:09 +00:00
static void fixedFree(int xid, Page *p, recordid rid) {
assertlocked(p->rwlatch);
if(*recordsize_ptr(p) == rid.slot+1) {
(*recordsize_ptr(p))--;
} else {
// leak space; there's no way to track it with this page format.
}
}
// XXX dereferenceRID
void fixedLoaded(Page *p) {
p->LSN = *lsn_ptr(p);
}
void fixedFlushed(Page *p) {
*lsn_ptr(p) = p->LSN;
2007-06-07 21:53:09 +00:00
}
page_impl fixedImpl() {
static page_impl pi = {
FIXED_PAGE,
fixedRead,
fixedWrite,
0,// readDone
0,// writeDone
2007-06-07 21:53:09 +00:00
fixedGetType,
fixedSetType,
fixedGetLength,
fixedFirst,
fixedNext,
notSupported, // notSupported,
pageGenericBlockFirst,
pageGenericBlockNext,
pageGenericBlockDone,
2007-06-07 21:53:09 +00:00
fixedFreespace,
fixedCompact,
fixedPreAlloc,
fixedPostAlloc,
fixedFree,
0, // XXX dereference
fixedLoaded, // loaded
fixedFlushed, // flushed
2007-06-07 21:53:09 +00:00
};
return pi;
}
/**
@todo arrayListImpl belongs in arrayList.c
*/
page_impl arrayListImpl() {
2007-06-07 21:53:09 +00:00
page_impl pi = fixedImpl();
pi.page_type = ARRAY_LIST_PAGE;
return pi;
}
2007-06-07 21:53:09 +00:00
void fixedPageInit() { }
void fixedPageDeinit() { }