public object Assemble(object cached, ISessionImplementor session, object owner) { IList srcList = (IList)cached; var result = new List <object>(); for (int i = 0; i < assemblersList.Count; i++) { ICacheAssembler[] assemblers = (ICacheAssembler[])assemblersList[i]; IList queryFromCache = (IList)srcList[i]; var queryResults = new List <object>(); foreach (object fromCache in queryFromCache) { if (assemblers.Length == 1) { queryResults.Add(assemblers[0].Assemble(fromCache, session, owner)); } else { queryResults.Add(TypeHelper.Assemble((object[])fromCache, assemblers, session, owner)); } } result.Add(queryResults); } return(result); }
private IList PerformAssemble( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable) { try { var result = new List <object>(cacheable.Count - 1); if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { result.Add(returnType.Assemble(cacheable[i], session, null)); } } else { var nonCollectionTypeIndexes = new List <int>(); for (var i = 0; i < returnTypes.Length; i++) { if (!(returnTypes[i] is CollectionType)) { nonCollectionTypeIndexes.Add(i); } } // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, nonCollectionTypeIndexes, session)); } } return(result); } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); // Handling a RemoveMany here does not look worth it, as this case short-circuits // the result-set. So a Many could only benefit batched queries, and only if many // of them are natural key lookup with an unresolvable object case. Cache.Remove(key); return(null); } throw; } }
private static object[] Assemble(object[] values, object result, object id, IEntityPersister persister, IInterceptor interceptor, ISessionImplementor session) { //assembled state gets put in a new array (we read from cache by value!) object[] assembledProps = TypeHelper.Assemble(values, persister.PropertyTypes, session, result); //from h3.2 TODO: reuse the PreLoadEvent PreLoadEvent preLoadEvent = new PreLoadEvent((IEventSource)session); preLoadEvent.Entity = result; preLoadEvent.State = assembledProps; preLoadEvent.Id = id; preLoadEvent.Persister = persister; IPreLoadEventListener[] listeners = session.Listeners.PreLoadEventListeners; for (int i = 0; i < listeners.Length; i++) { listeners[i].OnPreLoad(preLoadEvent); } persister.SetPropertyValues(result, assembledProps); return(assembledProps); }
public IList Get(QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISet <string> spaces, ISessionImplementor session) { if (Log.IsDebugEnabled) { Log.DebugFormat("checking cached query results in region: '{0}'; {1}", _regionName, key); } var cacheable = (IList)_queryCache.Get(key); if (cacheable == null) { Log.DebugFormat("query results were not found in cache: {0}", key); return(null); } var timestamp = (long)cacheable[0]; if (Log.IsDebugEnabled) { Log.DebugFormat("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(spaces)); } if (!isNaturalKeyLookup && !IsUpToDate(spaces, timestamp)) { Log.DebugFormat("cached query results were not up to date for: {0}", key); return(null); } Log.DebugFormat("returning cached query results for: {0}", key); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1 && !key.HasResultTransformer) { returnTypes[0].BeforeAssemble(cacheable[i], session); } else { TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } } IList result = new List <object>(cacheable.Count - 1); for (int i = 1; i < cacheable.Count; i++) { try { if (returnTypes.Length == 1 && !key.HasResultTransformer) { result.Add(returnTypes[0].Assemble(cacheable[i], session, null)); } else { result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, session, null)); } } catch (UnresolvableObjectException) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug("could not reassemble cached result set"); _queryCache.Remove(key); return(null); } throw; } } return(result); }
private IList GetResultFromCacheable( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable) { Log.Debug("returning cached query results for: {0}", key); if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0) { returnTypes = GuessTypes(cacheable); } try { var result = new List <object>(cacheable.Count - 1); if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { returnType.BeforeAssemble(cacheable[i], session); } for (var i = 1; i < cacheable.Count; i++) { result.Add(returnType.Assemble(cacheable[i], session, null)); } } else { var collectionIndexes = new Dictionary <int, ICollectionPersister>(); var nonCollectionTypeIndexes = new List <int>(); for (var i = 0; i < returnTypes.Length; i++) { if (returnTypes[i] is CollectionType collectionType) { collectionIndexes.Add(i, session.Factory.GetCollectionPersister(collectionType.Role)); } else { nonCollectionTypeIndexes.Add(i); } } // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } for (var i = 1; i < cacheable.Count; i++) { result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, nonCollectionTypeIndexes, session)); } // Initialization of the fetched collection must be done at the end in order to be able to batch fetch them // from the cache or database. The collections were already created in the previous for statement so we only // have to initialize them. if (collectionIndexes.Count > 0) { for (var i = 1; i < cacheable.Count; i++) { TypeHelper.InitializeCollections((object[])cacheable[i], (object[])result[i - 1], collectionIndexes, session); } } } return(result); } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); // Handling a RemoveMany here does not look worth it, as this case short-circuits // the result-set. So a Many could only benefit batched queries, and only if many // of them are natural key lookup with an unresolvable object case. Cache.Remove(key); return(null); } throw; } }
private IList GetResultFromCacheable( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable) { Log.Debug("returning cached query results for: {0}", key); if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0) { returnTypes = GuessTypes(cacheable); } try { var result = new List <object>(cacheable.Count - 1); if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp var rows = new List <object>(cacheable.Count - 1); for (var i = 1; i < cacheable.Count; i++) { rows.Add(cacheable[i]); } foreach (var row in rows) { returnType.BeforeAssemble(row, session); } foreach (var row in rows) { result.Add(returnType.Assemble(row, session, null)); } } else { // Skip first element, it is the timestamp var rows = new List <object[]>(cacheable.Count - 1); for (var i = 1; i < cacheable.Count; i++) { rows.Add((object[])cacheable[i]); } foreach (var row in rows) { TypeHelper.BeforeAssemble(row, returnTypes, session); } foreach (var row in rows) { result.Add(TypeHelper.Assemble(row, returnTypes, session, null)); } } return(result); } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); // Handling a RemoveMany here does not look worth it, as this case short-circuits // the result-set. So a Many could only benefit batched queries, and only if many // of them are natural key lookup with an unresolvable object case. Cache.Remove(key); return(null); } throw; } }