Optimizing tenants resolution performance

This commit is contained in:
Sebastien Ros
2013-11-06 16:06:00 -08:00
parent 5c24810427
commit 2cccd945e4

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -16,7 +17,9 @@ namespace Orchard.Environment {
public class RunningShellTable : IRunningShellTable {
private IEnumerable<ShellSettings> _shells = Enumerable.Empty<ShellSettings>();
private IEnumerable<IGrouping<string, ShellSettings>> _shellsByHost = Enumerable.Empty<ShellSettings>().GroupBy(x => default(string));
private IDictionary<string, IEnumerable<ShellSettings>> _shellsByHost;
private ConcurrentDictionary<string, ShellSettings> _shellsByHostAndPrefix = new ConcurrentDictionary<string, ShellSettings>(StringComparer.OrdinalIgnoreCase);
private ShellSettings _fallback;
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
@@ -81,7 +84,7 @@ namespace Orchard.Environment {
.Select(h => new ShellSettings(s) {RequestUrlHost = h}))
.GroupBy(s => s.RequestUrlHost ?? string.Empty)
.OrderByDescending(g => g.Key.Length)
.ToArray();
.ToDictionary(x => x.Key, x => x.AsEnumerable(), StringComparer.OrdinalIgnoreCase);
if (unqualified.Count() == 1) {
// only one shell had no request url criteria
@@ -113,15 +116,21 @@ namespace Orchard.Environment {
return _fallback;
}
// removing the port from the host
var hostLength = host.IndexOf(':');
if (hostLength != -1)
if (hostLength != -1) {
host = host.Substring(0, hostLength);
}
var mostQualifiedMatch = _shellsByHost
.Where(group => host.EndsWith(group.Key, StringComparison.OrdinalIgnoreCase))
.SelectMany(group => group
.OrderByDescending(settings => (settings.RequestUrlPrefix ?? string.Empty).Length))
.FirstOrDefault(settings => {
string hostAndPrefix = host + "/" + appRelativePath.Split('/')[1];
return _shellsByHostAndPrefix.GetOrAdd(hostAndPrefix, key => {
// filtering shells by host
var shells = _shellsByHost.ContainsKey(host) ? _shellsByHost[host] : _shellsByHost[""];
// looking for a request url prefix match
var mostQualifiedMatch = shells.FirstOrDefault(settings => {
if (settings.State == TenantState.Disabled) {
return false;
}
@@ -130,11 +139,12 @@ namespace Orchard.Environment {
return true;
}
return appRelativePath.StartsWith("~/" + settings.RequestUrlPrefix + "/", StringComparison.OrdinalIgnoreCase)
|| appRelativePath.Equals("~/" + settings.RequestUrlPrefix, StringComparison.OrdinalIgnoreCase);
return key.Equals(host + "/" + settings.RequestUrlPrefix, StringComparison.OrdinalIgnoreCase);
});
return mostQualifiedMatch ?? _fallback;
return mostQualifiedMatch ?? _fallback;
});
}
finally {
_lock.ExitReadLock();