private void FlushTrimmedTransactionLog() { byte[] transactionBuffer; using (var ms = new MemoryStream()) { ms.Write(Constants.StartTransactionSeparator, 0, Constants.StartTransactionSeparator.Length); var count = BitConverter.GetBytes(EstimatedCountOfItemsInQueue); ms.Write(count, 0, count.Length); var checkedOut = checkedOutEntries.ToArray(); foreach (var entry in checkedOut) { WriteEntryToTransactionLog(ms, entry, OperationType.Enqueue); } var listedEntries = entries.ToArray(); foreach (var entry in listedEntries) { WriteEntryToTransactionLog(ms, entry, OperationType.Enqueue); } ms.Write(Constants.EndTransactionSeparator, 0, Constants.EndTransactionSeparator.Length); ms.Flush(); transactionBuffer = ms.ToArray(); } Atomic.Write(TransactionLog, stream => { stream.SetLength(transactionBuffer.Length); stream.Write(transactionBuffer, 0, transactionBuffer.Length); }); }
public void CommitTransaction(ICollection <Operation> operations) { if (operations.Count == 0) { return; } byte[] transactionBuffer = GenerateTransactionBuffer(operations); lock (transactionLogLock) { long txLogSize; using (var stream = WaitForTransactionLog(transactionBuffer)) { stream.Write(transactionBuffer, 0, transactionBuffer.Length); txLogSize = stream.Position; stream.Flush(); } ApplyTransactionOperations(operations); TrimTransactionLogIfNeeded(txLogSize); Atomic.Write(Meta, stream => { var bytes = BitConverter.GetBytes(CurrentFileNumber); stream.Write(bytes, 0, bytes.Length); bytes = BitConverter.GetBytes(CurrentFilePosition); stream.Write(bytes, 0, bytes.Length); }); if (ParanoidFlushing) { FlushTrimmedTransactionLog(); } } }