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.

<http://issues.umbraco.org/issue/U4-10756>
This commit is contained in:
leekelleher
2018-01-18 11:40:46 +00:00
parent 7d5d69e2e3
commit bb9e23ca3e

View File

@@ -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<Guid, int> _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<Guid, int>();
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;
}