Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy initialize BatchingEntityLoader and BatchingCollectionInitializer #1904

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public partial class BatchingCollectionInitializer : ICollectionInitializer
public async Task InitializeAsync(object id, ISessionImplementor session, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
object[] batch =
await (session.PersistenceContext.BatchFetchQueue.GetCollectionBatchAsync(collectionPersister, id, batchSizes[0], cancellationToken)).ConfigureAwait(false);
object[] batch = await (session.PersistenceContext.BatchFetchQueue.GetCollectionBatchAsync(collectionPersister, id, batchSizes[0], cancellationToken)).ConfigureAwait(false);

for (int i = 0; i < batchSizes.Length; i++)
{
Expand All @@ -34,12 +33,12 @@ public async Task InitializeAsync(object id, ISessionImplementor session, Cancel
{
object[] smallBatch = new object[smallBatchSize];
Array.Copy(batch, 0, smallBatch, 0, smallBatchSize);
await (loaders[i].LoadCollectionBatchAsync(session, smallBatch, collectionPersister.KeyType, cancellationToken)).ConfigureAwait(false);
await (loaders[i].Value.LoadCollectionBatchAsync(session, smallBatch, collectionPersister.KeyType, cancellationToken)).ConfigureAwait(false);
return; //EARLY EXIT!
}
}

await (loaders[batchSizes.Length - 1].LoadCollectionAsync(session, id, collectionPersister.KeyType, cancellationToken)).ConfigureAwait(false);
await (loaders[batchSizes.Length - 1].Value.LoadCollectionAsync(session, id, collectionPersister.KeyType, cancellationToken)).ConfigureAwait(false);
}
}
}
}
6 changes: 3 additions & 3 deletions src/NHibernate/Async/Loader/Entity/BatchingEntityLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public async Task<object> LoadAsync(object id, object optionalObject, ISessionIm
Array.Copy(batch, 0, smallBatch, 0, smallBatchSize);

IList results =
await (loaders[i].LoadEntityBatchAsync(session, smallBatch, idType, optionalObject, persister.EntityName, id, persister, cancellationToken)).ConfigureAwait(false);
await (loaders[i].Value.LoadEntityBatchAsync(session, smallBatch, idType, optionalObject, persister.EntityName, id, persister, cancellationToken)).ConfigureAwait(false);

return GetObjectFromList(results, id, session); //EARLY EXIT
}
}

