diff --git a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml index f8b7eb86cf..677d28d362 100644 --- a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml @@ -43,6 +43,7 @@ + Umbraco diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs index bfe8fb5260..469d53f749 100644 --- a/src/Umbraco.Web/PublishedContentQuery.cs +++ b/src/Umbraco.Web/PublishedContentQuery.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Xml.XPath; @@ -224,14 +225,51 @@ namespace Umbraco.Web { var doc = cache.GetById(id); return doc; - } + } + + private static readonly ConcurrentDictionary _guidToIntLoopkup = new ConcurrentDictionary(); private IPublishedContent TypedDocumentById(Guid id, ContextualPublishedCache cache) - { - // todo: in v8, implement in a more efficient way - var legacyXml = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema; - var xpath = legacyXml ? "//node [@key=$guid]" : "//* [@key=$guid]"; - var doc = cache.GetSingleByXPath(xpath, new XPathVariable("guid", id.ToString())); + { + // Check if the loopkup is empty, if so populate it [LK] + if (_guidToIntLoopkup.Count == 0) + { + // TODO: Remove the debug profile logger + using (ApplicationContext.Current.ProfilingLogger.DebugDuration("Populate GUID/INT lookup")) + { + // NOTE, using the `@nodeTypeAlias` attribute in the XPath as this was support in both legacy & new schemas + var tmpNodes = cache.GetXPathNavigator().Select("//*[@nodeTypeAlias]"); + foreach (XPathNavigator tmpNode in tmpNodes) + { + if (int.TryParse(tmpNode.GetAttribute("id", string.Empty), out int tmpNodeId) + && Guid.TryParse(tmpNode.GetAttribute("key", string.Empty), out Guid tmpNodeKey)) + { + _guidToIntLoopkup[tmpNodeKey] = tmpNodeId; + } + } + } + } + + IPublishedContent doc; + + // Check if the lookup contains the GUID/INT value + if (_guidToIntLoopkup.TryGetValue(id, out int nodeId) == false) + { + // If not, then we perform an inefficient XPath for the GUID + + // todo: in v8, implement in a more efficient way + doc = cache.GetSingleByXPath("//*[@key=$guid]", new XPathVariable("guid", id.ToString())); + + // When we have the node, we add the GUID/INT value to the lookup + if (doc != null) + _guidToIntLoopkup[id] = doc.Id; + } + else + { + // Otherwise we have the node id (INT) and can perform an efficient retrieval + doc = cache.GetById(nodeId); + } + return doc; }