Example #1
0
//------------------------------------------------------------------
// HeapPage::DeleteRecord
//
// Input    : Record ID
// Output   : None
// Purpose  : Delete a record from the page
// Return   : OK if successful, FAIL otherwise
//------------------------------------------------------------------
Status HeapPage::DeleteRecord(RecordID rid)
{
    if ((rid.pageNo!=pid) || (rid.slotNo>numOfSlots-1))return FAIL;
    Slot *slot =GetSlotAtIndex(rid.slotNo);
    if (slot->length==INVALID_SLOT) return FAIL;
    if (HasNoOtherValidSlot(rid.slotNo)) { // if it's the only valid slot left
        freeSpace =  freeSpace + numOfSlots* sizeof(Slot)+slot->length;
        freePtr = HEAPPAGE_DATA_SIZE - 1; // reset freePtr
        numOfSlots=0;
    }
    else {
        if (SmallestOffset() == slot->offset) freePtr += slot->length; // increase freePtr if deleted record is the last
        if (rid.slotNo==numOfSlots-1) { // if it's the last slot
            //delete slot;
            numOfSlots--;
            freeSpace = freeSpace + sizeof(Slot)+slot->length;
            int k=numOfSlots-1;
            while (k>=0) { //  delete previous slots (that are now the last ones) that might be invalid
                if (SlotIsEmpty(GetSlotAtIndex(k))) {
                    numOfSlots--;
                    freeSpace += sizeof(Slot);
                }
                else break;
                k--;
            }
        }
        else {   // if it's just a normal slot
            freeSpace=freeSpace+slot->length;
            slot ->length= INVALID_SLOT;
        }
    }
    return OK;
}
Example #2
0
//------------------------------------------------------------------
// HeapPage::IsEmpty
//
// Input    : None
// Output   : None
// Purpose  : Check if there is any record in the page.
// Return   : true if the HeapPage is empty, and false otherwise.
//------------------------------------------------------------------
bool HeapPage::IsEmpty(void)
{
    for (int i=0; i<numOfSlots; i++) {
        if (!SlotIsEmpty(GetSlotAtIndex(i))) return false;
    }
    return true;
}
Example #3
0
//------------------------------------------------------------------
// HeapPage::HasNoOtherValidSlot
//
// Input    : Index of the slot that's checked against
// Output   : If all slots before it are invalid, false otherwise
// Purpose  : A helper function for DeleteRecord
// Return   : True if all slots before it are invalid, false otherwise
//------------------------------------------------------------------
bool HeapPage::HasNoOtherValidSlot(int slotNO)
{
    for (int i=0; i<numOfSlots; i++) {
        if ((i!=slotNO)&&(!SlotIsEmpty(GetSlotAtIndex(i)))) return false;
    }
    return true;
}
Example #4
0
//------------------------------------------------------------------
// HeapPage::GetNumOfRecords
//
// Input    : None
// Output   : None.
// Purpose  : To determine the number of records on the page (not necessarily equal to the number of slots).
// Return   : The number of records in the page.
//------------------------------------------------------------------
int HeapPage::GetNumOfRecords()
{
    int num = 0;
    for (int i=0; i<numOfSlots; i++) {
        if (!SlotIsEmpty(GetSlotAtIndex(i))) num++;
    }
    return num;
}
Example #5
0
//------------------------------------------------------------------
// HeapPage::FirstRecord
//
// Input    : None
// Output   : record id of the first record on a page
// Purpose  : To find the first record on a page
// Return   : OK if successful, DONE otherwise
//------------------------------------------------------------------
Status HeapPage::FirstRecord(RecordID& rid)
{
    for (short i=0; i<numOfSlots; i++) {
        if (!SlotIsEmpty(GetSlotAtIndex(i))) {
            rid.pageNo = pid;
            rid.slotNo = i;
            return OK;
        }
    }
    return DONE;
}
Example #6
0
//------------------------------------------------------------------
// HeapPage::NextRecord
//
// Input    : ID of the current record
// Output   : ID of the next record
// Return   : Return DONE if no more records exist on the page;
//            otherwise OK
//------------------------------------------------------------------
Status HeapPage::NextRecord (RecordID curRid, RecordID& nextRid)
{
    if (curRid.pageNo != pid || curRid.slotNo < 0 || curRid.slotNo >= numOfSlots) return FAIL;
    for (short i=curRid.slotNo+1; i<numOfSlots; i++) {
        if (!SlotIsEmpty(GetSlotAtIndex(i))) {
            nextRid.pageNo = pid;
            nextRid.slotNo = i;
            return OK;
        }
    }
    return DONE;
}
Example #7
0
//-------------------------------------------------------------------
// SortedKVPage::CutFromRecord
//
// Input   : relativeStartOffset, The offset relative to the start of the
//                                record at which to start cutting.
//           length,              The length of data to cut.
//           rid,                 The record id of the record in which to cut.
// Output  : None.
// Return  : OK    if successful.
//           FAIL  if rid is invalid or tries
//                 to cut after the end of the record.
// Purpose : Cuts data from an existing record and compacts appropriately.
//-------------------------------------------------------------------
Status ResizableRecordPage::CutFromRecord(int relativeStartOffset,
										  int length,
										  const RecordID &rid)
{
	if (rid.pageNo != pid || rid.slotNo < 0 || rid.slotNo >= numOfSlots) {
		return FAIL;
	}

	Slot *slot = GetFirstSlotPointer() - rid.slotNo;


	// Use the DeleteRecord method to cut the entire record.
	if ((relativeStartOffset == 0) && (length == slot->length)) {

		std::cout << "Returning HeapPage::DeleteRecord " << rid.pageNo << ", "  << rid.slotNo << std::endl;
		return HeapPage::DeleteRecord(rid);
	}

	if (relativeStartOffset + length > slot->length) {
		std::cerr << "Error: Trying to cut too much from record."
				  << "Record length=" << slot->length << std::endl;
		return FAIL;
	}

	// Move data up to fill in cut region.
	int mvLength = freePtr - (slot->offset + relativeStartOffset + length);
	char *src = data + slot->offset + relativeStartOffset + length;
	char *dest = data + slot->offset + relativeStartOffset;
	memmove(dest, src, mvLength);

	// Update free space appropriately.
	freePtr -= length;
	freeSpace += length;

	slot->length -= length;

	// Update offsets for slots following deleted region.
	for (int k = 0; k < numOfSlots; k++) {
		assert(!SlotIsEmpty(GetFirstSlotPointer() - k));
		Slot *curSlot = GetFirstSlotPointer() - k;

		if (curSlot->offset > slot->offset) {
			curSlot->offset -= length;
		}
	}

	return OK;
}
Example #8
0
//-------------------------------------------------------------------
// SortedKVPage::AppendToRecord
//
// Input   : newData,    A pointer to the data to append.
//           dataLength, The length of the data to append.
//           rid,        The record id of the record to append to.
// Output  : None.
// Return  : OK    if successful.
//           FAIL  if rid is invalid or there isn't space on this page.
// Purpose : Appends data to an existing record, shifting other
//           records as appropriate.
//-------------------------------------------------------------------
Status ResizableRecordPage::AppendToRecord(const char *newData, int dataLength, const RecordID &rid)
{
	// Invalid record id.
	if (rid.pageNo != pid || (rid.slotNo < 0 || rid.slotNo > numOfSlots)) {
		return FAIL;
	}

	// Not enough space to append new data.
	if (AvailableSpaceForAppend() < dataLength) {
		return FAIL;
	}

	Slot *slot = (Slot *)GetFirstSlotPointer() - rid.slotNo;

	// Move records following the target location to make space.
	memmove(data + slot->offset + slot->length + dataLength,
			data + slot->offset + slot->length,
			freePtr - (slot->offset + slot->length));

	// Copy data to append to appropriate spot on page.
	memcpy(data + slot->offset + slot->length, newData, dataLength);

	slot->length += dataLength;

	//	Change the offset of all slots pointing to pages after the one we modified.
	for (int i = 0; i < numOfSlots; i++) {
		assert(!SlotIsEmpty(GetFirstSlotPointer() - i));
		Slot *curSlot = GetFirstSlotPointer() - i;

		if (curSlot->offset > slot->offset) {
			curSlot->offset += dataLength;
		}
	}

	// Update freePtr and freeSpace appropriately.
	freePtr += dataLength;
	freeSpace -= dataLength;

	return OK;
}