#18880: Fixing performance issues in BlogArchiveWidget

Work Item: 18880

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2012-09-21 13:44:39 -07:00
parent c0698d11a0
commit 125f6f81b0

View File

@@ -12,44 +12,73 @@ using Orchard.Data;
namespace Orchard.Blogs.Handlers {
[UsedImplicitly]
public class BlogPartArchiveHandler : ContentHandler {
// contains the creation time of a blog part before it has been changed
private readonly Dictionary<BlogPostPart, DateTime> _previousCreatedUtc = new Dictionary<BlogPostPart,DateTime>();
public BlogPartArchiveHandler(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IBlogPostService blogPostService) {
OnVersioning<BlogPostPart>((context, bp1, bp2) => {
var commonPart = bp1.As<CommonPart>();
if(commonPart == null || !commonPart.CreatedUtc.HasValue || !bp1.IsPublished)
return;
_previousCreatedUtc[bp2] = commonPart.CreatedUtc.Value;
});
OnPublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
OnUnpublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
OnRemoved<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
}
private static void RecalculateBlogArchive(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IBlogPostService blogPostService, BlogPostPart blogPostPart) {
private void RecalculateBlogArchive(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IBlogPostService blogPostService, BlogPostPart blogPostPart) {
blogArchiveRepository.Flush();
var commonPart = blogPostPart.As<CommonPart>();
if(commonPart == null || !commonPart.CreatedUtc.HasValue)
return;
// remove all current blog archive records
var blogArchiveRecords =
from bar in blogArchiveRepository.Table
where bar.BlogPart == blogPostPart.BlogPart.Record
select bar;
blogArchiveRecords.ToList().ForEach(blogArchiveRepository.Delete);
var previousCreatedUtc = _previousCreatedUtc.ContainsKey(blogPostPart) ? _previousCreatedUtc[blogPostPart] : DateTime.MinValue;
var previousMonth = previousCreatedUtc != null ? previousCreatedUtc.Month : 0;
var previousYear = previousCreatedUtc != null ? previousCreatedUtc.Year : 0;
// get all blog posts for the current blog
var posts = blogPostService.Get(blogPostPart.BlogPart, VersionOptions.Published);
var newCreatedUtc = commonPart.CreatedUtc;
var newMonth = newCreatedUtc.HasValue ? newCreatedUtc.Value.Month : 0;
var newYear = newCreatedUtc.HasValue ? newCreatedUtc.Value.Year : 0;
// create a dictionary of all the year/month combinations and their count of posts that are published in this blog
var inMemoryBlogArchives = new Dictionary<DateTime, int>();
foreach (var post in posts) {
if (!post.Has<CommonPart>())
continue;
// if archives are the same there is nothing to do
if (previousMonth == newMonth && previousYear == newYear) {
return;
}
// decrement previous archive record
var previousArchiveRecord = blogArchiveRepository.Table
.Where(x => x.BlogPart == blogPostPart.BlogPart.Record
&& x.Month == previousMonth
&& x.Year == previousYear)
.FirstOrDefault();
var commonPart = post.As<CommonPart>();
var key = new DateTime(commonPart.CreatedUtc.Value.Year, commonPart.CreatedUtc.Value.Month, 1);
if (inMemoryBlogArchives.ContainsKey(key))
inMemoryBlogArchives[key]++;
else
inMemoryBlogArchives[key] = 1;
if (previousArchiveRecord != null && previousArchiveRecord.PostCount > 0) {
previousArchiveRecord.PostCount--;
}
// create the new blog archive records based on the in memory values
foreach (KeyValuePair<DateTime, int> item in inMemoryBlogArchives) {
blogArchiveRepository.Create(new BlogPartArchiveRecord {BlogPart = blogPostPart.BlogPart.Record, Year = item.Key.Year, Month = item.Key.Month, PostCount = item.Value});
// if previous count is now zero, delete the record
if (previousArchiveRecord != null && previousArchiveRecord.PostCount == 0) {
blogArchiveRepository.Delete(previousArchiveRecord);
}
// increment new archive record
var newArchiveRecord = blogArchiveRepository.Table
.Where(x => x.BlogPart == blogPostPart.BlogPart.Record
&& x.Month == newMonth
&& x.Year == newYear)
.FirstOrDefault();
// if record can't be found create it
if (newArchiveRecord == null) {
newArchiveRecord = new BlogPartArchiveRecord { BlogPart = blogPostPart.BlogPart.Record, Year = newYear, Month = newMonth, PostCount = 0 };
blogArchiveRepository.Create(newArchiveRecord);
}
newArchiveRecord.PostCount++;
}
}
}