优化快速排序
This commit is contained in:
parent
9d36677428
commit
bf3bd5c909
@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>2.0.8</Version>
|
<Version>2.0.9</Version>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<IsWebConfigTransformDisabled>true</IsWebConfigTransformDisabled>
|
<IsWebConfigTransformDisabled>true</IsWebConfigTransformDisabled>
|
||||||
|
|||||||
@ -61,14 +61,15 @@ namespace FastGithub.DomainResolve
|
|||||||
/// 解析域名
|
/// 解析域名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="endPoint">远程结节</param>
|
/// <param name="endPoint">远程结节</param>
|
||||||
|
/// <param name="fastSort">是否使用快速排序</param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async IAsyncEnumerable<IPAddress> ResolveAsync(DnsEndPoint endPoint, [EnumeratorCancellation] CancellationToken cancellationToken)
|
public async IAsyncEnumerable<IPAddress> ResolveAsync(DnsEndPoint endPoint, bool fastSort, [EnumeratorCancellation] CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var hashSet = new HashSet<IPAddress>();
|
var hashSet = new HashSet<IPAddress>();
|
||||||
foreach (var dns in this.GetDnsServers())
|
foreach (var dns in this.GetDnsServers())
|
||||||
{
|
{
|
||||||
var addresses = await this.LookupAsync(dns, endPoint, cancellationToken);
|
var addresses = await this.LookupAsync(dns, endPoint, fastSort, cancellationToken);
|
||||||
foreach (var address in addresses)
|
foreach (var address in addresses)
|
||||||
{
|
{
|
||||||
if (hashSet.Add(address) == true)
|
if (hashSet.Add(address) == true)
|
||||||
@ -106,9 +107,10 @@ namespace FastGithub.DomainResolve
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dns"></param>
|
/// <param name="dns"></param>
|
||||||
/// <param name="endPoint"></param>
|
/// <param name="endPoint"></param>
|
||||||
|
/// <param name="fastSort"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<IPAddress[]> LookupAsync(IPEndPoint dns, DnsEndPoint endPoint, CancellationToken cancellationToken = default)
|
private async Task<IPAddress[]> LookupAsync(IPEndPoint dns, DnsEndPoint endPoint, bool fastSort, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var key = $"{dns}/{endPoint}";
|
var key = $"{dns}/{endPoint}";
|
||||||
var semaphore = this.semaphoreSlims.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
|
var semaphore = this.semaphoreSlims.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
|
||||||
@ -121,7 +123,7 @@ namespace FastGithub.DomainResolve
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await this.LookupCoreAsync(dns, endPoint, cancellationToken);
|
var result = await this.LookupCoreAsync(dns, endPoint, fastSort, cancellationToken);
|
||||||
this.dnsCache.Set(key, result.Addresses, result.TimeToLive);
|
this.dnsCache.Set(key, result.Addresses, result.TimeToLive);
|
||||||
return result.Addresses;
|
return result.Addresses;
|
||||||
}
|
}
|
||||||
@ -146,9 +148,10 @@ namespace FastGithub.DomainResolve
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dns"></param>
|
/// <param name="dns"></param>
|
||||||
/// <param name="endPoint"></param>
|
/// <param name="endPoint"></param>
|
||||||
|
/// <param name="fastSort"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<LookupResult> LookupCoreAsync(IPEndPoint dns, DnsEndPoint endPoint, CancellationToken cancellationToken = default)
|
private async Task<LookupResult> LookupCoreAsync(IPEndPoint dns, DnsEndPoint endPoint, bool fastSort, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (endPoint.Host == LOCALHOST)
|
if (endPoint.Host == LOCALHOST)
|
||||||
{
|
{
|
||||||
@ -170,7 +173,7 @@ namespace FastGithub.DomainResolve
|
|||||||
return new LookupResult(addresses, this.minTimeToLive);
|
return new LookupResult(addresses, this.minTimeToLive);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addresses.Length > 1)
|
if (fastSort && addresses.Length > 1)
|
||||||
{
|
{
|
||||||
addresses = await OrderByConnectAnyAsync(addresses, endPoint.Port, cancellationToken);
|
addresses = await OrderByConnectAnyAsync(addresses, endPoint.Port, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -237,8 +240,13 @@ namespace FastGithub.DomainResolve
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static async Task<IPAddress[]> OrderByConnectAnyAsync(IPAddress[] addresses, int port, CancellationToken cancellationToken)
|
private static async Task<IPAddress[]> OrderByConnectAnyAsync(IPAddress[] addresses, int port, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tasks = addresses.Select(address => ConnectAsync(address, port, cancellationToken));
|
using var controlTokenSource = new CancellationTokenSource(connectTimeout);
|
||||||
var fastestAddress = await await Task.WhenAny(tasks);
|
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, controlTokenSource.Token);
|
||||||
|
|
||||||
|
var connectTasks = addresses.Select(address => ConnectAsync(address, port, linkedTokenSource.Token));
|
||||||
|
var fastestAddress = await await Task.WhenAny(connectTasks);
|
||||||
|
controlTokenSource.Cancel();
|
||||||
|
|
||||||
if (fastestAddress == null)
|
if (fastestAddress == null)
|
||||||
{
|
{
|
||||||
return addresses;
|
return addresses;
|
||||||
@ -266,10 +274,8 @@ namespace FastGithub.DomainResolve
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var timeoutTokenSource = new CancellationTokenSource(connectTimeout);
|
|
||||||
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);
|
|
||||||
using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||||
await socket.ConnectAsync(address, port, linkedTokenSource.Token);
|
await socket.ConnectAsync(address, port, cancellationToken);
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@ -65,7 +65,7 @@ namespace FastGithub.DomainResolve
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.dnsEndPointAddressElapseds.TryAdd(endPoint, IPAddressElapsedCollection.Empty);
|
this.dnsEndPointAddressElapseds.TryAdd(endPoint, IPAddressElapsedCollection.Empty);
|
||||||
await foreach (var adddress in this.dnsClient.ResolveAsync(endPoint, cancellationToken))
|
await foreach (var adddress in this.dnsClient.ResolveAsync(endPoint, fastSort: true, cancellationToken))
|
||||||
{
|
{
|
||||||
this.logger.LogInformation($"{endPoint.Host}->{adddress}");
|
this.logger.LogInformation($"{endPoint.Host}->{adddress}");
|
||||||
yield return adddress;
|
yield return adddress;
|
||||||
@ -86,7 +86,7 @@ namespace FastGithub.DomainResolve
|
|||||||
{
|
{
|
||||||
var dnsEndPoint = keyValue.Key;
|
var dnsEndPoint = keyValue.Key;
|
||||||
var addresses = new List<IPAddress>();
|
var addresses = new List<IPAddress>();
|
||||||
await foreach (var adddress in this.dnsClient.ResolveAsync(dnsEndPoint, cancellationToken))
|
await foreach (var adddress in this.dnsClient.ResolveAsync(dnsEndPoint, fastSort: false, cancellationToken))
|
||||||
{
|
{
|
||||||
addresses.Add(adddress);
|
addresses.Add(adddress);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user