stasis-aries-wal/src/lladd/operations/alloc.c

101 lines
2.8 KiB
C
Raw Normal View History

2004-06-24 21:10:31 +00:00
#include <lladd/operations/alloc.h>
#include <lladd/page.h>
#include <lladd/bufferManager.h>
#include "../blobManager.h"
2004-06-24 21:10:31 +00:00
/**
Implementation of Talloc() as an operation
This is a bit strange compared to other operations, as it happens
in two phases. The buffer manager reserves space for a record
before the log entry is allocated. Then, the recordid of this
space is written to the log. Finally, alloc tells bufferManager
that it will use the space.
@todo Currently, if the system crashes during an alloc, (before the
log is flushed, but after bufferManager returns a rid), then the
space alloced during the crash is leaked. This doesn't seem to be
too big of a deal, but it should be fixed someday. A more serious
problem results from crashes during blob allocation.
2004-06-24 21:10:31 +00:00
*/
static int operate(int xid, lsn_t lsn, recordid rid, const void * dat) {
if(rid.size >= BLOB_THRESHOLD_SIZE) {
allocBlob(xid, lsn, rid);
} else {
Page loadedPage = loadPage(rid.page);
/** Has no effect during normal operation. */
pageSlotRalloc(loadedPage, lsn, rid);
}
2004-06-24 21:10:31 +00:00
return 0;
}
/** @todo Currently, we just leak store space on dealloc. */
static int deoperate(int xid, lsn_t lsn, recordid rid, const void * dat) {
2004-06-24 21:10:31 +00:00
Page loadedPage = loadPage(rid.page);
/** Has no effect during normal operation, other than updating the LSN. */
pageSlotRalloc(loadedPage, lsn, rid);
2004-06-24 21:10:31 +00:00
return 0;
}
Operation getAlloc() {
Operation o = {
OPERATION_ALLOC, /* ID */
0,
OPERATION_DEALLOC,
&operate
};
return o;
}
2004-06-24 21:10:31 +00:00
recordid Talloc(int xid, size_t size) {
recordid rid;
if(size >= BLOB_THRESHOLD_SIZE) {
rid = preAllocBlob(xid, size);
} else {
/**
@todo we pass lsn -1 into ralloc here. This is a kludge, since we
need to log ralloc's return value, but can't get that return value
until after its executed. When it comes time to perform recovery,
it is possible that this record will be leaked during the undo
phase. We could do a two phase allocation to prevent the leak, but
then we'd need to lock the page that we're allocating a record in,
and that's a pain. Plus, this is a small leak. (There is a similar
problem involving blob allocation, which is more serious, as it may
result in double allocation...)
@todo If this should be the only call to ralloc in lladd, we may consider
removing the lsn parameter someday. (Is there a good reason to
provide users with direct access to ralloc()?)
*/
rid = ralloc(xid, -1, size);
}
2004-06-24 21:10:31 +00:00
Tupdate(xid,rid, NULL, OPERATION_ALLOC);
return rid;
}
Operation getDealloc() {
Operation o = {
OPERATION_DEALLOC,
0,
OPERATION_ALLOC,
&deoperate
};
return o;
}
void Tdealloc(int xid, recordid rid) {
Tupdate(xid, rid, NULL, OPERATION_DEALLOC);
}