private long AddToRecordList(long recordOffset)
{
lock (fixedList) {
// If there is no free deleted records in the delete chain,
if (firstDeleteChainRecord == -1) {
// Increase the size of the list structure.
fixedList.IncreaseSize();
// The start record of the new size
int newBlockNumber = fixedList.BlockCount - 1;
long startIndex = fixedList.BlockFirstPosition(newBlockNumber);
long sizeOfBlock = fixedList.BlockNodeCount(newBlockNumber);
// The IArea object for the new position
IArea a = fixedList.GetRecord(startIndex);
a.WriteInt4(0);
a.WriteInt4(0);
a.WriteInt8(-1); // Initially unknown size
a.WriteInt8(0); // Initially unknown current size
a.WriteInt8(recordOffset);
// Set the rest of the block as deleted records
for (long n = 1; n < sizeOfBlock - 1; ++n) {
a.WriteInt4(DeletedFlag);
a.WriteInt4(0);
a.WriteInt8(-1);
a.WriteInt8(startIndex + n + 1);
}
// The last block is end of delete chain.
a.WriteInt4(DeletedFlag);
a.WriteInt4(0);
a.WriteInt8(-1);
a.WriteInt8(-1);
// Check out the changes.
a.Flush();
// And set the new delete chain
firstDeleteChainRecord = startIndex + 1;
fixedList.WriteDeleteHead(firstDeleteChainRecord);
// Return pointer to the record we just added.
return startIndex;
}
// Pull free block from the delete chain and recycle it.
long recycledRecord = firstDeleteChainRecord;
IArea block = fixedList.GetRecord(recycledRecord);
var recordPos = block.Position;
// Status of the recycled block
int status = block.ReadInt4();
if ((status & DeletedFlag) == 0)
throw new InvalidOperationException("Assertion failed: record is not deleted!");
// Reference count (currently unused in delete chains).
block.ReadInt4();
// The size (should be -1);
block.ReadInt8();
// The current size should be 0
block.ReadInt8();
// The pointer to the next in the chain.
long nextChain = block.ReadInt8();
firstDeleteChainRecord = nextChain;
// Update the first_delete_chain_record field in the header
fixedList.WriteDeleteHead(firstDeleteChainRecord);
// Update the block
block.Position = recordPos;
block.WriteInt4(0);
block.WriteInt4(0);
block.WriteInt8(-1); // Initially unknown size
block.WriteInt8(0);
block.WriteInt8(recordOffset);
// Check out the changes
block.Flush();
return recycledRecord;
}
}