private void Free(long pointer)
{
// Get the area header
var headerInfo = new long[2];
ReadAreaHeader(pointer, headerInfo);
if ((headerInfo[0] & DeletedFlag) != 0)
throw new IOException("Area already marked as unallocated.");
// If (pointer + size) reaches the end of the header area, set this as the
// wilderness.
bool setAsWilderness = ((pointer + headerInfo[0]) >= DataAreaEndOffset);
var rOffset = pointer;
var freeingAreaSize = headerInfo[0];
var rSize = freeingAreaSize;
// Can this area coalesce?
var headerInfo2 = new long[2];
var leftPointer = GetPreviousAreaHeader(pointer, headerInfo2);
var coalesc = false;
if ((headerInfo2[0] & DeletedFlag) != 0) {
// Yes, we can coalesce left
long areaSize = (headerInfo2[0] & ActiveFlag);
rOffset = leftPointer;
rSize = rSize + areaSize;
// Remove left area from the bin
RemoveFromBinChain(leftPointer, areaSize);
coalesc = true;
}
if (!setAsWilderness) {
long rightPointer = GetNextAreaHeader(pointer, headerInfo2);
if ((headerInfo2[0] & DeletedFlag) != 0) {
// Yes, we can coalesce right
long areaSize = (headerInfo2[0] & ActiveFlag);
rSize = rSize + areaSize;
// Remove right from the bin
RemoveFromBinChain(rightPointer, areaSize);
setAsWilderness = (rightPointer == WildernessOffset);
coalesc = true;
}
}
// If we are coalescing parent areas
if (coalesc)
CoalesceArea(rOffset, rSize);
// Add this new area to the bin chain,
AddToBinChain(rOffset, rSize);
// Do we set this as the wilderness?
if (setAsWilderness)
WildernessOffset = rOffset;
totalAllocatedSpace -= freeingAreaSize;
}