Skip to content

Commit 261ac75

Browse files
Add the aliases directly into cached data
1 parent 0bf7921 commit 261ac75

File tree

2 files changed

+73
-122
lines changed

2 files changed

+73
-122
lines changed

src/NHibernate/Cache/QueryAliasesKey.cs

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/NHibernate/Cache/StandardQueryCache.cs

Lines changed: 73 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,16 @@ public bool Put(
8383
IList result,
8484
ISessionImplementor session)
8585
{
86-
// 6.0 TODO: inline the call.
87-
#pragma warning disable 612
88-
var cached = Put(key, returnTypes, result, queryParameters.NaturalKeyLookup, session);
89-
#pragma warning restore 612
86+
if (queryParameters.NaturalKeyLookup && result.Count == 0)
87+
return false;
9088

91-
if (cached && key.ResultTransformer?.AutoDiscoverTypes == true && key.ResultTransformer.AutoDiscoveredAliases != null)
92-
{
93-
Cache.Put(new QueryAliasesKey(key), key.ResultTransformer.AutoDiscoveredAliases);
94-
}
89+
var ts = session.Factory.Settings.CacheProvider.NextTimestamp();
9590

96-
return cached;
91+
Log.Debug("caching query results in region: '{0}'; {1}", _regionName, key);
92+
93+
Cache.Put(key, GetCacheableResult(returnTypes, session, result, ts, GetAutoDiscoveredAliases(key)));
94+
95+
return true;
9796
}
9897

9998
// Since 5.2
@@ -107,7 +106,7 @@ public bool Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool
107106

108107
Log.Debug("caching query results in region: '{0}'; {1}", _regionName, key);
109108

110-
Cache.Put(key, GetCacheableResult(returnTypes, session, result, ts));
109+
Cache.Put(key, GetCacheableResult(returnTypes, session, result, ts, null));
111110

