Exemple #1
0
TID SPSegment::insert(const Record& r){

	// Find page with enough space for r
    uint64_t pageId = this->lastPage + 1;

    for (auto it = this->fsi.rbegin(); it != this->fsi.rend(); it++) {
        if (it->second >= r.getLen()) {
            pageId = it->first;
            break;
        }
    }

    // If necessary, create new SlottedPage
    BufferFrame frame = bm->fixPage(pageId, true);
    SlottedPage* page = reinterpret_cast<SlottedPage*>(frame.getData());
    if (pageId > this->lastPage) {
        *page = SlottedPage();
        this->lastPage++;
        if (lastPage > 1l << 48) throw "Max page number reached.";
    }

    // TODO Reorder record ?

    // Write to page
    unsigned slotNum = page->insert(r);


    bm->unfixPage(frame, true);

    // Update lastTID
    TID newTID = TID(pageId, slotNum);
    if (newTID.tid > this->lastTID.tid) {
        this->lastTID = newTID;
    }

    // Update FSI
    this->fsi[newTID.getPage()] -= r.getLen() + (slotNum == page->getMaxSlot() ? sizeof(Slot) : 0);

    return newTID;
}
Exemple #2
0
bool SPSegment::update(TID tid, const Record& r){

	Record r_old = this->lookup(tid);

	unsigned len_old = r_old.getLen();
	unsigned len_new = r.getLen();

	BufferFrame frame = bm->fixPage(tid.getPage(), true);
    SlottedPage* page = reinterpret_cast<SlottedPage*>(frame.getData());

    if(len_old == len_new){
        // If size doesn't change, use memcpy
		memcpy(page->getSlot(tid.getSlot())->getRecord(), &r, r.getLen());
	} else if(len_old > len_new){
        // Record has become smaller
		memcpy(page->getSlot(tid.getSlot())->getRecord(), &r, r.getLen());
        // TODO Update freeSpace of page
        // TODO update FSI
	} else {
        // Record has become larger
        unsigned freeSpaceOnPage = page->remove(tid.getSlot());
        this->fsi[tid.getPage()] = freeSpaceOnPage;

        if (freeSpaceOnPage >= len_new) {
            // It fits on the page after removal
			page->insert(r);
    	} else {
            // Even after removal it is too large

            // Get another page
            uint64_t sndPageId = this->lastPage + 1;
            for (auto it = this->fsi.rbegin(); it != this->fsi.rend(); it++) {
                if (it->second >= r.getLen()) {
                    sndPageId = it->first;
                    break;
                }
            }
            BufferFrame sndFrame = bm->fixPage(sndPageId, true);

            // Create a new SlottedPage if necessary
            SlottedPage* sndPage = reinterpret_cast<SlottedPage*>(sndFrame.getData());
            if (sndPageId > this->lastPage) {
                *sndPage = SlottedPage();
                this->lastPage++;
                if (lastPage > 1l << 48) throw "Max page number reached.";
            }

            Slot* fstSlot = page->getSlot(tid.getSlot());
            assert(fstSlot->isEmpty());

            // Insert into new page
            unsigned sndSlotNum = sndPage->insert(r);
            this->fsi[sndPageId] -= r.getLen() + (sndSlotNum == sndPage->getMaxSlot() ? sizeof(Slot) : 0);

            // Update first slot to directo to second page.
            *fstSlot = Slot(TID(sndPageId, sndSlotNum));

            bm->unfixPage(sndFrame, true);
		}
	}
	bm->unfixPage(frame, true);
	return true;
}