2007-06-07 21:53:09 +00:00
|
|
|
#include <assert.h>
|
2004-10-06 06:08:09 +00:00
|
|
|
#include "../page.h"
|
|
|
|
#include "fixed.h"
|
2007-06-07 21:53:09 +00:00
|
|
|
/** @todo should page implementations provide readLSN / writeLSN??? */
|
2007-06-11 21:36:57 +00:00
|
|
|
#include <stasis/truncation.h>
|
2004-10-06 06:08:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2007-06-07 21:53:09 +00:00
|
|
|
int fixedRecordsPerPage(size_t size) {
|
2004-10-06 06:08:09 +00:00
|
|
|
return (USABLE_SIZE_OF_PAGE - 2*sizeof(short)) / size;
|
|
|
|
}
|
2005-02-02 02:12:40 +00:00
|
|
|
/** @todo CORRECTNESS Locking for fixedPageInitialize? (should hold writelock)*/
|
2004-10-06 06:08:09 +00:00
|
|
|
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?
|
2004-10-06 06:08:09 +00:00
|
|
|
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));
|
2004-10-06 06:08:09 +00:00
|
|
|
*recordcount_ptr(page)= count;
|
|
|
|
}
|
|
|
|
|
2007-06-07 21:53:09 +00:00
|
|
|
static int checkRidWarnedAboutUninitializedKludge = 0;
|
|
|
|
static void checkRid(Page * page, recordid rid) {
|
2007-06-01 21:32:33 +00:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2004-10-06 06:08:09 +00:00
|
|
|
assert(*page_type_ptr(page) == FIXED_PAGE || *page_type_ptr(page) == ARRAY_LIST_PAGE);
|
2007-06-07 21:53:09 +00:00
|
|
|
assert(page->id == rid.page);
|
|
|
|
assert(*recordsize_ptr(page) == rid.size);
|
|
|
|
assert(fixedRecordsPerPage(rid.size) > rid.slot);
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
|
|
|
|
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);
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
2004-10-06 06:08:09 +00:00
|
|
|
|
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;
|
2004-10-06 06:08:09 +00:00
|
|
|
} else {
|
2007-06-07 21:53:09 +00:00
|
|
|
return INVALID_SLOT;
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
|
|
|
}
|
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);
|
|
|
|
//XXX this should be here... assert(rid.slot < *recordcount_ptr(p));
|
|
|
|
checkRid(p, rid); // <-- XXX KLUDGE checkRid init's the page if necessary...
|
|
|
|
return rid.slot > *recordcount_ptr(p) ?
|
|
|
|
INVALID_SLOT : physical_slot_length(*recordsize_ptr(p));
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
2007-06-07 21:53:09 +00:00
|
|
|
/* XXXstatic recordid fixedFirst(int xid, Page *p, recordid rid) {
|
2004-10-06 06:08:09 +00:00
|
|
|
|
2007-06-07 21:53:09 +00:00
|
|
|
}
|
|
|
|
static recordid fixedNext(int xid, Page *p, recordid rid) {
|
|
|
|
|
|
|
|
} */
|
|
|
|
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));
|
2004-10-19 04:45:42 +00:00
|
|
|
} else {
|
2007-06-07 21:53:09 +00:00
|
|
|
// Page full; return zero.
|
|
|
|
return 0;
|
2004-10-19 04:45:42 +00:00
|
|
|
}
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
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;
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
|
|
|
}
|
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))++;
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
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.
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-07 21:53:09 +00:00
|
|
|
//// XXX missing some functions w/ murky futures.
|
|
|
|
/* static lsn_t fixedReadLSN(int xid, Page * p) {
|
|
|
|
return p->LSN;
|
|
|
|
}
|
|
|
|
static void fixedWriteLSN(int xid, Page * p, lsn_t lsn) {
|
|
|
|
p->LSN = lsn;
|
|
|
|
*lsn_ptr(p) = lsn;
|
|
|
|
dirtyPages_add(p);
|
|
|
|
} */
|
|
|
|
page_impl fixedImpl() {
|
|
|
|
static page_impl pi = {
|
|
|
|
FIXED_PAGE,
|
|
|
|
fixedRead,
|
|
|
|
fixedWrite,
|
|
|
|
fixedGetType,
|
|
|
|
fixedSetType,
|
|
|
|
fixedGetLength,
|
|
|
|
0, // fixedFirst,
|
|
|
|
0, // fixedNext,
|
|
|
|
0, // notSupported,
|
|
|
|
0, // block first
|
|
|
|
0, // block next
|
|
|
|
fixedFreespace,
|
|
|
|
fixedCompact,
|
|
|
|
fixedPreAlloc,
|
|
|
|
fixedPostAlloc,
|
|
|
|
fixedFree,
|
|
|
|
0, // XXX dereference
|
|
|
|
0, // loaded
|
|
|
|
0, // flushed
|
|
|
|
};
|
|
|
|
return pi;
|
|
|
|
}
|
2004-10-06 06:08:09 +00:00
|
|
|
|
2007-06-07 21:53:09 +00:00
|
|
|
page_impl arrayListImpl() {
|
|
|
|
page_impl pi = fixedImpl();
|
|
|
|
pi.page_type = ARRAY_LIST_PAGE;
|
|
|
|
return pi;
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
2007-06-07 21:53:09 +00:00
|
|
|
|
|
|
|
void fixedPageInit() { }
|
|
|
|
void fixedPageDeinit() { }
|