/// <summary> Try to initialize a collection from the cache</summary> private async Task <bool> InitializeCollectionFromCacheAsync( object collectionKey, ICollectionPersister persister, IPersistentCollection collection, ISessionImplementor source, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (!(source.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(source)) { log.Debug("disregarding cached version (if any) of collection due to enabled filters "); return(false); } bool useCache = persister.HasCache && source.CacheMode.HasFlag(CacheMode.Get); if (!useCache) { return(false); } var batchSize = persister.GetBatchSize(); if (batchSize > 1 && persister.Cache.PreferMultipleGet()) { var collectionEntries = new CollectionEntry[batchSize]; // The first item in the array is the item that we want to load var collectionBatch = await(source.PersistenceContext.BatchFetchQueue .GetCollectionBatchAsync(persister, collectionKey, batchSize, false, collectionEntries, cancellationToken)).ConfigureAwait(false); // Ignore null values as the retrieved batch may contains them when there are not enough // uninitialized collection in the queue var keys = new List <CacheKey>(batchSize); for (var i = 0; i < collectionBatch.Length; i++) { var key = collectionBatch[i]; if (key == null) { break; } keys.Add(source.GenerateCacheKey(key, persister.KeyType, persister.Role)); } var cachedObjects = await(persister.Cache.GetManyAsync(keys.ToArray(), source.Timestamp, cancellationToken)).ConfigureAwait(false); for (var i = 1; i < cachedObjects.Length; i++) { var coll = source.PersistenceContext.BatchFetchQueue.GetBatchLoadableCollection(persister, collectionEntries[i]); await(AssembleAsync(keys[i], cachedObjects[i], persister, source, coll, collectionBatch[i], false, cancellationToken)).ConfigureAwait(false); } return(await(AssembleAsync(keys[0], cachedObjects[0], persister, source, collection, collectionKey, true, cancellationToken)).ConfigureAwait(false)); } var cacheKey = source.GenerateCacheKey(collectionKey, persister.KeyType, persister.Role); var cachedObject = await(persister.Cache.GetAsync(cacheKey, source.Timestamp, cancellationToken)).ConfigureAwait(false); return(await(AssembleAsync(cacheKey, cachedObject, persister, source, collection, collectionKey, true, cancellationToken)).ConfigureAwait(false)); }
/// <summary> Try to initialize a collection from the cache</summary> private bool InitializeCollectionFromCache(object id, ICollectionPersister persister, IPersistentCollection collection, ISessionImplementor source) { if (!(source.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(source)) { log.Debug("disregarding cached version (if any) of collection due to enabled filters "); return(false); } bool useCache = persister.HasCache && source.CacheMode.HasFlag(CacheMode.Get); if (!useCache) { return(false); } var batchSize = persister.GetBatchSize(); if (batchSize > 1 && persister.Cache.IsBatchingGetSupported()) { var collectionEntries = new CollectionEntry[batchSize]; // The first item in the array is the item that we want to load var collectionBatch = source.PersistenceContext.BatchFetchQueue .GetCollectionBatch(persister, id, batchSize, false, collectionEntries); // Ignore null values as the retrieved batch may contains them when there are not enough // uninitialized collection in the queue var keys = new List <CacheKey>(batchSize); for (var i = 0; i < collectionBatch.Length; i++) { var key = collectionBatch[i]; if (key == null) { break; } keys.Add(source.GenerateCacheKey(key, persister.KeyType, persister.Role)); } var cachedObjects = persister.Cache.GetMany(keys.ToArray(), source.Timestamp); for (var i = 1; i < cachedObjects.Length; i++) { var coll = source.PersistenceContext.BatchFetchQueue.GetBatchLoadableCollection(persister, collectionEntries[i]); Assemble(keys[i], cachedObjects[i], persister, source, coll, collectionBatch[i], false); } return(Assemble(keys[0], cachedObjects[0], persister, source, collection, id, true)); } var cacheKey = source.GenerateCacheKey(id, persister.KeyType, persister.Role); var cachedObject = persister.Cache.Get(cacheKey, source.Timestamp); return(Assemble(cacheKey, cachedObject, persister, source, collection, id, true)); }
/// <summary> Add the collection to the second-level cache </summary> /// <param name="lce">The entry representing the collection to add </param> /// <param name="persister">The persister </param> /// <param name="cacheBatchingHandler">The action for handling cache batching</param> private void AddCollectionToCache(LoadingCollectionEntry lce, ICollectionPersister persister, Action <CachePutData> cacheBatchingHandler) { ISessionImplementor session = LoadContext.PersistenceContext.Session; ISessionFactoryImplementor factory = session.Factory; if (log.IsDebugEnabled()) { log.Debug("Caching collection: {0}", MessageHelper.CollectionInfoString(persister, lce.Collection, lce.Key, session)); } if (!(session.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(session)) { // some filters affecting the collection are enabled on the session, so do not do the put into the cache. log.Debug("Refusing to add to cache due to enabled filters"); // todo : add the notion of enabled filters to the CacheKey to differentiate filtered collections from non-filtered; // but CacheKey is currently used for both collections and entities; would ideally need to define two separate ones; // currently this works in conjunction with the check on // DefaultInitializeCollectionEventHandler.initializeCollectionFromCache() (which makes sure to not read from // cache with enabled filters). return; // EARLY EXIT!!!!! } IComparer versionComparator; object version; if (persister.IsVersioned) { versionComparator = persister.OwnerEntityPersister.VersionType.Comparator; object collectionOwner = LoadContext.PersistenceContext.GetCollectionOwner(lce.Key, persister); if (collectionOwner == null) { return; } version = LoadContext.PersistenceContext.GetEntry(collectionOwner).Version; } else { version = null; versionComparator = null; } CollectionCacheEntry entry = CollectionCacheEntry.Create(lce.Collection, persister); CacheKey cacheKey = session.GenerateCacheKey(lce.Key, persister.KeyType, persister.Role); if (persister.GetBatchSize() > 1) { cacheBatchingHandler( new CachePutData( cacheKey, persister.CacheEntryStructure.Structure(entry), version, versionComparator, factory.Settings.IsMinimalPutsEnabled && session.CacheMode != CacheMode.Refresh)); } else { bool put = persister.Cache.Put(cacheKey, persister.CacheEntryStructure.Structure(entry), session.Timestamp, version, versionComparator, factory.Settings.IsMinimalPutsEnabled && session.CacheMode != CacheMode.Refresh); if (put && factory.Statistics.IsStatisticsEnabled) { factory.StatisticsImplementor.SecondLevelCachePut(persister.Cache.RegionName); } } }
private bool ShouldExecuteBatch(ICollectionPersister persister, AbstractCacheBatch batch) { return(batch != _currentBatch || _currentPersister != persister || _currentBatch.BatchSize >= persister.GetBatchSize()); }