public override void ApplySlotChanges(IVisitable slotChangeTree, int slotChangeCount , Slot reservedSlot) { if (slotChangeCount > 0) { Slot transactionLogSlot = SlotLongEnoughForLog(slotChangeCount, reservedSlot) ? reservedSlot : AllocateSlot(true, slotChangeCount); StatefulBuffer buffer = new StatefulBuffer(_container.SystemTransaction(), transactionLogSlot ); buffer.WriteInt(transactionLogSlot.Length()); buffer.WriteInt(slotChangeCount); AppendSlotChanges(buffer, slotChangeTree); buffer.Write(); IRunnable commitHook = _container.CommitHook(); FlushDatabaseFile(); _container.WriteTransactionPointer(transactionLogSlot.Address()); FlushDatabaseFile(); if (WriteSlots(slotChangeTree)) { FlushDatabaseFile(); } _container.WriteTransactionPointer(0); commitHook.Run(); FlushDatabaseFile(); if (transactionLogSlot != reservedSlot) { FreeSlot(transactionLogSlot); } } FreeSlot(reservedSlot); }
public override void WriteFixedPart(LocalObjectContainer file, bool startFileLockingThread , bool shuttingDown, StatefulBuffer writer, int blockSize) { SystemData systemData = file.SystemData(); writer.Append(Signature); writer.WriteByte(Version()); writer.WriteInt((int)TimeToWrite(_timerFileLock.OpenTime(), shuttingDown)); writer.WriteLong(TimeToWrite(_timerFileLock.OpenTime(), shuttingDown)); writer.WriteLong(TimeToWrite(Runtime.CurrentTimeMillis(), shuttingDown)); writer.WriteInt(blockSize); writer.WriteInt(systemData.ClassCollectionID()); writer.WriteByte(systemData.IdSystemType()); writer.WriteInt(((FileHeaderVariablePart2)_variablePart).Address()); writer.WriteInt(((FileHeaderVariablePart2)_variablePart).Length()); writer.WriteInt(_transactionPointerAddress); writer.Write(); if (shuttingDown) { WriteVariablePart(file, true); } else { file.SyncFiles(); } if (startFileLockingThread) { file.ThreadPool().Start("db4o lock thread", _timerFileLock); } }
// When a file gets opened, it uses the file size to determine where // new slots can be appended. If this method would not be called, the // freespace system could already contain a slot that points beyond // the end of the file and this space could be allocated and used twice, // for instance if a slot was allocated and freed without ever being // written to file. internal virtual void EnsureLastSlotWritten() { if (_blockEndAddress > _blockConverter.BytesToBlocks(FileLength())) { StatefulBuffer writer = CreateStatefulBuffer(SystemTransaction(), _blockEndAddress - 1, BlockSize()); writer.Write(); } }
protected virtual void WriteTransactionPointer(Transaction systemTransaction, int transactionPointer, int address, int offset) { StatefulBuffer bytes = new StatefulBuffer(systemTransaction, address, TransactionPointerLength ); bytes.MoveForward(offset); bytes.WriteInt(transactionPointer); bytes.WriteInt(transactionPointer); // Dangerous write. // On corruption transaction pointers will not be the same and nothing will happen. bytes.Write(); }