Adds style cop (#109)

This commit is contained in:
Kamron Batman 2020-04-26 00:16:02 -07:00 • committed by GitHub
parent 3e715bcb60
commit 556a17aba8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1725 changed files with 33831 additions and 38046 deletions

View file

@ -33,14 +33,14 @@ namespace Server
protected override int BufferSize => 512;
public int CommitTo(SequentialFileWriter dataFile, SequentialFileWriter indexFile, int typeCode, uint serial)
public int CommitTo(SequentialFileWriterStream dataFile, SequentialFileWriterStream indexFile, int typeCode, uint serial)
{
Flush();
byte[] buffer = stream.GetBuffer();
int length = (int)stream.Length;
var buffer = stream.GetBuffer();
var length = (int)stream.Length;
long position = dataFile.Position;
var position = dataFile.Position;
dataFile.Write(buffer, 0, length);

View file

@ -30,7 +30,7 @@ namespace Server
{
PermitBackgroundWrite = permitBackgroundWrite;
Thread saveThread = new Thread(delegate() { SaveItems(); });
var saveThread = new Thread(SaveItems);
saveThread.Name = "Item Save Subset";
saveThread.Start();
@ -40,9 +40,8 @@ namespace Server
saveThread.Join();
if (permitBackgroundWrite && UseSequentialWriters
) //If we're permitted to write in the background, but we don't anyways, then notify.
if (permitBackgroundWrite && UseSequentialWriters) // If we're permitted to write in the background, but we don't anyways, then notify.
World.NotifyDiskWriteComplete();
}
}
}
}

View file

