Ejemplo n.º 1
0
        /// <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);
                }
            }
        }
Ejemplo n.º 4
0
 private bool ShouldExecuteBatch(ICollectionPersister persister, AbstractCacheBatch batch)
 {
     return(batch != _currentBatch || _currentPersister != persister ||
            _currentBatch.BatchSize >= persister.GetBatchSize());
 }