Change AllowedCharsBitmap back to a struct.

I also experimented with having a fixed uint[] field inside the struct, but this actually ended up having worse performance than a proper uint[] array reference since it defeated some of the JITter's optimizations.
This commit is contained in:
Levi B 2015-03-10 11:47:36 -07:00
parent 64077026c7
commit ae456401a8
3 changed files with 21 additions and 16 deletions

View File

@ -6,14 +6,15 @@ using System.Diagnostics;
namespace Microsoft.Framework.WebEncoders namespace Microsoft.Framework.WebEncoders
{ {
internal class AllowedCharsBitmap internal struct AllowedCharsBitmap
{ {
private const int ALLOWED_CHARS_BITMAP_LENGTH = 0x10000 / (8 * sizeof(uint)); private const int ALLOWED_CHARS_BITMAP_LENGTH = 0x10000 / (8 * sizeof(uint));
private uint[] _allowedCharsBitmap; private readonly uint[] _allowedCharsBitmap;
public AllowedCharsBitmap() private AllowedCharsBitmap(uint[] allowedCharsBitmap)
{ {
_allowedCharsBitmap = new uint[ALLOWED_CHARS_BITMAP_LENGTH]; Debug.Assert(allowedCharsBitmap != null);
_allowedCharsBitmap = allowedCharsBitmap;
} }
// Marks a character as allowed (can be returned unencoded) // Marks a character as allowed (can be returned unencoded)
@ -34,9 +35,13 @@ namespace Microsoft.Framework.WebEncoders
// Creates a deep copy of this bitmap // Creates a deep copy of this bitmap
public AllowedCharsBitmap Clone() public AllowedCharsBitmap Clone()
{ {
var retVal = new AllowedCharsBitmap(); return new AllowedCharsBitmap((uint[])_allowedCharsBitmap.Clone());
retVal._allowedCharsBitmap = (uint[])this._allowedCharsBitmap.Clone(); }
return retVal;
// should be called in place of the ctor
public static AllowedCharsBitmap CreateNew()
{
return new AllowedCharsBitmap(new uint[ALLOWED_CHARS_BITMAP_LENGTH]);
} }
// Marks a character as forbidden (must be returned encoded) // Marks a character as forbidden (must be returned encoded)
@ -47,7 +52,7 @@ namespace Microsoft.Framework.WebEncoders
int offset = (int)(codePoint & 0x1FU); int offset = (int)(codePoint & 0x1FU);
_allowedCharsBitmap[index] &= ~(0x1U << offset); _allowedCharsBitmap[index] &= ~(0x1U << offset);
} }
public void ForbidUndefinedCharacters() public void ForbidUndefinedCharacters()
{ {
// Forbid codepoints which aren't mapped to characters or which are otherwise always disallowed // Forbid codepoints which aren't mapped to characters or which are otherwise always disallowed

View File

@ -19,7 +19,7 @@ namespace Microsoft.Framework.WebEncoders
/// </summary> /// </summary>
public CodePointFilter() public CodePointFilter()
{ {
_allowedCharsBitmap = new AllowedCharsBitmap(); _allowedCharsBitmap = AllowedCharsBitmap.CreateNew();
} }
/// <summary> /// <summary>
@ -34,7 +34,7 @@ namespace Microsoft.Framework.WebEncoders
} }
else else
{ {
_allowedCharsBitmap = new AllowedCharsBitmap(); _allowedCharsBitmap = AllowedCharsBitmap.CreateNew();
AllowFilter(other); AllowFilter(other);
} }
} }
@ -45,7 +45,7 @@ namespace Microsoft.Framework.WebEncoders
/// </summary> /// </summary>
public CodePointFilter(params UnicodeRange[] allowedRanges) public CodePointFilter(params UnicodeRange[] allowedRanges)
{ {
_allowedCharsBitmap = new AllowedCharsBitmap(); _allowedCharsBitmap = AllowedCharsBitmap.CreateNew();
AllowRanges(allowedRanges); AllowRanges(allowedRanges);
} }

View File

@ -12,7 +12,7 @@ namespace Microsoft.Framework.WebEncoders
public void Ctor_EmptyByDefault() public void Ctor_EmptyByDefault()
{ {
// Act // Act
var bitmap = new AllowedCharsBitmap(); var bitmap = AllowedCharsBitmap.CreateNew();
// Assert // Assert
for (int i = 0; i <= Char.MaxValue; i++) for (int i = 0; i <= Char.MaxValue; i++)
@ -25,7 +25,7 @@ namespace Microsoft.Framework.WebEncoders
public void Allow_Forbid_ZigZag() public void Allow_Forbid_ZigZag()
{ {
// Arrange // Arrange
var bitmap = new AllowedCharsBitmap(); var bitmap = AllowedCharsBitmap.CreateNew();
// Act // Act
// The only chars which are allowed are those whose code points are multiples of 3 or 7 // The only chars which are allowed are those whose code points are multiples of 3 or 7
@ -58,7 +58,7 @@ namespace Microsoft.Framework.WebEncoders
public void Clear_ForbidsEverything() public void Clear_ForbidsEverything()
{ {
// Arrange // Arrange
var bitmap = new AllowedCharsBitmap(); var bitmap = AllowedCharsBitmap.CreateNew();
for (int i = 1; i <= Char.MaxValue; i++) for (int i = 1; i <= Char.MaxValue; i++)
{ {
bitmap.AllowCharacter((char)i); bitmap.AllowCharacter((char)i);
@ -78,7 +78,7 @@ namespace Microsoft.Framework.WebEncoders
public void Clone_MakesDeepCopy() public void Clone_MakesDeepCopy()
{ {
// Arrange // Arrange
var originalBitmap = new AllowedCharsBitmap(); var originalBitmap = AllowedCharsBitmap.CreateNew();
originalBitmap.AllowCharacter('x'); originalBitmap.AllowCharacter('x');
// Act // Act
@ -99,7 +99,7 @@ namespace Microsoft.Framework.WebEncoders
// We only allow odd-numbered characters in this test so that // We only allow odd-numbered characters in this test so that
// we can validate that we properly merged the two bitmaps together // we can validate that we properly merged the two bitmaps together
// rather than simply overwriting the target. // rather than simply overwriting the target.
var bitmap = new AllowedCharsBitmap(); var bitmap = AllowedCharsBitmap.CreateNew();
for (int i = 1; i <= Char.MaxValue; i += 2) for (int i = 1; i <= Char.MaxValue; i += 2)
{ {
bitmap.AllowCharacter((char)i); bitmap.AllowCharacter((char)i);