reuse rewind buffers

This commit is contained in:
zeromus 2013-08-24 23:00:33 +00:00
parent cec62d38f5
commit cfd3f05f1e
1 changed files with 61 additions and 29 deletions

View File

@ -29,10 +29,16 @@ namespace BizHawk.MultiClient
{ {
mStream.Dispose(); mStream.Dispose();
mStream = null; mStream = null;
if (mAllocatedBuffer != null)
mBufferManage(mAllocatedBuffer, 0, false);
} }
Func<byte[], long, bool, byte[]> mBufferManage;
byte[] mAllocatedBuffer;
public StreamBlobDatabase(bool onDisk, long capacity) public StreamBlobDatabase(bool onDisk, long capacity, Func<byte[],long,bool,byte[]> BufferManage)
{ {
this.mBufferManage = BufferManage;
mCapacity = capacity; mCapacity = capacity;
if (onDisk) if (onDisk)
{ {
@ -45,8 +51,8 @@ namespace BizHawk.MultiClient
} }
else else
{ {
var buffer = new byte[capacity]; mAllocatedBuffer = mBufferManage(null, capacity, true);
mStream = new MemoryStream(buffer); mStream = new MemoryStream(mAllocatedBuffer);
} }
} }
@ -220,31 +226,31 @@ namespace BizHawk.MultiClient
} }
} }
void Test() //void Test()
{ //{
var sbb = new StreamBlobDatabase(false, Global.Config.Rewind_BufferSize * 1024 * 1024); // var sbb = new StreamBlobDatabase(false, Global.Config.Rewind_BufferSize * 1024 * 1024);
var rand = new Random(0); // var rand = new Random(0);
int timestamp = 0; // int timestamp = 0;
for (; ; ) // for (; ; )
{ // {
long test = sbb.Enqueue(timestamp, rand.Next(100 * 1024)); // long test = sbb.Enqueue(timestamp, rand.Next(100 * 1024));
if (rand.Next(10) == 0) // if (rand.Next(10) == 0)
if (sbb.Count != 0) sbb.Dequeue(); // if (sbb.Count != 0) sbb.Dequeue();
if (rand.Next(10) == 0) // if (rand.Next(10) == 0)
if (sbb.Count != 0) sbb.Pop(); // if (sbb.Count != 0) sbb.Pop();
if (rand.Next(50) == 1) // if (rand.Next(50) == 1)
{ // {
while (sbb.Count != 0) // while (sbb.Count != 0)
{ // {
Console.WriteLine("ZAM!!!"); // Console.WriteLine("ZAM!!!");
sbb.Dequeue(); // sbb.Dequeue();
} // }
} // }
sbb.AssertMonotonic(); // sbb.AssertMonotonic();
timestamp++; // timestamp++;
Console.WriteLine("{0}, {1}", test, sbb.Count); // Console.WriteLine("{0}, {1}", test, sbb.Count);
} // }
} //}
} //class StreamBlobDatabase } //class StreamBlobDatabase
class RewindThreader : IDisposable class RewindThreader : IDisposable
@ -440,13 +446,39 @@ namespace BizHawk.MultiClient
if (rewind_enabled) if (rewind_enabled)
{ {
long cap = Global.Config.Rewind_BufferSize * (long)1024 * (long)1024; 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) if (RewindThread != null)
RewindThread.Dispose(); RewindThread.Dispose();
RewindThread = new RewindThreader(this, Global.Config.Rewind_IsThreaded); 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) void CaptureRewindStateNonDelta(byte[] CurrentState)
{ {
long offset = RewindBuf.Enqueue(0, CurrentState.Length + 1); long offset = RewindBuf.Enqueue(0, CurrentState.Length + 1);