void oamAllocReset(OamState *oam) { //allocate the buffer if null if(oam->allocBuffer == NULL) { oam->allocBuffer = (AllocHeader*)malloc(sizeof(AllocHeader) * oam->allocBufferSize); } AH(0)->nextFree = 1024; AH(0)->size = 1024; }
static int simpleAlloc(OamState *oam, int size) { if(oam->allocBuffer == NULL) { oamAllocReset(oam); } u16 curOffset = oam->firstFree; //check for out of memory if(oam->firstFree >= 1024 || oam->firstFree == -1) { oam->firstFree = -1; return -1; } int misalignment = curOffset & (size - 1); if(misalignment) misalignment = size - misalignment; int next = oam->firstFree; int last = next; //find a big enough block while(AH(next)->size - misalignment < size) { curOffset = AH(next)->nextFree; misalignment = curOffset & (size - 1); if(misalignment) misalignment = size - misalignment; if(curOffset >= 1024) { return -1; } last = next; next = curOffset; } //next should now point to a large enough block and last should point to the block prior ////align to block size if(misalignment) { int tempSize = AH(next)->size; int tempNextFree = AH(next)->nextFree; curOffset += misalignment; AH(next)->size = misalignment; AH(next)->nextFree = curOffset; last = next; next = curOffset; AH(next)->size = tempSize - misalignment; AH(next)->nextFree = tempNextFree; } //is the block the first free block if(curOffset == oam->firstFree) { if(AH(next)->size == size) { oam->firstFree = AH(next)->nextFree; } else { oam->firstFree = curOffset + size; AH(oam->firstFree)->nextFree = AH(next)->nextFree; AH(oam->firstFree)->size = AH(next)->size - size; } } else { if(AH(next)->size == size) { AH(last)->nextFree = AH(next)->nextFree; } else { AH(last)->nextFree = curOffset + size; AH(curOffset + size)->nextFree = AH(next)->nextFree; AH(curOffset + size)->size = AH(next)->size - size; } } AH(next)->size = size; return curOffset; }
static void simpleFree(OamState *oam, int index) { u16 curOffset = oam->firstFree; int next = oam->firstFree; int current = index; //if we were out of memory its trivial if(oam->firstFree == -1 || oam->firstFree >= 1024) { oam->firstFree = index; AH(current)->nextFree = 1024; return; } //if this index is before the first free block its also trivial if(index < oam->firstFree) { //check for abutment and combine if necessary if(index + AH(current)->size == oam->firstFree) { AH(current)->size += AH(next)->size; AH(current)->nextFree = AH(next)->nextFree; } else { AH(current)->nextFree = oam->firstFree; } oam->firstFree = index; return; } //otherwise locate the free block prior to index while(index > AH(next)->nextFree) { curOffset = AH(next)->nextFree; next = AH(next)->nextFree; } //check if the next free block and current can be appended // [curOffset] [index] [next->nextFree] // next | ~ | current | ~ | nextFree //check if current abuts nextFree if(AH(next)->nextFree == index + AH(current)->size && AH(next)->nextFree < 1024) { AH(current)->size += AH(AH(next)->nextFree)->size; AH(current)->nextFree = AH(AH(next)->nextFree)->nextFree; } else { AH(current)->nextFree = AH(next)->nextFree; } //check if current abuts previous free block if (curOffset + AH(next)->size == index) { AH(next)->size += AH(current)->size; AH(next)->nextFree = AH(current)->nextFree; } else { AH(next)->nextFree = index; } }
// Test out the heap implementation -- with max heap int main(int argc, char** argv) { int i, j; int n; Int* A[20]; Int* B[20]; Int C[10] = {73, 6, 57, 88, 60, 34, 83, 72, 48, 85}; heap<Int*, maxIntsCompare> BH(B, 0, 20); heap<Int, maxIntCompare> Test(C, 10, 10); if (argc != 2) { cout << "Usage: heap <heapsize>\n"; exit(-1); } n = atoi(argv[1]); if (n > 20) { cout << "heap size " << n << " too big.\n"; exit(-1); } Randomize(); for (i=0; i<n; i++) A[i] = new Int(i); permute(A, n); cout << "Initial values:\n"; for (i=0; i<n; i++) { cout << A[i] << " "; if (i == 9) cout << "\n"; } cout << "\n\n"; for (i=0; i<n; i++) BH.insert(A[i]); for (i=0; i<BH.size(); i++) { cout << B[i] << " "; if (i == 9) cout << "\n"; } cout << "\n\n"; heap<Int*, maxIntsCompare> AH(A, n, 20); Int* AHval = NULL; for (i=0; i<AH.size(); i++) { cout << A[i] << " "; if (i == 9) cout << "\n"; } cout << "\n\n"; AHval = AH.removefirst(); cout << "Max value: " << AHval << "\n"; for (i=0; i<AH.size(); i++) { cout << A[i] << " "; if (i == 9) cout << "\n"; } cout << "\n\n"; AHval = AH.removefirst(); cout << "Max value: " << AHval << "\n"; for (i=0; i<AH.size(); i++) { cout << A[i] << " "; if (i == 9) cout << "\n"; } cout << "\n\n"; AHval = AH.remove(2); cout << "Remove value: " << AHval << "\n"; for (i=0; i<AH.size(); i++) { cout << A[i] << " "; if (i == 9) cout << "\n"; } cout << "\n"; for (i=0; i<10; i++) cout << C[i] << " "; cout << "\n"; Int Testval; for (j=0; j<10; j++) { Testval = Test.removefirst(); for (i=0; i<10; i++) cout << C[i] << " "; cout << "\n"; } return 0; }