Stage 7

Inserting records into a relation -> Iterate through the blocks of the relation and find a free slot or allocate a new block of all the blocks are full.

Store the contents of the record in the appropriate slot in the block and update the slotmap

Update the relation catalog/cache to reflect the change in number of records. This entails a write back of the update cache to the corresponding buffer of catalog blocks

    int BlockAccess::insert(int relId, Attribute *record) {
    RelCatEntry relCatEntry;
    int blockNum = relCatEntry.firstBlk;
    RecId rec_id = {-1,-1};
    int prevBlockNum = -1;
    while(blockNum != -1) {
        unsigned char* slotMap
        getSlotMap(slotMap);
        for(int i = 0; i < header.numSlots; i++) {
            block = blockNum;
            slot = i;
            break;
        }
        if(block != -1 and slot != -1) break;
        prevBlockNum = blockNum;
        blockNum = header.rblock;
    }
    if(block == -1 and slot == -1) {
        // new block required for the relation
        if(relId = RELCAT_RELID) return E_MAXRELATIONS;
        BlockBuffer blockBuffer;
        blockNum = blockBuffer.getBlockNum();

        block = blockNum;
        slot = 0;
        // setting the header;
        HeadInfo header;
        header.pblock = -1
        if(relCatEntry.numRecs == 0) {
            header.lblock = prevBlockNum;
        } else hreader.lblock = -1;
        header.rblock = -1;
        header.blockType = REC;
        header.numAttrs = relCatEntry.numAttrs;
        header.numSlots = relCatEntry.numSlotsPerBlk;
        blockBuffer.setHeader(&blockHeader);

        // setting slotmap
        unsigned char* slotMap;
        for(int i = 0; i < relCatEntry.numSlotsPerBlk; i++) {
            slotMap[i] = SLOT_UNOCCUPIED;
        }
        blockBuffer.setSlotMap(slotMap);
        if(prevBlockNum != - 1) {
            RecBuffer prevBuffer(prevBlockNum);
            getHeader(&prevHeader);
            prevHeader.rblock = blockNum;
            setHeader(&prevHeader);
        } else {
            // first block for the relation 
            relCatEntry.firstBlk = rec_id.block;
            setRelCatEntry(relId,&relCatEntry);

        }
        // inserting the record
        RecBuffer buffer(rec_id.block);
        buffer.setRecord(record, rec_id.slot);
        unsigned char* slotMap;
        getSlotMap(slotMap);
        slotMap[slot] = SLOT_OCCUPIED;

        // setting headers and relCatEntry
        HeadInfo header;
        buffer.getheader(&header);
        header.numEntries+=-1;
        setHeader(&header);
        relCatEntry.numRecs++;
        setRelCatEntry(relId, &relCatEntry);

    }
}

int BlockBuffer::getFreeBlock(int blockType);

int BlockBuffer::setHeader(HeadInfo *head);
    int BlockBuffer::setBlockType(int blockType) {
    *((int32_t*)bufferPtr) = blockType;
}
int BlockBuffer::BlockBuffer(char blockType) {
    int block_type = blockType == 'R' ? REC : UNUSED_BLK;
    int blockNum = getFreeBlock(block_type);
    if(err) {
        this->blockNum = blockNum;
    }
    this->blockNum = blockNum;
}
int BlockBuffer::getFreeBlock(int blockType) {
    for(int i = 0; i < DISK_BLOCKS; i++) {
        if(StaticBuffer::blockAllocMap[i] == UNUSED_BLK) {
            break;
        }
    }
    // set the header
}