mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
- PERF: ShellDescriptorCache serialization is inefficient
- DataContractSerializer was replaced with a simpler low-footprint solution for caching shell descriptors. --HG-- branch : perf
This commit is contained in:
@@ -55,21 +55,6 @@ namespace Orchard.Tests.Environment.Blueprint {
|
||||
Assert.That(result.SerialNumber, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StoreNullWillClearEntry() {
|
||||
var service = _container.Resolve<IShellDescriptorCache>();
|
||||
|
||||
var descriptor1 = new ShellDescriptor { SerialNumber = 6655321 };
|
||||
service.Store("Hello", descriptor1);
|
||||
var result1 = service.Fetch("Hello");
|
||||
Assert.That(result1, Is.Not.Null);
|
||||
|
||||
service.Store("Hello", null);
|
||||
var result2 = service.Fetch("Hello");
|
||||
Assert.That(result2, Is.Null);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void AllDataWillRoundTrip() {
|
||||
var service = _container.Resolve<IShellDescriptorCache>();
|
||||
|
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Localization;
|
||||
@@ -54,11 +54,7 @@ namespace Orchard.Environment.Descriptor {
|
||||
XmlNode rootNode = xmlDocument.DocumentElement;
|
||||
foreach (XmlNode tenantNode in rootNode.ChildNodes) {
|
||||
if (String.Equals(tenantNode.Name, name, StringComparison.OrdinalIgnoreCase)) {
|
||||
var serializer = new DataContractSerializer(typeof(ShellDescriptor));
|
||||
var reader = new StringReader(tenantNode.InnerText);
|
||||
using (var xmlReader = XmlReader.Create(reader)) {
|
||||
return (ShellDescriptor)serializer.ReadObject(xmlReader, true);
|
||||
}
|
||||
return GetShellDecriptorForCacheText(tenantNode.InnerText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,24 +72,14 @@ namespace Orchard.Environment.Descriptor {
|
||||
XmlNode rootNode = xmlDocument.DocumentElement;
|
||||
foreach (XmlNode tenantNode in rootNode.ChildNodes) {
|
||||
if (String.Equals(tenantNode.Name, name, StringComparison.OrdinalIgnoreCase)) {
|
||||
var serializer = new DataContractSerializer(typeof(ShellDescriptor));
|
||||
var writer = new StringWriter();
|
||||
using (var xmlWriter = XmlWriter.Create(writer)) {
|
||||
serializer.WriteObject(xmlWriter, descriptor);
|
||||
}
|
||||
tenantNode.InnerText = writer.ToString();
|
||||
tenantNode.InnerText = GetCacheTextForShellDescriptor(descriptor);
|
||||
tenantCacheUpdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tenantCacheUpdated) {
|
||||
XmlElement newTenant = xmlDocument.CreateElement(name);
|
||||
var serializer = new DataContractSerializer(typeof(ShellDescriptor));
|
||||
var writer = new StringWriter();
|
||||
using (var xmlWriter = XmlWriter.Create(writer)) {
|
||||
serializer.WriteObject(xmlWriter, descriptor);
|
||||
}
|
||||
newTenant.InnerText = writer.ToString();
|
||||
newTenant.InnerText = GetCacheTextForShellDescriptor(descriptor);
|
||||
rootNode.AppendChild(newTenant);
|
||||
}
|
||||
|
||||
@@ -103,6 +89,32 @@ namespace Orchard.Environment.Descriptor {
|
||||
|
||||
#endregion
|
||||
|
||||
private static string GetCacheTextForShellDescriptor(ShellDescriptor descriptor) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(descriptor.SerialNumber + "|");
|
||||
foreach (var feature in descriptor.Features) {
|
||||
sb.Append(feature.Name + ";");
|
||||
}
|
||||
sb.Append("|");
|
||||
foreach (var parameter in descriptor.Parameters) {
|
||||
sb.Append(parameter.Component + "," + parameter.Name + "," + parameter.Value);
|
||||
sb.Append(";");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static ShellDescriptor GetShellDecriptorForCacheText(string p) {
|
||||
string[] fields = p.Trim().Split(new[] { "|" }, StringSplitOptions.None);
|
||||
ShellDescriptor shellDescriptor = new ShellDescriptor {SerialNumber = Convert.ToInt32(fields[0])};
|
||||
string[] features = fields[1].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
shellDescriptor.Features = features.Select(feature => new ShellFeature { Name = feature }).ToList();
|
||||
string[] parameters = fields[2].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
shellDescriptor.Parameters = parameters.Select(parameter => parameter.Split(new[] { "," }, StringSplitOptions.None)).Select(parameterFields => new ShellParameter { Component = parameterFields[0], Name = parameterFields[1], Value = parameterFields[2] }).ToList();
|
||||
|
||||
return shellDescriptor;
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
|
||||
private void VerifyCacheFile() {
|
||||
if (!_appDataFolder.FileExists(DescriptorCacheFileName)) {
|
||||
|
Reference in New Issue
Block a user