byte * stasis_record_write_begin(int xid, Page * p, recordid rid) { int page_type = p->pageType; assert(page_type); if(p->pageType != SLOTTED_LATCH_FREE_PAGE) { assert(stasis_record_length_read(xid, p, rid) == stasis_record_type_to_size(rid.size)); } return page_impls[page_type].recordWrite(xid, p, rid); }
void stasis_record_write(int xid, Page * p, recordid rid, const byte *dat) { assert( (p->id == rid.page) && (p->memAddr != NULL) ); assert(rid.size <= BLOB_THRESHOLD_SIZE); byte * buf = stasis_record_write_begin(xid, p, rid); memcpy(buf, dat, stasis_record_type_to_size(rid.size)); stasis_record_write_done(xid,p,rid,buf); assert( (p->id == rid.page) && (p->memAddr != NULL) ); }
static int operate_helper(int xid, Page * p, recordid rid) { if(stasis_record_type_read(xid, p, rid) == INVALID_SLOT) { stasis_record_alloc_done(xid, p, rid); } assert(stasis_record_length_read(xid, p, rid) == stasis_record_type_to_size(rid.size)); if(rid.size < 0) { assert(stasis_record_type_read(xid,p,rid) == rid.size); } return 0; }
static int blkSize(block_t * b) { genericBlockImpl * impl = (genericBlockImpl*)b->impl; return stasis_record_type_to_size(impl->pos.size); }
recordid Talloc(int xid, unsigned long size) { stasis_alloc_t* alloc = stasis_runtime_alloc_state(); short type; if(size >= BLOB_THRESHOLD_SIZE) { type = BLOB_SLOT; } else { assert(size >= 0); type = size; } recordid rid; pthread_mutex_lock(&alloc->mut); pageid_t pageid = stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid, stasis_record_type_to_size(type)); if(pageid == INVALID_PAGE) { stasis_alloc_reserve_new_region(alloc, xid); pageid = stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid, stasis_record_type_to_size(type)); } alloc->lastFreepage = pageid; Page * p = loadPage(xid, alloc->lastFreepage); writelock(p->rwlatch, 0); int rec_size = stasis_record_type_to_size(type); if(rec_size < 4) { rec_size = 4; } while(stasis_record_freespace(xid, p) < rec_size) { stasis_record_compact(p); int newFreespace = stasis_record_freespace(xid, p); if(newFreespace >= rec_size) { break; } unlock(p->rwlatch); stasis_allocation_policy_update_freespace(alloc->allocPolicy, pageid, newFreespace); releasePage(p); pageid = stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid, rec_size); if(pageid == INVALID_PAGE) { stasis_alloc_reserve_new_region(alloc, xid); pageid = stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid, rec_size); } alloc->lastFreepage = pageid; p = loadPage(xid, alloc->lastFreepage); writelock(p->rwlatch, 0); } rid = stasis_record_alloc_begin(xid, p, type); assert(rid.size != INVALID_SLOT); stasis_record_alloc_done(xid, p, rid); int newFreespace = stasis_record_freespace(xid, p); stasis_allocation_policy_alloced_from_page(alloc->allocPolicy, xid, pageid); stasis_allocation_policy_update_freespace(alloc->allocPolicy, pageid, newFreespace); unlock(p->rwlatch); alloc_arg a = { rid.slot, type }; Tupdate(xid, rid.page, &a, sizeof(a), OPERATION_ALLOC); if(type == BLOB_SLOT) { rid.size = size; stasis_blob_alloc(xid, rid); } releasePage(p); pthread_mutex_unlock(&alloc->mut); stasis_transaction_table_set_argument(alloc->xact_table, xid, alloc->callback_id, AT_COMMIT, alloc); return rid; // TODO return NULLRID on error }