@ -18,7 +18,6 @@
*
***************************************************************************/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -30,14 +29,14 @@ namespace Server
public sealed class DynamicSaveStrategy : SaveStrategy
{
private readonly ConcurrentBag<Item> _decayBag;
private SequentialFileWriter _guildData, _guildIndex;
private SequentialFileWriterStream _guildData, _guildIndex;
private readonly BlockingCollection<QueuedMemoryWriter> _guildThreadWriters;
private SequentialFileWriter _itemData, _itemIndex;
private SequentialFileWriterStream _itemData, _itemIndex;
private readonly BlockingCollection<QueuedMemoryWriter> _itemThreadWriters;
private SequentialFileWriter _mobileData, _mobileIndex;
private SequentialFileWriterStream _mobileData, _mobileIndex;
private readonly BlockingCollection<QueuedMemoryWriter> _mobileThreadWriters;
public DynamicSaveStrategy()
@ -54,7 +53,7 @@ namespace Server
{
OpenFiles();
Task[] saveTasks = new Task[3];
var saveTasks = new Task[3];
saveTasks[0] = SaveItems();
saveTasks[1] = SaveMobiles();
@ -64,25 +63,28 @@ namespace Server
if (permitBackgroundWrite)
{
//This option makes it finish the writing to disk in the background, continuing even after Save() returns.
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
// This option makes it finish the writing to disk in the background, continuing even after Save() returns.
Task.Factory.ContinueWhenAll(saveTasks, _ =>
{
CloseFiles();
World.NotifyDiskWriteComplete();
});
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
}
else
{
Task.WaitAll(saveTasks); //Waits for the completion of all of the tasks(committing to disk)
Task.WaitAll(saveTasks); // Waits for the completion of all of the tasks(committing to disk)
CloseFiles();
}
}
private Task StartCommitTask(BlockingCollection<QueuedMemoryWriter> threadWriter, SequentialFileWriter data,
SequentialFileWriter index)
private Task StartCommitTask(BlockingCollection<QueuedMemoryWriter> threadWriter, SequentialFileWriterStream data,
SequentialFileWriterStream index)
{
Task commitTask = Task.Factory.StartNew(() =>
#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler *
var commitTask = Task.Factory.StartNew(() =>
{
while (!threadWriter.IsCompleted)
{
@ -94,33 +96,34 @@ namespace Server
}
catch (InvalidOperationException)
{
//Per MSDN, it's fine if we're here, successful completion of adding can rarely put us into this state.
// Per MSDN, it's fine if we're here, successful completion of adding can rarely put us into this state.
break;
}
writer.CommitTo(data, index);
}
});
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
return commitTask;
}
private Task SaveItems()
{
//Start the blocking consumer; this runs in background.
Task commitTask = StartCommitTask(_itemThreadWriters, _itemData, _itemIndex);
// Start the blocking consumer; this runs in background.
var commitTask = StartCommitTask(_itemThreadWriters, _itemData, _itemIndex);
IEnumerable<Item> items = World.Items.Values;
//Start the producer.
// Start the producer.
Parallel.ForEach(items, () => new QueuedMemoryWriter(),
(item, state, writer) =>
{
long startPosition = writer.Position;
var startPosition = writer.Position;
item.Serialize(writer);
int size = (int)(writer.Position - startPosition);
var size = (int)(writer.Position - startPosition);
writer.QueueForIndex(item, size);
@ -136,27 +139,27 @@ namespace Server
_itemThreadWriters.Add(writer);
});
_itemThreadWriters.CompleteAdding(); //We only get here after the Parallel.ForEach completes. Lets our task
_itemThreadWriters.CompleteAdding(); // We only get here after the Parallel.ForEach completes. Lets our task
return commitTask;
}
private Task SaveMobiles()
{
//Start the blocking consumer; this runs in background.
Task commitTask = StartCommitTask(_mobileThreadWriters, _mobileData, _mobileIndex);
// Start the blocking consumer; this runs in background.
var commitTask = StartCommitTask(_mobileThreadWriters, _mobileData, _mobileIndex);
IEnumerable<Mobile> mobiles = World.Mobiles.Values;
//Start the producer.
// Start the producer.
Parallel.ForEach(mobiles, () => new QueuedMemoryWriter(),
(mobile, state, writer) =>
{
long startPosition = writer.Position;
var startPosition = writer.Position;
mobile.Serialize(writer);
int size = (int)(writer.Position - startPosition);
var size = (int)(writer.Position - startPosition);
writer.QueueForIndex(mobile, size);
@ -170,27 +173,27 @@ namespace Server
});
_mobileThreadWriters
.CompleteAdding(); //We only get here after the Parallel.ForEach completes. Lets our task tell the consumer that we're done
.CompleteAdding(); // We only get here after the Parallel.ForEach completes. Lets our task tell the consumer that we're done
return commitTask;
}
private Task SaveGuilds()
{
//Start the blocking consumer; this runs in background.
Task commitTask = StartCommitTask(_guildThreadWriters, _guildData, _guildIndex);
// Start the blocking consumer; this runs in background.
var commitTask = StartCommitTask(_guildThreadWriters, _guildData, _guildIndex);
IEnumerable<BaseGuild> guilds = BaseGuild.List.Values;
//Start the producer.
// Start the producer.
Parallel.ForEach(guilds, () => new QueuedMemoryWriter(),
(guild, state, writer) =>
{
long startPosition = writer.Position;
var startPosition = writer.Position;
guild.Serialize(writer);
int size = (int)(writer.Position - startPosition);
var size = (int)(writer.Position - startPosition);
writer.QueueForIndex(guild, size);
@ -203,28 +206,28 @@ namespace Server
_guildThreadWriters.Add(writer);
});
_guildThreadWriters.CompleteAdding(); //We only get here after the Parallel.ForEach completes. Lets our task
_guildThreadWriters.CompleteAdding(); // We only get here after the Parallel.ForEach completes. Lets our task
return commitTask;
}
public override void ProcessDecay()
{
while (_decayBag.TryTake(out Item item))
while (_decayBag.TryTake(out var item))
if (item.OnDecay())
item.Delete();
}
private void OpenFiles()
{
_itemData = new SequentialFileWriter(World.ItemDataPath);
_itemIndex = new SequentialFileWriter(World.ItemIndexPath);
_itemData = new SequentialFileWriterStream(World.ItemDataPath);
_itemIndex = new SequentialFileWriterStream(World.ItemIndexPath);
_mobileData = new SequentialFileWriter(World.MobileDataPath);
_mobileIndex = new SequentialFileWriter(World.MobileIndexPath);
_mobileData = new SequentialFileWriterStream(World.MobileDataPath);
_mobileIndex = new SequentialFileWriterStream(World.MobileIndexPath);
_guildData = new SequentialFileWriter(World.GuildDataPath);
_guildIndex = new SequentialFileWriter(World.GuildIndexPath);
_guildData = new SequentialFileWriterStream(World.GuildDataPath);
_guildIndex = new SequentialFileWriterStream(World.GuildIndexPath);
WriteCount(_itemIndex, World.Items.Count);
WriteCount(_mobileIndex, World.Mobiles.Count);
@ -243,10 +246,10 @@ namespace Server
_guildIndex.Close();
}
private void WriteCount(SequentialFileWriter indexFile, int count)
private void WriteCount(SequentialFileWriterStream indexFile, int count)
{
//Equiv to GenericWriter.Write( (int)count );
byte[] buffer = new byte[4];
// Equiv to GenericWriter.Write( (int)count );
var buffer = new byte[4];
buffer[0] = (byte)count;
buffer[1] = (byte)(count >> 8);
@ -264,15 +267,15 @@ namespace Server
private void SaveTypeDatabase(string path, List<Type> types)
{
BinaryFileWriter bfw = new BinaryFileWriter(path, false);
var bfw = new BinaryFileWriter(path, false);
bfw.Write(types.Count);
foreach (Type type in types) bfw.Write(type.FullName);
foreach (var type in types) bfw.Write(type.FullName);
bfw.Flush();
bfw.Close();
}
}
}
}