112111
return true;
113112
}
@@ -130,20 +129,32 @@ public IList Get(
130129

131130
try
132131
{
133-
// 6.0 TODO: inline the call.
134-
#pragma warning disable 612
135-
var result = Get(key, returnTypes, queryParameters.NaturalKeyLookup, spaces, session);
136-
#pragma warning restore 612
132+
if (Log.IsDebugEnabled())
133+
Log.Debug("checking cached query results in region: '{0}'; {1}", _regionName, key);
134+
135+
var cacheable = (IList) Cache.Get(key);
136+
if (cacheable == null)
137+
{
138+
Log.Debug("query results were not found in cache: {0}", key);
139+
return null;
140+
}
141+
142+
var timestamp = (long) cacheable[0];
143+
144+
if (Log.IsDebugEnabled())
145+
Log.Debug("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(spaces));
146+
147+
if (!queryParameters.NaturalKeyLookup && !IsUpToDate(spaces, timestamp))
148+
{
149+
Log.Debug("cached query results were not up to date for: {0}", key);
150+
return null;
151+
}
152+
153+
var result = GetResultFromCacheable(key, returnTypes, queryParameters.NaturalKeyLookup, session, cacheable);
137154

138155
if (result != null && key.ResultTransformer?.AutoDiscoverTypes == true && result.Count > 0)
139156
{
140-
var aliasesKey = new QueryAliasesKey(key);
141-
if (!(Cache.Get(aliasesKey) is string[] aliases))
142-
{
143-
// Cannot properly initialize the result transformer, treat it as a cache miss
144-
Log.Debug("query aliases were not found in cache: {0}", aliasesKey);
145-
return null;
146-
}
157+
var aliases = (string[]) cacheable[1];
147158
key.ResultTransformer.SupplyAutoDiscoveredParameters(queryParameters.ResultTransformer, aliases);
148159
}
149160

@@ -207,20 +218,19 @@ public bool[] PutMany(
207218
var key = keys[i];
208219
cached[i] = true;
209220
cachedKeys.Add(key);
210-
cachedResults.Add(GetCacheableResult(returnTypes[i], session, result, ts));
211-
212-
if (key.ResultTransformer?.AutoDiscoverTypes == true && key.ResultTransformer.AutoDiscoveredAliases != null)
213-
{
214-
cachedKeys.Add(new QueryAliasesKey(key));
215-
cachedResults.Add(key.ResultTransformer.AutoDiscoveredAliases);
216-
}
221+
cachedResults.Add(GetCacheableResult(returnTypes[i], session, result, ts, GetAutoDiscoveredAliases(key)));
217222
}
218223

219224
_cache.PutMany(cachedKeys.ToArray(), cachedResults.ToArray());
220225

221226
return cached;
222227
}
223228

229+
private static string[] GetAutoDiscoveredAliases(QueryKey key)
230+
{
231+
return key.ResultTransformer?.AutoDiscoverTypes == true ? key.ResultTransformer.AutoDiscoveredAliases : null;
232+
}
233+
224234
/// <inheritdoc />
225235
public IList[] GetMany(
226236
QueryKey[] keys,
@@ -271,8 +281,6 @@ public IList[] GetMany(
271281
{
272282
session.PersistenceContext.BatchFetchQueue.InitializeQueryCacheQueue();
273283

274-
var queryAliasesKeys = new QueryAliasesKey[keys.Length];
275-
var hasAliasesToFetch = false;
276284
for (var i = 0; i < keys.Length; i++)
277285
{
278286
var cacheable = (IList) cacheables[i];
@@ -297,35 +305,10 @@ public IList[] GetMany(
297305
finalReturnTypes[i] = GetReturnTypes(key, returnTypes[i], cacheable);
298306
PerformBeforeAssemble(finalReturnTypes[i], session, cacheable);
299307

300-
if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0)
308+
if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 2)
301309
{
302-
queryAliasesKeys[i] = new QueryAliasesKey(key);
303-
hasAliasesToFetch = true;
304-
}
305-
}
306-
307-
if (hasAliasesToFetch)
308-
{
309-
var allAliases = _cache.GetMany(queryAliasesKeys.Where(k => k != null).ToArray());
310-
311-
var aliasesIndex = 0;
312-
for (var i = 0; i < keys.Length; i++)
313-
{
314-
var queryAliasesKey = queryAliasesKeys[i];
315-
if (queryAliasesKey == null)
316-
continue;
317-
318-
if (allAliases[aliasesIndex] is string[] aliases)
319-
{
320-
keys[i].ResultTransformer.SupplyAutoDiscoveredParameters(queryParameters[i].ResultTransformer, aliases);
321-
}
322-
else
323-
{
324-
// Cannot properly initialize the result transformer, treat it as a cache miss
325-
Log.Debug("query aliases were not found in cache: {0}", queryAliasesKey);
326-
finalReturnTypes[i] = null;
327-
}
328-
aliasesIndex++;
310+
var aliases = (string[]) cacheable[1];
311+
key.ResultTransformer.SupplyAutoDiscoveredParameters(queryParams.ResultTransformer, aliases);
329312
}
330313
}
331314

@@ -395,9 +378,9 @@ private static List<object> GetCacheableResult(
395378
ICacheAssembler[] returnTypes,
396379
ISessionImplementor session,
397380
IList result,
398-
long ts)
381+
long ts, string[] aliases)
399382
{
400-
var cacheable = new List<object>(result.Count + 1) { ts };
383+
var cacheable = new List<object>(result.Count + 2) { ts, aliases };
401384
foreach (var row in result)
402385
{
403386
if (returnTypes.Length == 1)
@@ -413,12 +396,21 @@ private static List<object> GetCacheableResult(
413396
return cacheable;
414397
}
415398

399+
private static IEnumerable<object> GetResultsEnumerable(IList results)
400+
{
401+
// Skip first element, it is the timestamp, and the second, it is the aliases.
402+
for (var i = 2; i < results.Count; i++)
403+
{
404+
yield return results[i];
405+
}
406+
}
407+
416408
private static ICacheAssembler[] GetReturnTypes(
417409
QueryKey key,
418410
ICacheAssembler[] returnTypes,
419411
IList cacheable)
420412
{
421-
if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0)
413+
if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 2)
422414
{
423415
returnTypes = GuessTypes(cacheable);
424416
}
@@ -435,18 +427,16 @@ private static void PerformBeforeAssemble(
435427
{
436428
var returnType = returnTypes[0];
437429

438-
// Skip first element, it is the timestamp
439-
for (var i = 1; i < cacheable.Count; i++)
430+
foreach (var cached in GetResultsEnumerable(cacheable))
440431
{
441-
returnType.BeforeAssemble(cacheable[i], session);
432+
returnType.BeforeAssemble(cached, session);
442433
}
443434
}
444435
else
445436
{
446-
// Skip first element, it is the timestamp
447-
for (var i = 1; i < cacheable.Count; i++)
437+
foreach (var cached in GetResultsEnumerable(cacheable))
448438
{
449-
TypeHelper.BeforeAssemble((object[]) cacheable[i], returnTypes, session);
439+
TypeHelper.BeforeAssemble((object[]) cached, returnTypes, session);
450440
}
451441
}
452442
}
@@ -460,15 +450,14 @@ private IList PerformAssemble(
460450
{
461451
try
462452
{
463-
var result = new List<object>(cacheable.Count - 1);
453+
var result = new List<object>(cacheable.Count - 2);
464454
if (returnTypes.Length == 1)
465455
{
466456
var returnType = returnTypes[0];
467457

468-
// Skip first element, it is the timestamp
469-
for (var i = 1; i < cacheable.Count; i++)
458+
foreach (var cached in GetResultsEnumerable(cacheable))
470459
{
471-
result.Add(returnType.Assemble(cacheable[i], session, null));
460+
result.Add(returnType.Assemble(cached, session, null));
472461
}
473462
}
474463
else
@@ -482,10 +471,9 @@ private IList PerformAssemble(
482471
}
483472
}
484473

485-
// Skip first element, it is the timestamp
486-
for (var i = 1; i < cacheable.Count; i++)
474+
foreach (var cached in GetResultsEnumerable(cacheable))
487475
{
488-
result.Add(TypeHelper.Assemble((object[]) cacheable[i], returnTypes, nonCollectionTypeIndexes, session));
476+
result.Add(TypeHelper.Assemble((object[]) cached, returnTypes, nonCollectionTypeIndexes, session));
489477
}
490478
}
491479

@@ -530,17 +518,18 @@ private static void InitializeCollections(
530518
return;
531519
}
532520

533-
// Skip first element, it is the timestamp
534-
for (var i = 1; i < cacheResult.Count; i++)
521+
var j = 0;
522+
foreach (var cached in GetResultsEnumerable(cacheResult))
535523
{
536524
// Initialization of the fetched collection must be done at the end in order to be able to batch fetch them
537525
// from the cache or database. The collections were already created when their owners were assembled so we only
538526
// have to initialize them.
539527
TypeHelper.InitializeCollections(
540-
(object[]) cacheResult[i],
541-
(object[]) assembleResult[i - 1],
528+
(object[]) cached,
529+
(object[]) assembleResult[j],
542530
collectionIndexes,
543531
session);
532+
j++;
544533
}
545534
}
546535

@@ -570,23 +559,24 @@ private IList GetResultFromCacheable(
570559

571560
private static ICacheAssembler[] GuessTypes(IList cacheable)
572561
{
573-
var colCount = (cacheable[0] as object[])?.Length ?? 1;
562+
var colCount = (cacheable[2] as object[])?.Length ?? 1;
574563
var returnTypes = new ICacheAssembler[colCount];
575564
if (colCount == 1)
576565
{
577-
foreach (var obj in cacheable)
566+
foreach (var cached in GetResultsEnumerable(cacheable))
578567
{
579-
if (obj == null)
568+
if (cached == null)
580569
continue;
581-
returnTypes[0] = NHibernateUtil.GuessType(obj);
570+
returnTypes[0] = NHibernateUtil.GuessType(cached);
582571
break;
583572
}
584573
}
585574
else
586575
{
587576
var foundTypes = 0;
588-
foreach (object[] row in cacheable)
577+
foreach (var cached in GetResultsEnumerable(cacheable))
589578
{
579+
var row = (object[]) cached;
590580
for (var i = 0; i < colCount; i++)
591581
{
592582
if (row[i] != null && returnTypes[i] == null)

0 commit comments

Comments
 (0)