- 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:
Suha Can
2010-11-16 16:06:14 -08:00
parent 46d2821b8b
commit c02d20c3b1
2 changed files with 31 additions and 34 deletions

View File

@@ -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>();

View File

@@ -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)) {