diff --git a/BizHawk.MultiClient/Rewind.cs b/BizHawk.MultiClient/Rewind.cs index 03c2305c54..78192592fb 100644 --- a/BizHawk.MultiClient/Rewind.cs +++ b/BizHawk.MultiClient/Rewind.cs @@ -29,10 +29,16 @@ namespace BizHawk.MultiClient { mStream.Dispose(); mStream = null; + if (mAllocatedBuffer != null) + mBufferManage(mAllocatedBuffer, 0, false); } + + Func mBufferManage; + byte[] mAllocatedBuffer; - public StreamBlobDatabase(bool onDisk, long capacity) + public StreamBlobDatabase(bool onDisk, long capacity, Func BufferManage) { + this.mBufferManage = BufferManage; mCapacity = capacity; if (onDisk) { @@ -45,8 +51,8 @@ namespace BizHawk.MultiClient } else { - var buffer = new byte[capacity]; - mStream = new MemoryStream(buffer); + mAllocatedBuffer = mBufferManage(null, capacity, true); + mStream = new MemoryStream(mAllocatedBuffer); } } @@ -220,31 +226,31 @@ namespace BizHawk.MultiClient } } - void Test() - { - var sbb = new StreamBlobDatabase(false, Global.Config.Rewind_BufferSize * 1024 * 1024); - var rand = new Random(0); - int timestamp = 0; - for (; ; ) - { - long test = sbb.Enqueue(timestamp, rand.Next(100 * 1024)); - if (rand.Next(10) == 0) - if (sbb.Count != 0) sbb.Dequeue(); - if (rand.Next(10) == 0) - if (sbb.Count != 0) sbb.Pop(); - if (rand.Next(50) == 1) - { - while (sbb.Count != 0) - { - Console.WriteLine("ZAM!!!"); - sbb.Dequeue(); - } - } - sbb.AssertMonotonic(); - timestamp++; - Console.WriteLine("{0}, {1}", test, sbb.Count); - } - } + //void Test() + //{ + // var sbb = new StreamBlobDatabase(false, Global.Config.Rewind_BufferSize * 1024 * 1024); + // var rand = new Random(0); + // int timestamp = 0; + // for (; ; ) + // { + // long test = sbb.Enqueue(timestamp, rand.Next(100 * 1024)); + // if (rand.Next(10) == 0) + // if (sbb.Count != 0) sbb.Dequeue(); + // if (rand.Next(10) == 0) + // if (sbb.Count != 0) sbb.Pop(); + // if (rand.Next(50) == 1) + // { + // while (sbb.Count != 0) + // { + // Console.WriteLine("ZAM!!!"); + // sbb.Dequeue(); + // } + // } + // sbb.AssertMonotonic(); + // timestamp++; + // Console.WriteLine("{0}, {1}", test, sbb.Count); + // } + //} } //class StreamBlobDatabase class RewindThreader : IDisposable @@ -440,13 +446,39 @@ namespace BizHawk.MultiClient if (rewind_enabled) { long cap = Global.Config.Rewind_BufferSize * (long)1024 * (long)1024; - RewindBuf = new StreamBlobDatabase(Global.Config.Rewind_OnDisk, cap); + + if(RewindBuf != null) + RewindBuf.Dispose(); + RewindBuf = new StreamBlobDatabase(Global.Config.Rewind_OnDisk, cap, BufferManage); + if (RewindThread != null) RewindThread.Dispose(); RewindThread = new RewindThreader(this, Global.Config.Rewind_IsThreaded); } } + byte[] RewindFellationBuf; + byte[] BufferManage(byte[] inbuf, long size, bool allocate) + { + if (allocate) + { + //if we have an appropriate buffer free, return it + if (RewindFellationBuf != null && RewindFellationBuf.LongLength == size) + { + byte[] ret = RewindFellationBuf; + RewindFellationBuf = null; + return ret; + } + //otherwise, allocate it + return new byte[size]; + } + else + { + RewindFellationBuf = inbuf; + return null; + } + } + void CaptureRewindStateNonDelta(byte[] CurrentState) { long offset = RewindBuf.Enqueue(0, CurrentState.Length + 1);