Perf: making content type definitions cached

ContentTypeDefinition needed to fully resolve parts to avoid orphan record access
ContentDefinitionManager caches results incrementally
All cached definitions expire when any information is touched

--HG--
branch : perf
extra : rebase_source : b9779a86684aa652ed63360ab6558070e04600ee
This commit is contained in:
Louis DeJardin
2010-11-16 15:51:30 -08:00
parent c02d20c3b1
commit a1c5dd646e
2 changed files with 40 additions and 6 deletions

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Orchard.Caching;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.Core.Settings.Metadata.Records;
@@ -11,6 +12,9 @@ using Orchard.Utility.Extensions;
namespace Orchard.Core.Settings.Metadata {
public class ContentDefinitionManager : Component, IContentDefinitionManager {
private const string ContentDefinitionSignal = "ContentDefinitionManager";
private readonly ICacheManager _cacheManager;
private readonly ISignals _signals;
private readonly IRepository<ContentTypeDefinitionRecord> _typeDefinitionRepository;
private readonly IRepository<ContentPartDefinitionRecord> _partDefinitionRepository;
private readonly IRepository<ContentFieldDefinitionRecord> _fieldDefinitionRepository;
@@ -18,11 +22,15 @@ namespace Orchard.Core.Settings.Metadata {
private readonly IMapper<SettingsDictionary, XElement> _settingsWriter;
public ContentDefinitionManager(
ICacheManager cacheManager,
ISignals signals,
IRepository<ContentTypeDefinitionRecord> typeDefinitionRepository,
IRepository<ContentPartDefinitionRecord> partDefinitionRepository,
IRepository<ContentFieldDefinitionRecord> fieldDefinitionRepository,
IMapper<XElement, SettingsDictionary> settingsReader,
IMapper<SettingsDictionary, XElement> settingsWriter) {
_cacheManager = cacheManager;
_signals = signals;
_typeDefinitionRepository = typeDefinitionRepository;
_partDefinitionRepository = partDefinitionRepository;
_fieldDefinitionRepository = fieldDefinitionRepository;
@@ -31,33 +39,58 @@ namespace Orchard.Core.Settings.Metadata {
}
public ContentTypeDefinition GetTypeDefinition(string name) {
return _typeDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault();
return _cacheManager.Get(name, ctx => {
MonitorContentDefinitionSignal(ctx);
return _typeDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault();
});
}
public ContentPartDefinition GetPartDefinition(string name) {
return _partDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault();
return _cacheManager.Get(name, ctx => {
MonitorContentDefinitionSignal(ctx);
return _partDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault();
});
}
public IEnumerable<ContentTypeDefinition> ListTypeDefinitions() {
return _typeDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection();
return _cacheManager.Get(string.Empty, ctx => {
MonitorContentDefinitionSignal(ctx);
return _typeDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection();
});
}
public IEnumerable<ContentPartDefinition> ListPartDefinitions() {
return _partDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection();
return _cacheManager.Get(string.Empty, ctx => {
MonitorContentDefinitionSignal(ctx);
return _partDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection();
});
}
public IEnumerable<ContentFieldDefinition> ListFieldDefinitions() {
return _fieldDefinitionRepository.Fetch(x => true, cfdr => cfdr.Asc(fdr => fdr.Name)).Select(Build).ToReadOnlyCollection();
return _cacheManager.Get(string.Empty, ctx => {
MonitorContentDefinitionSignal(ctx);
return _fieldDefinitionRepository.Fetch(x => true, cfdr => cfdr.Asc(fdr => fdr.Name)).Select(Build).ToReadOnlyCollection();
});
}
public void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition) {
TriggerContentDefinitionSignal();
Apply(contentTypeDefinition, Acquire(contentTypeDefinition));
}
public void StorePartDefinition(ContentPartDefinition contentPartDefinition) {
_signals.Trigger(ContentDefinitionSignal);
Apply(contentPartDefinition, Acquire(contentPartDefinition));
}
private void MonitorContentDefinitionSignal(AcquireContext<string> ctx) {
ctx.Monitor(_signals.When(ContentDefinitionSignal));
}
private void TriggerContentDefinitionSignal() {
_signals.Trigger(ContentDefinitionSignal);
}
private ContentTypeDefinitionRecord Acquire(ContentTypeDefinition contentTypeDefinition) {
var result = _typeDefinitionRepository.Fetch(x => x.Name == contentTypeDefinition.Name).SingleOrDefault();
if (result == null) {

View File

@@ -1,13 +1,14 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Orchard.Utility.Extensions;
namespace Orchard.ContentManagement.MetaData.Models {
public class ContentTypeDefinition {
public ContentTypeDefinition(string name, string displayName, IEnumerable<ContentTypePartDefinition> parts, SettingsDictionary settings) {
Name = name;
DisplayName = displayName;
Parts = parts;
Parts = parts.ToReadOnlyCollection();
Settings = settings;
}