Skip to content

Commit 17680ea

Browse files
committed
Avoid recursive calls in BatchFetchQueue
1 parent 77c7ea4 commit 17680ea

File tree

2 files changed

+47
-54
lines changed

2 files changed

+47
-54
lines changed

src/NHibernate/Async/Engine/BatchFetchQueue.cs

Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ internal async Task<object[]> GetEntityBatchAsync(IEntityPersister persister, ob
266266
foreach (var key in set)
267267
{
268268
cancellationToken.ThrowIfCancellationRequested();
269-
if (await (ProcessKeyAsync(key)).ConfigureAwait(false))
269+
if (ProcessKey(key) ?? await (CheckCacheAndProcessResultAsync()).ConfigureAwait(false))
270270
{
271271
return ids;
272272
}
@@ -299,7 +299,7 @@ async Task<bool> CheckCacheAndProcessResultAsync()
299299
{
300300
for (var j = 0; j < entityKeys.Count; j++)
301301
{
302-
if (await (ProcessKeyAsync(entityKeys[indexes[j]].Key)).ConfigureAwait(false))
302+
if (ProcessKey(entityKeys[indexes[j]].Key) == true)
303303
{
304304
return true;
305305
}
@@ -310,7 +310,7 @@ async Task<bool> CheckCacheAndProcessResultAsync()
310310
var results = await (AreCachedAsync(entityKeys, indexes, persister, batchableCache, checkCache, cancellationToken)).ConfigureAwait(false);
311311
for (var j = 0; j < results.Length; j++)
312312
{
313-
if (!results[j] && await (ProcessKeyAsync(entityKeys[indexes[j]].Key, true)).ConfigureAwait(false))
313+
if (!results[j] && ProcessKey(entityKeys[indexes[j]].Key, true) == true)
314314
{
315315
return true;
316316
}
@@ -324,62 +324,55 @@ async Task<bool> CheckCacheAndProcessResultAsync()
324324
return false;
325325
}
326326

327-
Task<bool> ProcessKeyAsync(EntityKey key, bool ignoreCache = false)
327+
bool? ProcessKey(EntityKey key, bool ignoreCache = false)
328328
{
329-
try
329+
//TODO: this needn't exclude subclasses...
330+
if (checkForEnd && (index == set.Count || index >= idIndex.Value + batchSize))
330331
{
331-
//TODO: this needn't exclude subclasses...
332-
if (checkForEnd && (index == set.Count || index >= idIndex.Value + batchSize))
333-
{
334-
return Task.FromResult<bool>(true);
335-
}
336-
if (persister.IdentifierType.IsEqual(id, key.Identifier))
337-
{
338-
idIndex = index;
339-
}
340-
else if (!checkCache || batchableCache == null)
341-
{
342-
if (index < set.Count && (!idIndex.HasValue || index < idIndex.Value))
343-
{
344-
entityKeys.Add(new KeyValuePair<EntityKey, int>(key, index));
345-
return Task.FromResult<bool>(false);
346-
}
347-
348-
// No need to check "!checkCache || !IsCached(key, persister)": "batchableCache == null"
349-
// already means there is no cache, so IsCached can only yield false. (This method is now
350-
// removed.)
351-
ids[i++] = key.Identifier;
352-
}
353-
else if (ignoreCache)
354-
{
355-
ids[i++] = key.Identifier;
356-
}
357-
else
332+
return true;
333+
}
334+
if (persister.IdentifierType.IsEqual(id, key.Identifier))
335+
{
336+
idIndex = index;
337+
}
338+
else if (!checkCache || batchableCache == null)
339+
{
340+
if (index < set.Count && (!idIndex.HasValue || index < idIndex.Value))
358341
{
359342
entityKeys.Add(new KeyValuePair<EntityKey, int>(key, index));
360-
// Check the cache only when we have collected as many keys as are needed to fill the batch,
361-
// that are after the demanded key.
362-
if (!idIndex.HasValue || index < idIndex.Value + batchSize)
363-
{
364-
return Task.FromResult<bool>(false);
365-
}
366-
return CheckCacheAndProcessResultAsync();
343+
return false;
367344
}
368-
if (i == batchSize)
345+
346+
// No need to check "!checkCache || !IsCached(key, persister)": "batchableCache == null"
347+
// already means there is no cache, so IsCached can only yield false. (This method is now
348+
// removed.)
349+
ids[i++] = key.Identifier;
350+
}
351+
else if (ignoreCache)
352+
{
353+
ids[i++] = key.Identifier;
354+
}
355+
else
356+
{
357+
entityKeys.Add(new KeyValuePair<EntityKey, int>(key, index));
358+
// Check the cache only when we have collected as many keys as are needed to fill the batch,
359+
// that are after the demanded key.
360+
if (!idIndex.HasValue || index < idIndex.Value + batchSize)
369361
{
370-
i = 1; // End of array, start filling again from start
371-
if (index == set.Count || idIndex.HasValue)
372-
{
373-
checkForEnd = true;
374-
return Task.FromResult<bool>(index == set.Count || index >= idIndex.Value + batchSize);
375-
}
362+
return false;
376363
}
377-
return Task.FromResult<bool>(false);
364+
return null;
378365
}
379-
catch (Exception ex)
366+
if (i == batchSize)
380367
{
381-
return Task.FromException<bool>(ex);
368+
i = 1; // End of array, start filling again from start
369+
if (index == set.Count || idIndex.HasValue)
370+
{
371+
checkForEnd = true;
372+
return index == set.Count || index >= idIndex.Value + batchSize;
373+
}
382374
}
375+
return false;
383376
}
384377
}
385378

src/NHibernate/Engine/BatchFetchQueue.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ internal object[] GetEntityBatch(IEntityPersister persister, object id, int batc
427427

428428
foreach (var key in set)
429429
{
430-
if (ProcessKey(key))
430+
if (ProcessKey(key) ?? CheckCacheAndProcessResult())
431431
{
432432
return ids;
433433
}
@@ -459,7 +459,7 @@ bool CheckCacheAndProcessResult()
459459
{
460460
for (var j = 0; j < entityKeys.Count; j++)
461461
{
462-
if (ProcessKey(entityKeys[indexes[j]].Key))
462+
if (ProcessKey(entityKeys[indexes[j]].Key) == true)
463463
{
464464
return true;
465465
}
@@ -470,7 +470,7 @@ bool CheckCacheAndProcessResult()
470470
var results = AreCached(entityKeys, indexes, persister, batchableCache, checkCache);
471471
for (var j = 0; j < results.Length; j++)
472472
{
473-
if (!results[j] && ProcessKey(entityKeys[indexes[j]].Key, true))
473+
if (!results[j] && ProcessKey(entityKeys[indexes[j]].Key, true) == true)
474474
{
475475
return true;
476476
}
@@ -484,7 +484,7 @@ bool CheckCacheAndProcessResult()
484484
return false;
485485
}
486486

487-
bool ProcessKey(EntityKey key, bool ignoreCache = false)
487+
bool? ProcessKey(EntityKey key, bool ignoreCache = false)
488488
{
489489
//TODO: this needn't exclude subclasses...
490490
if (checkForEnd && (index == set.Count || index >= idIndex.Value + batchSize))
@@ -521,7 +521,7 @@ bool ProcessKey(EntityKey key, bool ignoreCache = false)
521521
{
522522
return false;
523523
}
524-
return CheckCacheAndProcessResult();
524+
return null;
525525
}
526526
if (i == batchSize)
527527
{

0 commit comments

Comments
 (0)