fix: Removes custom BitArray (#1597)

### Summary

The BitArray class will be optimized over the next several years for various platforms/hardware and maintaining a duplicate for serialization is not practical. Removing the custom implementation. Recommend against using BitArray for serialization unless it is absolutely necessary.
This commit is contained in:
Kamron Batman 2023-11-17 14:37:07 -08:00 committed by GitHub
parent a1dffd10ce
commit e9642d61f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 32 additions and 1489 deletions

View file

@ -1,29 +0,0 @@
using Server.Collections;
using Xunit;
namespace Server.Tests;
public class BitArrayTests
{
[Fact]
public void TestBitArray()
{
var bitArray = new BitArray(700); // Restricted Spells;
bitArray.Set(5, true);
bitArray.Set(39, true);
bitArray.Set(125, true);
// Simulate World Saving
var writer = new BufferWriter(1024, false);
writer.Write(bitArray); // Save it to a file
// Simulate World Loading
var reader = new BufferReader(writer.Buffer);
var bitArrayTest = reader.ReadBitArray();
Assert.Equal(700, bitArrayTest.Length);
for (var i = 0; i < bitArrayTest.Length; i++)
{
Assert.Equal(i is 5 or 39 or 125, bitArrayTest.Get(i));
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -14,9 +14,9 @@
*************************************************************************/ *************************************************************************/
using System; using System;
using System.Collections;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Server.Collections;
namespace Server.Json; namespace Server.Json;

View file

@ -19,7 +19,6 @@ using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using Server.Buffers; using Server.Buffers;
using Server.Collections;
using Server.Logging; using Server.Logging;
using Server.Text; using Server.Text;
@ -166,15 +165,6 @@ public class BinaryFileReader : IGenericReader, IDisposable
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Read(Span<byte> buffer) => _reader.Read(buffer); public int Read(Span<byte> buffer) => _reader.Read(buffer);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BitArray ReadBitArray()
{
var length = ((IGenericReader)this).ReadEncodedInt();
// BinaryReader doesn't expose a Span slice of the buffer, so we use a custom ctor
return new BitArray(_reader, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public long Seek(long offset, SeekOrigin origin) => _reader.BaseStream.Seek(offset, origin); public long Seek(long offset, SeekOrigin origin) => _reader.BaseStream.Seek(offset, origin);

View file

@ -15,6 +15,7 @@
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@ -221,21 +222,6 @@ public class BufferReader : IGenericReader
return length; return length;
} }
public BitArray ReadBitArray()
{
var bitLength = ((IGenericReader)this).ReadEncodedInt();
var length = BitArray.GetByteArrayLengthFromBitLength(bitLength);
if (length > _buffer.Length - _position)
{
throw new OutOfMemoryException();
}
var bitArray = new BitArray(_buffer.AsSpan(_position, length), bitLength);
_position += length;
return bitArray;
}
public virtual long Seek(long offset, SeekOrigin origin) public virtual long Seek(long offset, SeekOrigin origin)
{ {
Debug.Assert( Debug.Assert(

View file

@ -20,7 +20,6 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using Server.Collections;
using Server.Text; using Server.Text;
namespace Server; namespace Server;
@ -135,17 +134,6 @@ public class BufferWriter : IGenericWriter
Index += length; Index += length;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(BitArray bitArray)
{
var byteLength = BitArray.GetByteArrayLengthFromBitLength(bitArray.Length);
((IGenericWriter)this).WriteEncodedInt(bitArray.Length);
FlushIfNeeded(byteLength);
bitArray.CopyTo(_buffer.AsSpan((int)Index, byteLength));
Index += byteLength;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual long Seek(long offset, SeekOrigin origin) public virtual long Seek(long offset, SeekOrigin origin)
{ {

View file

@ -14,6 +14,8 @@
*************************************************************************/ *************************************************************************/
using System; using System;
using System.Buffers;
using System.Collections;
using System.IO; using System.IO;
using System.Net; using System.Net;
using Server.Collections; using Server.Collections;
@ -120,7 +122,17 @@ public interface IGenericReader
return new Guid(bytes); return new Guid(bytes);
} }
BitArray ReadBitArray(); public BitArray ReadBitArray()
{
var byteArrayLength = ReadEncodedInt();
// We need an exact array size since the ctor doesn't allow for offset/length, not much we can do at this point.
var byteArray = new byte[byteArrayLength];
Read(byteArray);
return new BitArray(byteArray);
}
TextDefinition ReadTextDefinition() TextDefinition ReadTextDefinition()
{ {

View file

@ -14,9 +14,13 @@
*************************************************************************/ *************************************************************************/
using System; using System;
using System.Buffers;
using System.Collections;
using System.Collections.Specialized;
using System.IO; using System.IO;
using System.Net; using System.Net;
using Server.Collections; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Server; namespace Server;
@ -162,7 +166,17 @@ public interface IGenericWriter
Write(stack); Write(stack);
} }
void Write(BitArray bitArray); public void Write(BitArray bitArray)
{
var bytesLength = (bitArray.Length - 1 + (1 << 3)) >>> 3;
var arrayBuffer = ArrayPool<byte>.Shared.Rent(bytesLength);
WriteEncodedInt(bytesLength);
bitArray.CopyTo(arrayBuffer, 0);
Write(arrayBuffer.AsSpan(0, bytesLength));
ArrayPool<byte>.Shared.Return(arrayBuffer);
}
void Write(TextDefinition def) void Write(TextDefinition def)
{ {

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;