private bool ReleaseReference(long id)
{
try {
lock (fixedList) {
// Update the record in the fixed list.
IArea block = fixedList.GetRecord(id);
var recordPos = block.Position;
int status = block.ReadInt4();
if (status != 1)
throw new Exception("Assertion failed: Record is not static (status = " + status + ")");
int refCount = block.ReadInt4();
if (refCount == 0)
throw new Exception("Releasing when IBlob reference counter is at 0.");
var objSize = block.ReadInt8();
var objFinalSize = block.ReadInt8();
var objPos = block.ReadInt8();
// If reference count == 0 then we need to free all the resources
// associated with this object in the store.
if ((refCount - 1) == 0) {
// Free the resources associated with this object.
IArea area = store.GetArea(objPos);
area.ReadInt4();
var type = (byte)area.ReadInt4();
var totalSize = area.ReadInt8();
var pageCount = area.ReadInt8();
// Free all of the pages in this blob.
for (long i = 0; i < pageCount; ++i) {
long pageOffset = area.ReadInt8();
if (pageOffset > 0)
store.DeleteArea(pageOffset);
}
// Free the blob area object itself.
store.DeleteArea(objPos);
// Write out the blank record.
block.Position = recordPos;
block.WriteInt4(DeletedFlag);
block.WriteInt4(0);
block.WriteInt8(-1);
block.WriteInt8(firstDeleteChainRecord);
// CHeck out these changes
block.Flush();
firstDeleteChainRecord = id;
// Update the first_delete_chain_record field in the header
fixedList.WriteDeleteHead(firstDeleteChainRecord);
return true;
}
// Simply decrement the reference counter for this record.
block.Position = recordPos + 4;
// Write the reference count - 1
block.WriteInt4(refCount - 1);
// Check out this change
block.Flush();
return false;
}
} catch (IOException e) {
throw new Exception("IO Error: " + e.Message);
}
}