return await (((IUniqueEntityLoader) loaders[batchSizes.Length - 1]).LoadAsync(id, optionalObject, session, cancellationToken)).ConfigureAwait(false);
return await (((IUniqueEntityLoader) loaders[batchSizes.Length - 1].Value).LoadAsync(id, optionalObject, session, cancellationToken)).ConfigureAwait(false);
}
}
}
}
62 changes: 35 additions & 27 deletions src/NHibernate/Loader/Collection/BatchingCollectionInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ namespace NHibernate.Loader.Collection
/// <seealso cref="OneToManyLoader"/>
public partial class BatchingCollectionInitializer : ICollectionInitializer
{
private readonly Loader[] loaders;
private readonly Lazy<Loader>[] loaders;
private readonly int[] batchSizes;
private readonly ICollectionPersister collectionPersister;

public BatchingCollectionInitializer(ICollectionPersister collectionPersister, int[] batchSizes, Loader[] loaders)
: this(collectionPersister, batchSizes, Array.ConvertAll(loaders, loader => new Lazy<Loader>(() => loader)))
{
}

public BatchingCollectionInitializer(ICollectionPersister collectionPersister, int[] batchSizes, Lazy<Loader>[] loaders)
{
this.loaders = loaders;
this.batchSizes = batchSizes;
Expand All @@ -26,8 +31,7 @@ public BatchingCollectionInitializer(ICollectionPersister collectionPersister, i

public void Initialize(object id, ISessionImplementor session)
{
object[] batch =
session.PersistenceContext.BatchFetchQueue.GetCollectionBatch(collectionPersister, id, batchSizes[0]);
object[] batch = session.PersistenceContext.BatchFetchQueue.GetCollectionBatch(collectionPersister, id, batchSizes[0]);

for (int i = 0; i < batchSizes.Length; i++)
{
Expand All @@ -36,54 +40,58 @@ public void Initialize(object id, ISessionImplementor session)
{
object[] smallBatch = new object[smallBatchSize];
Array.Copy(batch, 0, smallBatch, 0, smallBatchSize);
loaders[i].LoadCollectionBatch(session, smallBatch, collectionPersister.KeyType);
loaders[i].Value.LoadCollectionBatch(session, smallBatch, collectionPersister.KeyType);
return; //EARLY EXIT!
}
}

loaders[batchSizes.Length - 1].LoadCollection(session, id, collectionPersister.KeyType);
loaders[batchSizes.Length - 1].Value.LoadCollection(session, id, collectionPersister.KeyType);
}

public static ICollectionInitializer CreateBatchingOneToManyInitializer(OneToManyPersister persister, int maxBatchSize,
ISessionFactoryImplementor factory,
IDictionary<string, IFilter> enabledFilters)
public static ICollectionInitializer CreateBatchingOneToManyInitializer(
OneToManyPersister persister,
int maxBatchSize,
ISessionFactoryImplementor factory,
IDictionary<string, IFilter> enabledFilters)
{
if (maxBatchSize > 1)
{
int[] batchSizesToCreate = ArrayHelper.GetBatchSizes(maxBatchSize);
Loader[] loadersToCreate = new Loader[batchSizesToCreate.Length];
var batchSizesToCreate = ArrayHelper.GetBatchSizes(maxBatchSize);
var loadersToCreate = new Lazy<Loader>[batchSizesToCreate.Length];
for (int i = 0; i < batchSizesToCreate.Length; i++)
{
loadersToCreate[i] = new OneToManyLoader(persister, batchSizesToCreate[i], factory, enabledFilters);
var batchSize = batchSizesToCreate[i];
loadersToCreate[i] = new Lazy<Loader>(
() => new OneToManyLoader(persister, batchSize, factory, enabledFilters));
}

return new BatchingCollectionInitializer(persister, batchSizesToCreate, loadersToCreate);
}
else
{
return new OneToManyLoader(persister, factory, enabledFilters);
}

return new OneToManyLoader(persister, factory, enabledFilters);
}

public static ICollectionInitializer CreateBatchingCollectionInitializer(IQueryableCollection persister,
int maxBatchSize,
ISessionFactoryImplementor factory,
IDictionary<string, IFilter> enabledFilters)
public static ICollectionInitializer CreateBatchingCollectionInitializer(
IQueryableCollection persister,
int maxBatchSize,
ISessionFactoryImplementor factory,
IDictionary<string, IFilter> enabledFilters)
{
if (maxBatchSize > 1)
{
int[] batchSizesToCreate = ArrayHelper.GetBatchSizes(maxBatchSize);
Loader[] loadersToCreate = new Loader[batchSizesToCreate.Length];
var batchSizesToCreate = ArrayHelper.GetBatchSizes(maxBatchSize);
var loadersToCreate = new Lazy<Loader>[batchSizesToCreate.Length];
for (int i = 0; i < batchSizesToCreate.Length; i++)
{
loadersToCreate[i] = new BasicCollectionLoader(persister, batchSizesToCreate[i], factory, enabledFilters);
var batchSize = batchSizesToCreate[i];
loadersToCreate[i] = new Lazy<Loader>(
() => new BasicCollectionLoader(persister, batchSize, factory, enabledFilters));
}

return new BatchingCollectionInitializer(persister, batchSizesToCreate, loadersToCreate);
}
else
{
return new BasicCollectionLoader(persister, factory, enabledFilters);
}

return new BasicCollectionLoader(persister, factory, enabledFilters);
}
}
}
}
39 changes: 24 additions & 15 deletions src/NHibernate/Loader/Entity/BatchingEntityLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ namespace NHibernate.Loader.Entity
/// <seealso cref="EntityLoader"/>
public partial class BatchingEntityLoader : IUniqueEntityLoader
{
private readonly Loader[] loaders;
private readonly Lazy<Loader>[] loaders;
private readonly int[] batchSizes;
private readonly IEntityPersister persister;
private readonly IType idType;

public BatchingEntityLoader(IEntityPersister persister, int[] batchSizes, Loader[] loaders)
: this(persister, batchSizes, Array.ConvertAll(loaders, loader => new Lazy<Loader>(() => loader)))
{
}

public BatchingEntityLoader(IEntityPersister persister, int[] batchSizes, Lazy<Loader>[] loaders)
{
this.batchSizes = batchSizes;
this.loaders = loaders;
Expand Down Expand Up @@ -58,33 +63,37 @@ public object Load(object id, object optionalObject, ISessionImplementor session
Array.Copy(batch, 0, smallBatch, 0, smallBatchSize);

IList results =
loaders[i].LoadEntityBatch(session, smallBatch, idType, optionalObject, persister.EntityName, id, persister);
loaders[i].Value.LoadEntityBatch(session, smallBatch, idType, optionalObject, persister.EntityName, id, persister);

return GetObjectFromList(results, id, session); //EARLY EXIT
}
}

return ((IUniqueEntityLoader) loaders[batchSizes.Length - 1]).Load(id, optionalObject, session);
return ((IUniqueEntityLoader) loaders[batchSizes.Length - 1].Value).Load(id, optionalObject, session);
}

public static IUniqueEntityLoader CreateBatchingEntityLoader(IOuterJoinLoadable persister, int maxBatchSize,
LockMode lockMode, ISessionFactoryImplementor factory,
IDictionary<string, IFilter> enabledFilters)
public static IUniqueEntityLoader CreateBatchingEntityLoader(
IOuterJoinLoadable persister,
int maxBatchSize,
LockMode lockMode,
ISessionFactoryImplementor factory,
IDictionary<string, IFilter> enabledFilters)
{
if (maxBatchSize > 1)
{
int[] batchSizesToCreate = ArrayHelper.GetBatchSizes(maxBatchSize);
Loader[] loadersToCreate = new Loader[batchSizesToCreate.Length];
for (int i = 0; i < batchSizesToCreate.Length; i++)
var batchSizesToCreate = ArrayHelper.GetBatchSizes(maxBatchSize);
var loadersToCreate = new Lazy<Loader>[batchSizesToCreate.Length];
for (var i = 0; i < batchSizesToCreate.Length; i++)
{
loadersToCreate[i] = new EntityLoader(persister, batchSizesToCreate[i], lockMode, factory, enabledFilters);
var batchSize = batchSizesToCreate[i];
loadersToCreate[i] = new Lazy<Loader>(
() => new EntityLoader(persister, batchSize, lockMode, factory, enabledFilters));
}

return new BatchingEntityLoader(persister, batchSizesToCreate, loadersToCreate);
}
else
{
return new EntityLoader(persister, lockMode, factory, enabledFilters);
}

return new EntityLoader(persister, lockMode, factory, enabledFilters);
}
}
}
}