From 45bd3d69dfbdf9feb1ed1697f539f48e83aabc10 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 4 Jan 2012 15:24:57 -0800 Subject: [PATCH] #18317: Improving Import performance Work Item: 18317 --HG-- branch : 1.x --- .../ContentManagement/DefaultHqlQuery.cs | 3 +- .../ContentManagement/ImportContentSession.cs | 63 ++++++++++++++----- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/Orchard/ContentManagement/DefaultHqlQuery.cs b/src/Orchard/ContentManagement/DefaultHqlQuery.cs index 674314fd2..c272482e3 100644 --- a/src/Orchard/ContentManagement/DefaultHqlQuery.cs +++ b/src/Orchard/ContentManagement/DefaultHqlQuery.cs @@ -403,7 +403,8 @@ namespace Orchard.ContentManagement { } public IAliasFactory ContentItemVersion() { - return Named("civ"); + Current = _query.BindItemVersionCriteria(); + return this; } public IAliasFactory ContentType() { diff --git a/src/Orchard/ContentManagement/ImportContentSession.cs b/src/Orchard/ContentManagement/ImportContentSession.cs index eab6caad4..6dff3ed1f 100644 --- a/src/Orchard/ContentManagement/ImportContentSession.cs +++ b/src/Orchard/ContentManagement/ImportContentSession.cs @@ -1,41 +1,76 @@ using System.Collections.Generic; +using System.Linq; namespace Orchard.ContentManagement { // Maps content identities to content items on the importer. public class ImportContentSession { private readonly IContentManager _contentManager; + private const int BulkPage = 128; + private int _lastIndex = 0; - private readonly Dictionary _dictionary; + private readonly Dictionary _identities; + private readonly Dictionary _contentItemIds; public ImportContentSession(IContentManager contentManager) { _contentManager = contentManager; - _dictionary = new Dictionary(new ContentIdentity.ContentIdentityEqualityComparer()); + _identities = new Dictionary(new ContentIdentity.ContentIdentityEqualityComparer()); + _contentItemIds = new Dictionary(); } public ContentItem Get(string id) { var contentIdentity = new ContentIdentity(id); - if (_dictionary.ContainsKey(contentIdentity)) - return _dictionary[contentIdentity]; + // lookup in local cache + if (_identities.ContainsKey(contentIdentity)) + return _identities[contentIdentity]; - foreach (var item in _contentManager.Query(VersionOptions.Latest).List()) { - var identity = _contentManager.GetItemMetadata(item).Identity; - var equalityComparer = new ContentIdentity.ContentIdentityEqualityComparer(); - if (equalityComparer.Equals(identity, contentIdentity)) { - _dictionary.Add(identity, item); - return item; - } + // no result ? then check if there are some more content items to load from the db + + if(_lastIndex == int.MaxValue) { + // everything has already been loaded from db + return null; } + var equalityComparer = new ContentIdentity.ContentIdentityEqualityComparer(); + IEnumerable block; + + // load identities in blocks + while ((block = _contentManager.HqlQuery() + .ForVersion(VersionOptions.Latest) + .OrderBy(x => x.ContentItemVersion(), x => x.Asc("Id")) + .Slice(_lastIndex, BulkPage)).Any()) { + + foreach (var item in block) { + _lastIndex++; + + // ignore content item if it has already been imported + if(_contentItemIds.ContainsKey(item.Id)) { + continue; + } + + var identity = _contentManager.GetItemMetadata(item).Identity; + + _identities.Add(identity, item); + _contentItemIds.Add(item.Id, identity); + + if (equalityComparer.Equals(identity, contentIdentity)) { + return item; + } + } + } + + _lastIndex = int.MaxValue; return null; } public void Store(string id, ContentItem item) { var contentIdentity = new ContentIdentity(id); - if (_dictionary.ContainsKey(contentIdentity)) { - _dictionary.Remove(contentIdentity); + if (_identities.ContainsKey(contentIdentity)) { + _identities.Remove(contentIdentity); + _contentItemIds.Remove(item.Id); } - _dictionary.Add(contentIdentity, item); + _identities.Add(contentIdentity, item); + _contentItemIds.Add(item.Id, contentIdentity); } }