From bb9e23ca3ea080d2a4c0191747fff38b3c4ca683 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 18 Jan 2018 11:40:46 +0000 Subject: [PATCH] Proposed patch for U4-10756 - Guid TypedContent performance This is a proposal for a temporary workaround to issue U4-10756. It uses a local static ConcurrentDictionary to store a lookup of Guid/int values. If the Guid isn't in the lookup, then the traditional XPath is used, which would add the resulting node ID (int) to the lookup. If the lookup contains the Guid, then the returned int value will be used to perform a more efficient retrieval. --- src/Umbraco.Web/PublishedContentQuery.cs | 37 ++++++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs index bfe8fb5260..a609a609b7 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,38 @@ namespace Umbraco.Web { var doc = cache.GetById(id); return doc; - } + } + + private static ConcurrentDictionary _guidToIntLoopkup; 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())); + { + // We create the lookup when we first need it + if (_guidToIntLoopkup == null) + _guidToIntLoopkup = new ConcurrentDictionary(); + + 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 + var legacyXml = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema; + var xpath = legacyXml ? "//node[@key=$guid]" : "//*[@key=$guid]"; + doc = cache.GetSingleByXPath(xpath, new XPathVariable("guid", id.ToString())); + + // When we have the node, we add the GUID/INT value to the lookup + if (doc != null) + _guidToIntLoopkup.TryAdd(id, doc.Id); + } + else + { + // Otherwise we have the node id (INT) and can perform an efficient retrieval + doc = cache.GetById(nodeId); + } + return doc; }