View file

@ -18,7 +18,6 @@
*
***************************************************************************/
using System;
using System.IO;
#if !MONO
@ -34,11 +33,11 @@ namespace Server
public const int KB = 1024;
public const int MB = 1024 * KB;
public static int BufferSize{ get; set; } = 1 * MB;
public static int BufferSize { get; set; } = 1 * MB;
public static int Concurrency{ get; set; } = 1;
public static int Concurrency { get; set; } = 1;
public static bool Unbuffered{ get; set; } = true;
public static bool Unbuffered { get; set; } = true;
public static bool AreSynchronous => Concurrency < 1;
@ -46,7 +45,7 @@ namespace Server
public static FileStream OpenSequentialStream(string path, FileMode mode, FileAccess access, FileShare share)
{
FileOptions options = FileOptions.SequentialScan;
var options = FileOptions.SequentialScan;
if (Concurrency > 0)
options |= FileOptions.Asynchronous;
@ -59,7 +58,7 @@ namespace Server
else
return new FileStream(path, mode, access, share, BufferSize, options);
SafeFileHandle fileHandle =
var fileHandle =
UnsafeNativeMethods.CreateFile(path, (int)access, share, IntPtr.Zero, mode, (int)options, IntPtr.Zero);
if (fileHandle.IsInvalid) throw new IOException();

View file

@ -47,10 +47,12 @@ namespace Server
public FileQueue(int concurrentWrites, FileCommitCallback callback)
{
if (concurrentWrites < 1) throw new ArgumentOutOfRangeException("concurrentWrites");
if (concurrentWrites < 1) throw new ArgumentOutOfRangeException(nameof(concurrentWrites));
if (bufferSize < 1)
throw new ArgumentOutOfRangeException("bufferSize");
#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentOutOfRangeException(nameof(FileOperations.BufferSize));
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
syncRoot = new object();
@ -62,7 +64,7 @@ namespace Server
idle = new ManualResetEvent(true);
}
public long Position{ get; private set; }
public long Position { get; private set; }
public void Dispose()
{
@ -81,7 +83,7 @@ namespace Server
++activeCount;
for (int slot = 0; slot < active.Length; ++slot)
for (var slot = 0; slot < active.Length; ++slot)
if (active[slot] == null)
{
active[slot] = new Chunk(this, slot, page.buffer, 0, page.length);
@ -106,12 +108,12 @@ namespace Server
}
/*lock ( syncRoot ) {
if ( pending.Count > 0 ) {
if (pending.Count > 0 ) {
idle.Reset();
}
for ( int slot = 0; slot < active.Length && pending.Count > 0; ++slot ) {
if ( active[slot] == null ) {
if (active[slot] == null ) {
Page page = pending.Dequeue();
active[slot] = new Chunk( this, slot, page.buffer, 0, page.length );
@ -128,17 +130,17 @@ namespace Server
private void Commit(Chunk chunk, int slot)
{
if (slot < 0 || slot >= active.Length) throw new ArgumentOutOfRangeException("slot");
if (slot < 0 || slot >= active.Length) throw new ArgumentOutOfRangeException(nameof(slot));
lock (syncRoot)
{
if (active[slot] != chunk) throw new ArgumentException();
if (active[slot] != chunk) throw new ArgumentException("active slot is not the current chunk");
ArrayPool<byte>.Shared.Return(chunk.Buffer);
if (pending.Count > 0)
{
Page page = pending.Dequeue();
var page = pending.Dequeue();
active[slot] = new Chunk(this, slot, page.buffer, 0, page.length);
@ -157,11 +159,11 @@ namespace Server
public void Enqueue(byte[] buffer, int offset, int size)
{
if (buffer == null) throw new ArgumentNullException("buffer");
if (buffer == null) throw new ArgumentNullException(nameof(buffer));
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
if (size < 0) throw new ArgumentOutOfRangeException("size");
if (buffer.Length - offset < size) throw new ArgumentException();
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));
if (size < 0) throw new ArgumentOutOfRangeException(nameof(size));
if (buffer.Length - offset < size) throw new ArgumentOutOfRangeException(nameof(offset));
Position += size;
@ -169,9 +171,9 @@ namespace Server
{
buffered.buffer ??= ArrayPool<byte>.Shared.Rent(bufferSize);
byte[] page = buffered.buffer; // buffer page
int pageSpace = page.Length - buffered.length; // available bytes in page
int byteCount = size > pageSpace ? pageSpace : size; // how many bytes we can copy over
var page = buffered.buffer; // buffer page
var pageSpace = page.Length - buffered.length; // available bytes in page
var byteCount = size > pageSpace ? pageSpace : size; // how many bytes we can copy over
Buffer.BlockCopy(buffer, offset, page, buffered.length, byteCount);
@ -192,29 +194,28 @@ namespace Server
public sealed class Chunk
{
private int offset;
private readonly FileQueue owner;
private readonly int slot;
private readonly FileQueue m_Owner;
private readonly int m_Slot;
public Chunk(FileQueue owner, int slot, byte[] buffer, int offset, int size)
{
this.owner = owner;
this.slot = slot;
m_Owner = owner;
m_Slot = slot;
Buffer = buffer;
this.offset = offset;
Offset = offset;
Size = size;
}
public byte[] Buffer{ get; }
public byte[] Buffer { get; }
public int Offset => 0;
public int Offset { get; }
public int Size{ get; }
public int Size { get; }
public void Commit()
{
owner.Commit(this, slot);
m_Owner.Commit(this, m_Slot);
}
}

View file

@ -26,7 +26,7 @@ using Server.Guilds;
namespace Server
{
public sealed class ParallelSaveStrategy : SaveStrategy
public sealed class ParallelSaveStrategy : SaveStrategy, IDisposable
{
private readonly Queue<Item> _decayQueue;
@ -34,11 +34,11 @@ namespace Server
private int cycle;
private bool finished;
private SequentialFileWriter guildData, guildIndex;
private SequentialFileWriterStream guildData, guildIndex;
private SequentialFileWriter itemData, itemIndex;
private SequentialFileWriterStream itemData, itemIndex;
private SequentialFileWriter mobileData, mobileIndex;
private SequentialFileWriterStream mobileData, mobileIndex;
private readonly int processorCount;
@ -59,11 +59,11 @@ namespace Server
consumers = new Consumer[GetThreadCount()];
for (int i = 0; i < consumers.Length; ++i) consumers[i] = new Consumer(this, 256);
for (var i = 0; i < consumers.Length; ++i) consumers[i] = new Consumer(this, 256);
IEnumerable<ISerializable> collection = new Producer();
foreach (ISerializable value in collection)
foreach (var value in collection)
while (!Enqueue(value))
if (!Commit())
Thread.Sleep(0);
@ -75,9 +75,7 @@ namespace Server
WaitHandle.WaitAll(
Array.ConvertAll<Consumer, WaitHandle>(
consumers,
input => input.completionEvent
)
);
input => input.completionEvent));
Commit();
@ -88,7 +86,7 @@ namespace Server
{
while (_decayQueue.Count > 0)
{
Item item = _decayQueue.Dequeue();
var item = _decayQueue.Dequeue();
if (item.OnDecay()) item.Delete();
}
@ -102,11 +100,11 @@ namespace Server
private void SaveTypeDatabase(string path, List<Type> types)
{
BinaryFileWriter bfw = new BinaryFileWriter(path, false);
var bfw = new BinaryFileWriter(path, false);
bfw.Write(types.Count);
foreach (Type type in types) bfw.Write(type.FullName);
foreach (var type in types) bfw.Write(type.FullName);
bfw.Flush();
@ -115,23 +113,23 @@ namespace Server
private void OpenFiles()
{
itemData = new SequentialFileWriter(World.ItemDataPath);
itemIndex = new SequentialFileWriter(World.ItemIndexPath);
itemData = new SequentialFileWriterStream(World.ItemDataPath);
itemIndex = new SequentialFileWriterStream(World.ItemIndexPath);
mobileData = new SequentialFileWriter(World.MobileDataPath);
mobileIndex = new SequentialFileWriter(World.MobileIndexPath);
mobileData = new SequentialFileWriterStream(World.MobileDataPath);
mobileIndex = new SequentialFileWriterStream(World.MobileIndexPath);
guildData = new SequentialFileWriter(World.GuildDataPath);
guildIndex = new SequentialFileWriter(World.GuildIndexPath);
guildData = new SequentialFileWriterStream(World.GuildDataPath);
guildIndex = new SequentialFileWriterStream(World.GuildIndexPath);
WriteCount(itemIndex, World.Items.Count);
WriteCount(mobileIndex, World.Mobiles.Count);
WriteCount(guildIndex, BaseGuild.List.Count);
}
private void WriteCount(SequentialFileWriter indexFile, int count)
private void WriteCount(SequentialFileWriterStream indexFile, int count)
{
byte[] buffer = new byte[4];
var buffer = new byte[4];
buffer[0] = (byte)count;
buffer[1] = (byte)(count >> 8);
@ -157,8 +155,8 @@ namespace Server
private void OnSerialized(ConsumableEntry entry)
{
ISerializable value = entry.value;
BinaryMemoryWriter writer = entry.writer;
var value = entry.value;
var writer = entry.writer;
if (value is Item item)
Save(item, writer);
@ -170,7 +168,7 @@ namespace Server
private void Save(Item item, BinaryMemoryWriter writer)
{
writer.CommitTo(itemData, itemIndex, item.m_TypeRef, item.Serial);
writer.CommitTo(itemData, itemIndex, item.TypeRef, item.Serial);
if (item.Decays && item.Parent == null && item.Map != Map.Internal &&
DateTime.UtcNow > item.LastMoved + item.DecayTime) _decayQueue.Enqueue(item);
@ -178,19 +176,19 @@ namespace Server
private void Save(Mobile mob, BinaryMemoryWriter writer)
{
writer.CommitTo(mobileData, mobileIndex, mob.m_TypeRef, mob.Serial);
writer.CommitTo(mobileData, mobileIndex, mob.TypeRef, mob.Serial);
}
private void Save(BaseGuild guild, BinaryMemoryWriter writer)
{
writer.CommitTo(guildData, guildIndex, 0, guild.Id);
writer.CommitTo(guildData, guildIndex, 0, guild.Serial);
}
private bool Enqueue(ISerializable value)
{
for (int i = 0; i < consumers.Length; ++i)
for (var i = 0; i < consumers.Length; ++i)
{
Consumer consumer = consumers[cycle++ % consumers.Length];
var consumer = consumers[cycle++ % consumers.Length];
if (consumer.tail - consumer.head < consumer.buffer.Length)
{
@ -206,11 +204,11 @@ namespace Server
private bool Commit()
{
bool committed = false;
var committed = false;
for (int i = 0; i < consumers.Length; ++i)
for (var i = 0; i < consumers.Length; ++i)
{
Consumer consumer = consumers[i];
var consumer = consumers[i];
while (consumer.head < consumer.done)
{
@ -239,11 +237,11 @@ namespace Server
public IEnumerator<ISerializable> GetEnumerator()
{
foreach (Item item in items) yield return item;
foreach (var item in items) yield return item;
foreach (Mobile mob in mobiles) yield return mob;
foreach (var mob in mobiles) yield return mob;
foreach (BaseGuild guild in guilds) yield return guild;
foreach (var guild in guilds) yield return guild;
}
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
@ -271,7 +269,7 @@ namespace Server
buffer = new ConsumableEntry[bufferSize];
for (int i = 0; i < buffer.Length; ++i) buffer[i].writer = new BinaryMemoryWriter();
for (var i = 0; i < buffer.Length; ++i) buffer[i].writer = new BinaryMemoryWriter();
completionEvent = new ManualResetEvent(false);
@ -316,5 +314,39 @@ namespace Server
}
}
}
private bool disposedValue = false; // To detect redundant calls
public void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~ParallelSaveStrategy()
// {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
}
}
}

View file

@ -1,10 +1,6 @@
#region References
using System;
using System.IO;
#endregion
namespace Server
{
public static class Persistence
@ -25,8 +21,8 @@ namespace Server
file.Refresh();
using FileStream fs = file.OpenWrite();
BinaryFileWriter writer = new BinaryFileWriter(fs, true);
using var fs = file.OpenWrite();
var writer = new BinaryFileWriter(fs, true);
try
{
@ -79,8 +75,8 @@ namespace Server
file.Refresh();
using FileStream fs = file.OpenRead();
BinaryFileReader reader = new BinaryFileReader(new BinaryReader(fs));
using var fs = file.OpenRead();
var reader = new BinaryFileReader(new BinaryReader(fs));
try
{

View file

@ -1,4 +1,4 @@
/***************************************************************************
/***************************************************************************
* QueuedMemoryWriter.cs
* -------------------
* begin : December 16, 2010
@ -40,36 +40,36 @@ namespace Server
info.size = size;
info.typeCode = serializable.TypeReference; //For guilds, this will automagically be zero.
info.serial = serializable.SerialIdentity;
info.typeCode = serializable.TypeRef; // For guilds, this will automagically be zero.
info.serial = serializable.Serial;
_orderedIndexInfo.Add(info);
}
public void CommitTo(SequentialFileWriter dataFile, SequentialFileWriter indexFile)
public void CommitTo(SequentialFileWriterStream dataFile, SequentialFileWriterStream indexFile)
{
Flush();
int memLength = (int)_memStream.Position;
var memLength = (int)_memStream.Position;
if (memLength > 0)
{
byte[] memBuffer = _memStream.GetBuffer();
var memBuffer = _memStream.GetBuffer();
long actualPosition = dataFile.Position;
var actualPosition = dataFile.Position;
dataFile.Write(memBuffer, 0, memLength); //The buffer contains the data from many items.
dataFile.Write(memBuffer, 0, memLength); // The buffer contains the data from many items.
//Console.WriteLine("Writing {0} bytes starting at {1}, with {2} things", memLength, actualPosition, _orderedIndexInfo.Count);
// Console.WriteLine("Writing {0} bytes starting at {1}, with {2} things", memLength, actualPosition, _orderedIndexInfo.Count);
byte[] indexBuffer = new byte[20];
var indexBuffer = new byte[20];
//int indexWritten = _orderedIndexInfo.Count * indexBuffer.Length;
//int totalWritten = memLength + indexWritten
// int indexWritten = _orderedIndexInfo.Count * indexBuffer.Length;
// int totalWritten = memLength + indexWritten
for (int i = 0; i < _orderedIndexInfo.Count; i++)
for (var i = 0; i < _orderedIndexInfo.Count; i++)
{
IndexInfo info = _orderedIndexInfo[i];
var info = _orderedIndexInfo[i];
indexBuffer[0] = (byte)info.typeCode;
indexBuffer[1] = (byte)(info.typeCode >> 8);
@ -101,7 +101,7 @@ namespace Server
}
}
Close(); //We're done with this writer.
Close(); // We're done with this writer.
}
private struct IndexInfo
@ -111,4 +111,4 @@ namespace Server
public uint serial;
}
}
}
}

View file

@ -22,13 +22,13 @@ namespace Server
{
public abstract class SaveStrategy
{
public abstract string Name{ get; }
public abstract string Name { get; }
public static SaveStrategy Acquire()
{
if (Core.MultiProcessor)
{
int processorCount = Core.ProcessorCount;
var processorCount = Core.ProcessorCount;
if (processorCount > 2)
return
@ -44,4 +44,4 @@ namespace Server
public abstract void ProcessDecay();
}
}
}

View file

@ -23,23 +23,22 @@ using System.IO;
namespace Server
{
public sealed class SequentialFileWriter : Stream
public sealed class SequentialFileWriterStream : Stream
{
private FileQueue fileQueue;
private FileStream fileStream;
private AsyncCallback writeCallback;
public SequentialFileWriter(string path)
public SequentialFileWriterStream(string path)
{
if (path == null) throw new ArgumentNullException("path");
if (path == null) throw new ArgumentNullException(nameof(path));
fileStream = FileOperations.OpenSequentialStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
fileQueue = new FileQueue(
Math.Max(1, FileOperations.Concurrency),
FileCallback
);
FileCallback);
}
public override long Position
@ -74,7 +73,7 @@ namespace Server
private void OnWrite(IAsyncResult asyncResult)
{
FileQueue.Chunk chunk = asyncResult.AsyncState as FileQueue.Chunk;
var chunk = asyncResult.AsyncState as FileQueue.Chunk;
fileStream.EndWrite(asyncResult);

View file

@ -33,7 +33,8 @@ namespace Server
Threaded
}
public static SaveOption SaveType = SaveOption.Normal;
// TODO: Move to configuration
public static SaveOption SaveType => SaveOption.Normal;
private readonly Queue<Item> _decayQueue;
@ -41,7 +42,7 @@ namespace Server
public override string Name => "Standard";
protected bool PermitBackgroundWrite{ get; set; }
protected bool PermitBackgroundWrite { get; set; }
protected bool UseSequentialWriters => SaveType == SaveOption.Normal || !PermitBackgroundWrite;
@ -49,16 +50,17 @@ namespace Server
{
PermitBackgroundWrite = permitBackgroundWrite;
#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler *
Task.WaitAll(Task.Factory.StartNew(SaveMobiles), Task.Factory.StartNew(SaveItems), Task.Factory.StartNew(SaveGuilds));
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
if (permitBackgroundWrite && UseSequentialWriters
) //If we're permitted to write in the background, but we don't anyways, then notify.
if (permitBackgroundWrite && UseSequentialWriters) // If we're permitted to write in the background, but we don't anyways, then notify.
World.NotifyDiskWriteComplete();
}
protected void SaveMobiles()
{
Dictionary<Serial, Mobile> mobiles = World.Mobiles;
var mobiles = World.Mobiles;
IGenericWriter idx;
IGenericWriter tdb;
@ -76,27 +78,28 @@ namespace Server
tdb = new AsyncWriter(World.MobileTypesPath, false);
bin = new AsyncWriter(World.MobileDataPath, true);
}
#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler *
Task.Factory.StartNew(() =>
{
tdb.Write(World.m_MobileTypes.Count);
for (int i = 0; i < World.m_MobileTypes.Count; ++i)
for (var i = 0; i < World.m_MobileTypes.Count; ++i)
tdb.Write(World.m_MobileTypes[i].FullName);
tdb.Close();
});
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
Parallel.ForEach(mobiles.Values, mobile => mobile.Serialize());
#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler *
Task.Factory.StartNew(() =>
{
idx.Write(mobiles.Count);
foreach (Mobile m in mobiles.Values)
foreach (var m in mobiles.Values)
{
long start = bin.Position;
var start = bin.Position;
idx.Write(m.m_TypeRef);
idx.Write(m.TypeRef);
idx.Write(m.Serial);
idx.Write(start);
idx.Write((int)m.SaveBuffer.Position);
@ -108,11 +111,12 @@ namespace Server
idx.Close();
bin.Close();
});
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
}
protected void SaveItems()
{
Dictionary<Serial, Item> items = World.Items;
var items = World.Items;
IGenericWriter idx;
IGenericWriter tdb;
@ -131,24 +135,27 @@ namespace Server
bin = new AsyncWriter(World.ItemDataPath, true);
}
#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler *
Task.Factory.StartNew(() =>
{
tdb.Write(World.m_ItemTypes.Count);
for (int i = 0; i < World.m_ItemTypes.Count; ++i)
for (var i = 0; i < World.m_ItemTypes.Count; ++i)
tdb.Write(World.m_ItemTypes[i].FullName);
tdb.Close();
});
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
Parallel.ForEach(items.Values, item => item.Serialize());
idx.Write(items.Count);
DateTime n = DateTime.UtcNow;
var n = DateTime.UtcNow;
Task.Factory.StartNew(() => {
foreach (Item item in items.Values)
#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler *
Task.Factory.StartNew(() =>
{
foreach (var item in items.Values)
{
if (item.Decays && item.Parent == null && item.Map != Map.Internal && item.LastMoved + item.DecayTime <= n)
{
@ -156,9 +163,9 @@ namespace Server
_decayQueue.Enqueue(item);
}
long start = bin.Position;
var start = bin.Position;
idx.Write(item.m_TypeRef);
idx.Write(item.TypeRef);
idx.Write(item.Serial);
idx.Write(start);
idx.Write((int)item.SaveBuffer.Position);
@ -170,7 +177,9 @@ namespace Server
idx.Close();
bin.Close();
});
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
}
protected void SaveGuilds()
{
IGenericWriter idx;
@ -190,15 +199,15 @@ namespace Server
Parallel.ForEach(BaseGuild.List.Values, guild => guild.Serialize());
idx.Write(BaseGuild.List.Count);
#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler *
Task.Factory.StartNew(() =>
{
foreach (BaseGuild guild in BaseGuild.List.Values)
foreach (var guild in BaseGuild.List.Values)
{
long start = bin.Position;
var start = bin.Position;
idx.Write(0); //guilds have no typeid
idx.Write(guild.Id);
idx.Write(0); // guilds have no typeid
idx.Write(guild.Serial);
idx.Write(start);
idx.Write((int)guild.SaveBuffer.Position);
@ -208,13 +217,14 @@ namespace Server
idx.Close();
bin.Close();
});
#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler *
}
public override void ProcessDecay()
{
while (_decayQueue.Count > 0)
{
Item item = _decayQueue.Dequeue();
var item = _decayQueue.Dequeue();
if (item.OnDecay())
item.Delete();