Skip to content

Commit 616497d

Browse files
committed
Avoid recursive calls in BatchFetchQueue
1 parent 77c7ea4 commit 616497d

File tree

2 files changed

+54
-53
lines changed

2 files changed

+54
-53
lines changed

src/NHibernate/Async/Engine/BatchFetchQueue.cs

Lines changed: 45 additions & 48 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,59 @@ 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-
}
332+
return true;
333+
}
347334

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
335+
if (persister.IdentifierType.IsEqual(id, key.Identifier))
336+
{
337+
idIndex = index;
338+
}
339+
else if (!checkCache || batchableCache == null)
340+
{
341+
if (index < set.Count && (!idIndex.HasValue || index < idIndex.Value))
358342
{
359343
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();
344+
return false;
367345
}
368-
if (i == batchSize)
346+
347+
// No need to check "!checkCache || !IsCached(key, persister)": "batchableCache == null"
348+
// already means there is no cache, so IsCached can only yield false. (This method is now
349+
// removed.)
350+
ids[i++] = key.Identifier;
351+
}
352+
else if (ignoreCache)
353+
{
354+
ids[i++] = key.Identifier;
355+
}
356+
else
357+
{
358+
entityKeys.Add(new KeyValuePair<EntityKey, int>(key, index));
359+
// Check the cache only when we have collected as many keys as are needed to fill the batch,
360+
// that are after the demanded key.
361+
if (!idIndex.HasValue || index < idIndex.Value + batchSize)
369362
{
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-
}
363+
return false;
376364
}
377-
return Task.FromResult<bool>(false);
365+
366+
return null;
378367
}
379-
catch (Exception ex)
368+
369+
if (i == batchSize)
380370
{
381-
return Task.FromException<bool>(ex);
371+
i = 1; // End of array, start filling again from start
372+
if (index == set.Count || idIndex.HasValue)
373+
{
374+
checkForEnd = true;
375+
return index == set.Count || index >= idIndex.Value + batchSize;
376+
}
382377
}
378+
379+
return false;
383380
}
384381
}
385382

src/NHibernate/Engine/BatchFetchQueue.cs

Lines changed: 9 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,13 +484,14 @@ 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))
491491
{
492492
return true;
493493
}
494+
494495
if (persister.IdentifierType.IsEqual(id, key.Identifier))
495496
{
496497
idIndex = index;
@@ -521,8 +522,10 @@ bool ProcessKey(EntityKey key, bool ignoreCache = false)
521522
{
522523
return false;
523524
}
524-
return CheckCacheAndProcessResult();
525+
526+
return null;
525527
}
528+
526529
if (i == batchSize)
527530
{
528531
i = 1; // End of array, start filling again from start
@@ -532,6 +535,7 @@ bool ProcessKey(EntityKey key, bool ignoreCache = false)
532535
return index == set.Count || index >= idIndex.Value + batchSize;
533536
}
534537
}
538+
535539
return false;
536540
}
537541
}

0 commit comments

Comments
 (0)