ContigousMemory / memories / FirstFitMemory.cpp
FirstFitMemory.cpp
Raw
#include "FauxMemory.imp.h"

class FitFirstMemory : public FauxMemory {

  public:

  // Constructor
  FitFirstMemory(int size) : FauxMemory(size) {strategy = "First fit";};


  // Malloc
   bool allocMem(ProgramBlock* new_block){
    // Increment BID (block id) , sort of like a PID.
    this->incrementBid();
    

    // Check if the new block is indeed the next in the sequence.
    if((*this->getBid()) != new_block->getId()){
      return false;
    }


    // Check if new block > available free space in memory.
    if (new_block->getSize() > (*this->getFree())){
      return false;
    }

    // Make sure new block size is not negative or zero.
    if (new_block->getSize() < 1){
      return false;
    }       

    // Look through blocks to find first available hole block.
    // Must be of adequate size for allocation to happen.
    for(int i = 0; i<(*this->getAllBlocks()).size(); i++){

      // Declare the current block for readability
      MemBlock* currBlock = (*this->getAllBlocks())[i];


      // Check if Hole Block (identified by negative id)
      if(currBlock->getId() == -1){


        // Make sure program block is smaller than the found hole block.
        if(new_block->getSize() <= currBlock->getSize()) {
        

          // Set new block id for a valid block.
          // Copy start address and work out end address.
          // Reduce address by one since we count the start block
          new_block->setStart(currBlock->getStart());
          new_block->setEnd(currBlock->getStart() + new_block->getSize() - 1);



          // Add the new block (as pointer) at the "correct" position in "memory" (sorting)
          // Done for pretty print, since logic dictates if block is valid.
          // Valid blocks store their own addresses.
          this->getAllBlocks()->insert(this->getAllBlocks()->begin() + i, new_block);

          // Reduce the free space var;
          this->setFree((*this->getFree()) - new_block->getSize());
          
          //Case program block < hole block:
          if (new_block->getSize() < currBlock->getSize()) {
            
            // "Create" a smaller hole block.
            // Same end, but different start.
            // +1 for start address since addresses can't overlap.
            currBlock->setStart(new_block->getEnd() + 1);


            // Set size according to start and end
            currBlock->resize();

          }
          //Case equal:
            else {
            // Erase the hole block at index i + 1 since we used .insert()
            this->getAllBlocks()->erase(this->getAllBlocks()->begin() + i + 1);
            delete currBlock;
          }
          // Confirm valid allocation.
          return true;
        };
      };
    };
    // No free blocks available.
    return false; 
  };
};