private NewUnusedSegment growHeap(LayerWriteGroup tx, int length)
{
long new_addr;
FreespaceExtent newblock_info;
// make an atomic write-group to "carve off" a pending chunk
LayerWriteGroup carveoff_wg =
tx.mylayer.newWriteGroup(type: LayerWriteGroup.WriteGroupType.DISK_ATOMIC_NOFLUSH);
// lock to make sure two threads don't carve off at the same time...
lock (this) {
// HACK: currently we just grab off the top of heap
new_addr = next_allocation;
next_allocation = next_allocation + (long)length;
if (new_addr <= 0) {
throw new Exception("invalid address in allocateNewSegment: " + new_addr);
}
newblock_info = new FreespaceExtent();
newblock_info.start_addr = new_addr;
newblock_info.end_addr = new_addr + length;
// add the pending chunk
carveoff_wg.setValue(this.pendingKeyForAddr(new_addr),
RecordUpdate.WithPayload(newblock_info.pack()));
Console.WriteLine("allocateNewSegment - next address: " + new_addr);
// add our new top of heap pointer
{
RecordKey key = new RecordKey().appendParsedKey(".ROOT/FREELIST/HEAD");
carveoff_wg.setValue(key, RecordUpdate.WithPayload(Lsd.numberToLsd(next_allocation, 13)));
}
// commit the metadata tx
carveoff_wg.finish();
}
return new NewUnusedSegment(store,newblock_info);
}