/* * Main goals: * 1. No copies, ever. States are deposited directly to, and read directly from, one giant ring buffer. * As a consequence, there is no multi-threading because there is nothing to thread. * 2. Support for arbitrary and changeable state sizes. Frequency is calculated dynamically. * 3. No delta compression. Keep it simple. If there are cores that benefit heavily from delta compression, we should * maintain a separate rewinder alongside this one that is customized for those cores. */ public ZwinderBuffer(IRewindSettings settings) { if (settings == null) { throw new ArgumentException("ZwinderBuffer's settings cannot be null."); } long targetSize = settings.BufferSize * 1024 * 1024; if (settings.TargetFrameLength < 1) { throw new ArgumentOutOfRangeException(nameof(settings.TargetFrameLength)); } Size = 1L << (int)Math.Floor(Math.Log(targetSize, 2)); _sizeMask = Size - 1; _backingStoreType = settings.BackingStore; switch (settings.BackingStore) { case IRewindSettings.BackingStoreType.Memory: { var buffer = new MemoryBlock((ulong)Size); buffer.Protect(buffer.Start, buffer.Size, MemoryBlock.Protection.RW); _disposables.Add(buffer); _backingStore = new MemoryViewStream(true, true, (long)buffer.Start, (long)buffer.Size); _disposables.Add(_backingStore); break; } case IRewindSettings.BackingStoreType.TempFile: { var filename = TempFileManager.GetTempFilename("ZwinderBuffer"); var filestream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose); filestream.SetLength(Size); _backingStore = filestream; _disposables.Add(filestream); break; } default: throw new ArgumentException("Unsupported store type for ZwinderBuffer."); } if (settings.UseFixedRewindInterval) { _fixedRewindInterval = true; _targetRewindInterval = settings.TargetRewindInterval; } else { _fixedRewindInterval = false; _targetFrameLength = settings.TargetFrameLength; } _allowOutOfOrderStates = settings.AllowOutOfOrderStates; _states = new StateInfo[STATEMASK + 1]; _useCompression = settings.UseCompression; }
/* * Main goals: * 1. No copies, ever. States are deposited directly to, and read directly from, one giant ring buffer. * As a consequence, there is no multi-threading because there is nothing to thread. * 2. Support for arbitrary and changeable state sizes. Frequency is calculated dynamically. * 3. No delta compression. Keep it simple. If there are cores that benefit heavily from delta compression, we should * maintain a separate rewinder alongside this one that is customized for those cores. */ public ZwinderBuffer(IRewindSettings settings) { long targetSize = settings.BufferSize * 1024 * 1024; if (settings.TargetFrameLength < 1) { throw new ArgumentOutOfRangeException(nameof(settings.TargetFrameLength)); } Size = 1L << (int)Math.Floor(Math.Log(targetSize, 2)); _sizeMask = Size - 1; _buffer = new byte[Size]; _targetFrameLength = settings.TargetFrameLength; _states = new StateInfo[StateMask + 1]; _useCompression = settings.UseCompression; }
/* * Main goals: * 1. No copies, ever. States are deposited directly to, and read directly from, one giant ring buffer. * As a consequence, there is no multi-threading because there is nothing to thread. * 2. Support for arbitrary and changeable state sizes. Frequency is calculated dynamically. * 3. No delta compression. Keep it simple. If there are cores that benefit heavily from delta compression, we should * maintain a separate rewinder alongside this one that is customized for those cores. */ public ZwinderBuffer(IRewindSettings settings) { long targetSize = settings.BufferSize * 1024 * 1024; if (settings.TargetFrameLength < 1) { throw new ArgumentOutOfRangeException(nameof(settings.TargetFrameLength)); } Size = 1L << (int)Math.Floor(Math.Log(targetSize, 2)); _sizeMask = Size - 1; _buffer = new MemoryBlock((ulong)Size); _buffer.Protect(_buffer.Start, _buffer.Size, MemoryBlock.Protection.RW); _targetFrameLength = settings.TargetFrameLength; _states = new StateInfo[STATEMASK + 1]; _useCompression = settings.UseCompression; }
public Zwinder(IStatable stateSource, IRewindSettings settings) { _buffer = new ZwinderBuffer(settings); _stateSource = stateSource; Active = true; }