Updated the RebuildXmlStructures method with performance improvements. Added cache checking to the GetByPublishedVersion method since published content should always be 'latest' this will speed things up tremendously if items are found there. Added 2 more performance tests which show very large perf improvements, namely the Get_All_Published_Content_Of_Type shows a 77% improvement.
This commit is contained in:
@@ -449,7 +449,15 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
yield return CreateContentFromDto(dto, dto.VersionId);
|
||||
var fromCache = TryGetFromCache(dto.NodeId);
|
||||
if (fromCache.Success)
|
||||
{
|
||||
yield return fromCache.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return CreateContentFromDto(dto, dto.VersionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,11 +85,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public TEntity Get(TId id)
|
||||
{
|
||||
Guid key = id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString());
|
||||
var rEntity = _cache.GetById(typeof(TEntity), key);
|
||||
if (rEntity != null)
|
||||
var fromCache = TryGetFromCache(id);
|
||||
if (fromCache.Success)
|
||||
{
|
||||
return (TEntity)rEntity;
|
||||
return fromCache.Result;
|
||||
}
|
||||
|
||||
var entity = PerformGet(id);
|
||||
@@ -112,6 +111,17 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected Attempt<TEntity> TryGetFromCache(TId id)
|
||||
{
|
||||
Guid key = id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString());
|
||||
var rEntity = _cache.GetById(typeof(TEntity), key);
|
||||
if (rEntity != null)
|
||||
{
|
||||
return new Attempt<TEntity>(true, (TEntity) rEntity);
|
||||
}
|
||||
return Attempt<TEntity>.False;
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<TEntity> PerformGetAll(params TId[] ids);
|
||||
/// <summary>
|
||||
/// Gets all entities of type TEntity or a list according to the passed in Ids
|
||||
@@ -173,14 +183,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public bool Exists(TId id)
|
||||
{
|
||||
Guid key = id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString());
|
||||
var rEntity = _cache.GetById(typeof(TEntity), key);
|
||||
if (rEntity != null)
|
||||
var fromCache = TryGetFromCache(id);
|
||||
if (fromCache.Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PerformExists(id);
|
||||
return PerformExists(id);
|
||||
}
|
||||
|
||||
protected abstract int PerformCount(IQuery<TEntity> query);
|
||||
|
||||
@@ -13,6 +13,7 @@ using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Publishing;
|
||||
|
||||
@@ -250,6 +251,17 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<IContent> GetPublishedContentOfContentType(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IContent>.Builder.Where(x => x.ContentTypeId == id);
|
||||
var contents = repository.GetByPublishedVersion(query);
|
||||
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects by Level
|
||||
/// </summary>
|
||||
@@ -431,6 +443,19 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all published content items
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<IContent> GetAllPublished()
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IContent>.Builder.Where(x => x.Trashed == false);
|
||||
return repository.GetByPublishedVersion(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects, which has an expiration date less than or equal to today.
|
||||
/// </summary>
|
||||
@@ -1359,23 +1384,13 @@ namespace Umbraco.Core.Services
|
||||
uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN cmsDocument ON cmsContentXml.nodeId = cmsDocument.nodeId)");
|
||||
|
||||
//get all content items that are published
|
||||
// Consider creating a Path query instead of recursive method:
|
||||
// var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
|
||||
var rootContent = GetRootContent();
|
||||
foreach (var content in rootContent.Where(content => content.Published))
|
||||
{
|
||||
list.Add(content);
|
||||
list.AddRange(GetPublishedDescendants(content));
|
||||
}
|
||||
|
||||
list.AddRange(GetAllPublished());
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var id in contentTypeIds)
|
||||
{
|
||||
|
||||
|
||||
//first we'll clear out the data from the cmsContentXml table for this type
|
||||
uow.Database.Execute(@"delete from cmsContentXml where nodeId in
|
||||
(select cmsDocument.nodeId from cmsDocument
|
||||
@@ -1383,7 +1398,7 @@ namespace Umbraco.Core.Services
|
||||
where published = 1 and contentType = @contentTypeId)", new {contentTypeId = id});
|
||||
|
||||
//now get all published content objects of this type and add to the list
|
||||
list.AddRange(GetContentOfContentType(id).Where(content => content.Published));
|
||||
list.AddRange(GetPublishedContentOfContentType(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
@@ -66,6 +67,90 @@ namespace Umbraco.Tests.Services
|
||||
base.TearDown();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_All_Published_Content()
|
||||
{
|
||||
var result = PrimeDbWithLotsOfContent();
|
||||
var contentSvc = (ContentService) ServiceContext.ContentService;
|
||||
|
||||
var countOfPublished = result.Count(x => x.Published);
|
||||
var contentTypeId = result.First().ContentTypeId;
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content normally"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
|
||||
var published = new List<IContent>();
|
||||
//get all content items that are published
|
||||
var rootContent = contentSvc.GetRootContent();
|
||||
foreach (var content in rootContent.Where(content => content.Published))
|
||||
{
|
||||
published.Add(content);
|
||||
published.AddRange(contentSvc.GetPublishedDescendants(content));
|
||||
}
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content optimized"))
|
||||
{
|
||||
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
|
||||
//get all content items that are published
|
||||
var published = contentSvc.GetAllPublished();
|
||||
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_All_Published_Content_Of_Type()
|
||||
{
|
||||
var result = PrimeDbWithLotsOfContent();
|
||||
var contentSvc = (ContentService)ServiceContext.ContentService;
|
||||
|
||||
var countOfPublished = result.Count(x => x.Published);
|
||||
var contentTypeId = result.First().ContentTypeId;
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content of type normally"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
//get all content items that are published of this type
|
||||
var published = contentSvc.GetContentOfContentType(contentTypeId).Where(content => content.Published);
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content of type optimized"))
|
||||
{
|
||||
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
//get all content items that are published of this type
|
||||
var published = contentSvc.GetPublishedContentOfContentType(contentTypeId);
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Truncate_Insert_Vs_Update_Insert()
|
||||
{
|
||||
@@ -130,6 +215,51 @@ namespace Umbraco.Tests.Services
|
||||
|
||||
}
|
||||
|
||||
private IEnumerable<IContent> PrimeDbWithLotsOfContent()
|
||||
{
|
||||
var contentType1 = MockedContentTypes.CreateSimpleContentType();
|
||||
contentType1.AllowedAsRoot = true;
|
||||
ServiceContext.ContentTypeService.Save(contentType1);
|
||||
contentType1.AllowedContentTypes = new List<ContentTypeSort>
|
||||
{
|
||||
new ContentTypeSort
|
||||
{
|
||||
Alias = contentType1.Alias,
|
||||
Id = new Lazy<int>(() => contentType1.Id),
|
||||
SortOrder = 0
|
||||
}
|
||||
};
|
||||
var result = new List<IContent>();
|
||||
ServiceContext.ContentTypeService.Save(contentType1);
|
||||
IContent lastParent = MockedContent.CreateSimpleContent(contentType1);
|
||||
ServiceContext.ContentService.SaveAndPublish(lastParent);
|
||||
result.Add(lastParent);
|
||||
//create 20 deep
|
||||
for (var i = 0; i < 20; i++)
|
||||
{
|
||||
//for each level, create 20
|
||||
IContent content = null;
|
||||
for (var j = 1; j <= 10; j++)
|
||||
{
|
||||
content = MockedContent.CreateSimpleContent(contentType1, "Name" + j, lastParent);
|
||||
//only publish evens
|
||||
if (j % 2 == 0)
|
||||
{
|
||||
ServiceContext.ContentService.SaveAndPublish(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServiceContext.ContentService.Save(content);
|
||||
}
|
||||
result.Add(content);
|
||||
}
|
||||
|
||||
//assign the last one as the next parent
|
||||
lastParent = content;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private IEnumerable<NodeDto> PrimeDbWithLotsOfContentXmlRecords(Guid customObjectType)
|
||||
{
|
||||
var nodes = new List<NodeDto>();
|
||||
|
||||
Reference in New Issue
Block a user