mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
#18880: Fixing performance issues in BlogArchiveWidget
Work Item: 18880 --HG-- branch : 1.x
This commit is contained in:
@@ -12,44 +12,73 @@ using Orchard.Data;
|
|||||||
namespace Orchard.Blogs.Handlers {
|
namespace Orchard.Blogs.Handlers {
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public class BlogPartArchiveHandler : ContentHandler {
|
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) {
|
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));
|
OnPublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
|
||||||
OnUnpublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
|
OnUnpublished<BlogPostPart>((context, bp) => RecalculateBlogArchive(blogArchiveRepository, blogPostService, bp));
|
||||||
OnRemoved<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();
|
blogArchiveRepository.Flush();
|
||||||
|
|
||||||
// remove all current blog archive records
|
var commonPart = blogPostPart.As<CommonPart>();
|
||||||
var blogArchiveRecords =
|
if(commonPart == null || !commonPart.CreatedUtc.HasValue)
|
||||||
from bar in blogArchiveRepository.Table
|
return;
|
||||||
where bar.BlogPart == blogPostPart.BlogPart.Record
|
|
||||||
select bar;
|
|
||||||
blogArchiveRecords.ToList().ForEach(blogArchiveRepository.Delete);
|
|
||||||
|
|
||||||
// get all blog posts for the current blog
|
var previousCreatedUtc = _previousCreatedUtc.ContainsKey(blogPostPart) ? _previousCreatedUtc[blogPostPart] : DateTime.MinValue;
|
||||||
var posts = blogPostService.Get(blogPostPart.BlogPart, VersionOptions.Published);
|
var previousMonth = previousCreatedUtc != null ? previousCreatedUtc.Month : 0;
|
||||||
|
var previousYear = previousCreatedUtc != null ? previousCreatedUtc.Year : 0;
|
||||||
|
|
||||||
// create a dictionary of all the year/month combinations and their count of posts that are published in this blog
|
var newCreatedUtc = commonPart.CreatedUtc;
|
||||||
var inMemoryBlogArchives = new Dictionary<DateTime, int>();
|
var newMonth = newCreatedUtc.HasValue ? newCreatedUtc.Value.Month : 0;
|
||||||
foreach (var post in posts) {
|
var newYear = newCreatedUtc.HasValue ? newCreatedUtc.Value.Year : 0;
|
||||||
if (!post.Has<CommonPart>())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var commonPart = post.As<CommonPart>();
|
// if archives are the same there is nothing to do
|
||||||
var key = new DateTime(commonPart.CreatedUtc.Value.Year, commonPart.CreatedUtc.Value.Month, 1);
|
if (previousMonth == newMonth && previousYear == newYear) {
|
||||||
|
return;
|
||||||
if (inMemoryBlogArchives.ContainsKey(key))
|
|
||||||
inMemoryBlogArchives[key]++;
|
|
||||||
else
|
|
||||||
inMemoryBlogArchives[key] = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the new blog archive records based on the in memory values
|
// decrement previous archive record
|
||||||
foreach (KeyValuePair<DateTime, int> item in inMemoryBlogArchives) {
|
var previousArchiveRecord = blogArchiveRepository.Table
|
||||||
blogArchiveRepository.Create(new BlogPartArchiveRecord {BlogPart = blogPostPart.BlogPart.Record, Year = item.Key.Year, Month = item.Key.Month, PostCount = item.Value});
|
.Where(x => x.BlogPart == blogPostPart.BlogPart.Record
|
||||||
}
|
&& x.Month == previousMonth
|
||||||
|
&& x.Year == previousYear)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (previousArchiveRecord != null && previousArchiveRecord.PostCount > 0) {
|
||||||
|
previousArchiveRecord.PostCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user