Slim down CandidateSet
This commit is contained in:
parent
6eeda774ef
commit
e47fbbab9e
|
|
@ -18,19 +18,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
{
|
{
|
||||||
private const int BitVectorSize = 32;
|
private const int BitVectorSize = 32;
|
||||||
|
|
||||||
// Cannot be readonly because we need to modify it in place.
|
private readonly CandidateState[] _candidates;
|
||||||
private BitVector32 _validity;
|
|
||||||
private readonly BitArray _largeCapactityValidity;
|
|
||||||
|
|
||||||
// We inline storage for 4 candidates here to avoid allocations in common
|
|
||||||
// cases. There's no real reason why 4 is important, it just seemed like
|
|
||||||
// a plausible number.
|
|
||||||
private CandidateState _state0;
|
|
||||||
private CandidateState _state1;
|
|
||||||
private CandidateState _state2;
|
|
||||||
private CandidateState _state3;
|
|
||||||
|
|
||||||
private CandidateState[] _additionalCandidates;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>
|
/// <para>
|
||||||
|
|
@ -69,56 +57,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
|
|
||||||
Count = endpoints.Length;
|
Count = endpoints.Length;
|
||||||
|
|
||||||
switch (endpoints.Length)
|
_candidates = new CandidateState[endpoints.Length];
|
||||||
|
for (var i = 0; i < endpoints.Length; i++)
|
||||||
{
|
{
|
||||||
case 0:
|
_candidates[i] = new CandidateState(endpoints[i], values[i], scores[i]);
|
||||||
return;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
_state0 = new CandidateState(endpoints[0], values[0], scores[0]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
_state0 = new CandidateState(endpoints[0], values[0], scores[0]);
|
|
||||||
_state1 = new CandidateState(endpoints[1], values[1], scores[1]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
_state0 = new CandidateState(endpoints[0], values[0], scores[0]);
|
|
||||||
_state1 = new CandidateState(endpoints[1], values[1], scores[1]);
|
|
||||||
_state2 = new CandidateState(endpoints[2], values[2], scores[2]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
_state0 = new CandidateState(endpoints[0], values[0], scores[0]);
|
|
||||||
_state1 = new CandidateState(endpoints[1], values[1], scores[1]);
|
|
||||||
_state2 = new CandidateState(endpoints[2], values[2], scores[2]);
|
|
||||||
_state3 = new CandidateState(endpoints[3], values[3], scores[3]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
_state0 = new CandidateState(endpoints[0], values[0], scores[0]);
|
|
||||||
_state1 = new CandidateState(endpoints[1], values[1], scores[1]);
|
|
||||||
_state2 = new CandidateState(endpoints[2], values[2], scores[2]);
|
|
||||||
_state3 = new CandidateState(endpoints[3], values[3], scores[3]);
|
|
||||||
|
|
||||||
_additionalCandidates = new CandidateState[endpoints.Length - 4];
|
|
||||||
for (var i = 4; i < endpoints.Length; i++)
|
|
||||||
{
|
|
||||||
_additionalCandidates[i - 4] = new CandidateState(endpoints[i], values[i], scores[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize validity to valid by default.
|
|
||||||
if (Count < BitVectorSize)
|
|
||||||
{
|
|
||||||
// Sets the bit for each candidate that exists (bits > Count will be 0).
|
|
||||||
_validity = new BitVector32(unchecked((int)~(0xFFFFFFFFu << Count)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_largeCapactityValidity = new BitArray(Count, defaultValue: true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,56 +68,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
{
|
{
|
||||||
Count = candidates.Length;
|
Count = candidates.Length;
|
||||||
|
|
||||||
switch (candidates.Length)
|
_candidates = new CandidateState[candidates.Length];
|
||||||
|
for (var i = 0; i < candidates.Length; i++)
|
||||||
{
|
{
|
||||||
case 0:
|
_candidates[i] = new CandidateState(candidates[i].Endpoint, candidates[i].Score);
|
||||||
return;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
_state0 = new CandidateState(candidates[0].Endpoint, candidates[0].Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
_state0 = new CandidateState(candidates[0].Endpoint, candidates[0].Score);
|
|
||||||
_state1 = new CandidateState(candidates[1].Endpoint, candidates[1].Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
_state0 = new CandidateState(candidates[0].Endpoint, candidates[0].Score);
|
|
||||||
_state1 = new CandidateState(candidates[1].Endpoint, candidates[1].Score);
|
|
||||||
_state2 = new CandidateState(candidates[2].Endpoint, candidates[2].Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
_state0 = new CandidateState(candidates[0].Endpoint, candidates[0].Score);
|
|
||||||
_state1 = new CandidateState(candidates[1].Endpoint, candidates[1].Score);
|
|
||||||
_state2 = new CandidateState(candidates[2].Endpoint, candidates[2].Score);
|
|
||||||
_state3 = new CandidateState(candidates[3].Endpoint, candidates[3].Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
_state0 = new CandidateState(candidates[0].Endpoint, candidates[0].Score);
|
|
||||||
_state1 = new CandidateState(candidates[1].Endpoint, candidates[1].Score);
|
|
||||||
_state2 = new CandidateState(candidates[2].Endpoint, candidates[2].Score);
|
|
||||||
_state3 = new CandidateState(candidates[3].Endpoint, candidates[3].Score);
|
|
||||||
|
|
||||||
_additionalCandidates = new CandidateState[candidates.Length - 4];
|
|
||||||
for (var i = 4; i < candidates.Length; i++)
|
|
||||||
{
|
|
||||||
_additionalCandidates[i - 4] = new CandidateState(candidates[i].Endpoint, candidates[i].Score);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize validity to valid by default.
|
|
||||||
if (Count < BitVectorSize)
|
|
||||||
{
|
|
||||||
// Sets the bit for each candidate that exists (bits > Count will be 0).
|
|
||||||
_validity = new BitVector32(unchecked((int)~(0xFFFFFFFFu << Count)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_largeCapactityValidity = new BitArray(Count, defaultValue: true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,23 +103,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
ThrowIndexArgumentOutOfRangeException();
|
ThrowIndexArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (index)
|
return ref _candidates[index];
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return ref _state0;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
return ref _state1;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
return ref _state2;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
return ref _state3;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ref _additionalCandidates[index - 4];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,7 +113,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The candidate index.</param>
|
/// <param name="index">The candidate index.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <c>true</c> if the candidate at position <paramref name="index"/> is considered value
|
/// <c>true</c> if the candidate at position <paramref name="index"/> is considered valid
|
||||||
/// for the current request, otherwise <c>false</c>.
|
/// for the current request, otherwise <c>false</c>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public bool IsValidCandidate(int index)
|
public bool IsValidCandidate(int index)
|
||||||
|
|
@ -244,15 +124,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
ThrowIndexArgumentOutOfRangeException();
|
ThrowIndexArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Count < BitVectorSize)
|
return _candidates[index].Score >= 0;
|
||||||
{
|
|
||||||
// Get the n-th bit
|
|
||||||
return _validity[0x00000001 << index];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return _largeCapactityValidity[index];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -270,15 +142,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
ThrowIndexArgumentOutOfRangeException();
|
ThrowIndexArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Count < BitVectorSize)
|
ref var original = ref _candidates[index];
|
||||||
{
|
_candidates[index] = new CandidateState(original.Endpoint, original.Values, original.Score >= 0 ^ value ? ~original.Score : original.Score);
|
||||||
// Set the n-th bit
|
|
||||||
_validity[0x00000001 << index] = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_largeCapactityValidity[index] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -303,28 +168,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
||||||
ThrowIndexArgumentOutOfRangeException();
|
ThrowIndexArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (index)
|
_candidates[index] = new CandidateState(endpoint, values, _candidates[index].Score);
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
_state0 = new CandidateState(endpoint, values, _state0.Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
_state1 = new CandidateState(endpoint, values, _state1.Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
_state2 = new CandidateState(endpoint, values, _state2.Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
_state3 = new CandidateState(endpoint, values, _state3.Score);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
_additionalCandidates[index - 4] = new CandidateState(endpoint, values, _additionalCandidates[index - 4].Score);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endpoint == null)
|
if (endpoint == null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue