Improving support of huge amount of content items

This commit is contained in:
Sebastien Ros
2014-04-03 18:36:14 -07:00
parent 6bee52e950
commit dad8835196
9 changed files with 72 additions and 10 deletions

View File

@@ -80,11 +80,16 @@ namespace Orchard.Tests.Stubs {
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public int MaxPageSize {
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public int MaxPagedCount {
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public string BaseUrl { get; set;}

View File

@@ -105,7 +105,8 @@ namespace Orchard.Core.Contents.Controllers {
.Select(ctd => new KeyValuePair<string, string>(ctd.Name, ctd.DisplayName))
.ToList().OrderBy(kvp => kvp.Value);
var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count());
var maxPagedCount = _siteService.GetSiteSettings().MaxPagedCount;
var pagerShape = Shape.Pager(pager).TotalItemCount(maxPagedCount > 0 ? maxPagedCount : query.Count());
var pageOfContentItems = query.Slice(pager.GetStartIndex(), pager.PageSize).ToList();
var list = Shape.List();

View File

@@ -55,6 +55,11 @@ namespace Orchard.Core.Settings.Models {
set { this.Store(x => x.MaxPageSize, value); }
}
public int MaxPagedCount {
get { return this.Retrieve(x => x.MaxPagedCount); }
set { this.Store(x => x.MaxPagedCount, value); }
}
public string SiteTimeZone {
get { return this.Retrieve(x => x.SiteTimeZone); }
set { this.Store(x => x.SiteTimeZone, value); }

View File

@@ -56,6 +56,11 @@ namespace Orchard.Core.Settings.ViewModels {
set { Site.MaxPageSize = value; }
}
public int MaxPagedCount {
get { return Site.MaxPagedCount; }
set { Site.MaxPagedCount = value; }
}
public string BaseUrl {
get { return Site.BaseUrl; }
set { Site.BaseUrl = value; }

View File

@@ -69,5 +69,10 @@
@Html.TextBoxFor(m => m.MaxPageSize, new {@class = "text small"})
<span class="hint">@T("Determines the maximum number of items that are shown per page. Leave 0 for unlimited.")</span>
</div>
<div>
<label for="MaxPagedCount">@T("Last index of items in pages")</label>
@Html.TextBoxFor(m => m.MaxPagedCount, new { @class = "text small" })
<span class="hint">@T("Determines the last element of the database that can be displayed. Leave 0 for unlimited.")</span>
</div>
}
</fieldset>

View File

@@ -196,6 +196,11 @@ namespace Orchard.Setup {
set { throw new NotImplementedException(); }
}
public int MaxPagedCount {
get { return 0; }
set { throw new NotImplementedException(); }
}
public string BaseUrl {
get { return ""; }
}

View File

@@ -90,6 +90,11 @@ namespace Orchard.Tokens.Tests {
set { throw new NotImplementedException(); }
}
public int MaxPagedCount {
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public string BaseUrl { get; set; }
public string SiteTimeZone {

View File

@@ -11,6 +11,7 @@ using Orchard.Data;
using NHibernate.Transform;
using NHibernate.SqlCommand;
using Orchard.Utility.Extensions;
using Orchard.Caching;
namespace Orchard.ContentManagement {
public class DefaultContentQuery : IContentQuery {
@@ -18,10 +19,21 @@ namespace Orchard.ContentManagement {
private ISession _session;
private ICriteria _itemVersionCriteria;
private VersionOptions _versionOptions;
private ICacheManager _cacheManager;
private ISignals _signals;
private IRepository<ContentTypeRecord> _contentTypeRepository;
public DefaultContentQuery(IContentManager contentManager, ISessionLocator sessionLocator) {
public DefaultContentQuery(
IContentManager contentManager,
ISessionLocator sessionLocator,
ICacheManager cacheManager,
ISignals signals,
IRepository<ContentTypeRecord> contentTypeRepository) {
_sessionLocator = sessionLocator;
ContentManager = contentManager;
_cacheManager = cacheManager;
_signals = signals;
_contentTypeRepository = contentTypeRepository;
}
public IContentManager ContentManager { get; private set; }
@@ -36,11 +48,11 @@ namespace Orchard.ContentManagement {
return criteria.GetCriteriaByPath(path) ?? criteria.CreateCriteria(path);
}
ICriteria BindTypeCriteria() {
// ([ContentItemVersionRecord] >join> [ContentItemRecord]) >join> [ContentType]
//ICriteria BindTypeCriteria() {
// // ([ContentItemVersionRecord] >join> [ContentItemRecord]) >join> [ContentType]
return BindCriteriaByPath(BindItemCriteria(), "ContentType");
}
// return BindCriteriaByPath(BindItemCriteria(), "ContentType");
//}
ICriteria BindItemCriteria() {
// [ContentItemVersionRecord] >join> [ContentItemRecord]
@@ -63,15 +75,33 @@ namespace Orchard.ContentManagement {
return BindCriteriaByPath(BindItemCriteria(), typeof(TRecord).Name);
}
private int GetContentTypeRecordId(string contentType) {
return _cacheManager.Get(contentType + "_Record", ctx => {
ctx.Monitor(_signals.When(contentType + "_Record"));
var contentTypeRecord = _contentTypeRepository.Get(x => x.Name == contentType);
if (contentTypeRecord == null) {
//TEMP: this is not safe... ContentItem types could be created concurrently?
contentTypeRecord = new ContentTypeRecord { Name = contentType };
_contentTypeRepository.Create(contentTypeRecord);
}
return contentTypeRecord.Id;
});
}
private void ForType(params string[] contentTypeNames) {
if (contentTypeNames != null && contentTypeNames.Length != 0)
if (contentTypeNames != null && contentTypeNames.Length != 0) {
var contentTypeIds = contentTypeNames.Select(GetContentTypeRecordId).ToArray();
// don't use the IN operator if not needed for performance reasons
if (contentTypeNames.Length == 1) {
BindTypeCriteria().Add(Restrictions.Eq("Name", contentTypeNames[0]));
BindItemCriteria().Add(Restrictions.Eq("ContentType.Id", contentTypeIds[0]));
}
else {
BindTypeCriteria().Add(Restrictions.InG("Name", contentTypeNames));
BindItemCriteria().Add(Restrictions.InG("ContentType.Id", contentTypeIds));
}
}
}
public void ForVersion(VersionOptions options) {

View File

@@ -15,6 +15,7 @@ namespace Orchard.Settings {
ResourceDebugMode ResourceDebugMode { get; set; }
int PageSize { get; set; }
int MaxPageSize { get; set; }
int MaxPagedCount { get; set; }
string BaseUrl { get; }
string SiteTimeZone { get; }
}