Пример #1
0
        /// <summary> Try to initialize a collection from the cache</summary>
        private async Task <bool> InitializeCollectionFromCacheAsync(object id, 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);
            }
            else
            {
                ISessionFactoryImplementor factory = source.Factory;

                CacheKey ck = source.GenerateCacheKey(id, persister.KeyType, persister.Role);
                object   ce = await(persister.Cache.GetAsync(ck, source.Timestamp, cancellationToken)).ConfigureAwait(false);

                if (factory.Statistics.IsStatisticsEnabled)
                {
                    if (ce == null)
                    {
                        factory.StatisticsImplementor.SecondLevelCacheMiss(persister.Cache.RegionName);
                    }
                    else
                    {
                        factory.StatisticsImplementor.SecondLevelCacheHit(persister.Cache.RegionName);
                    }
                }

                if (ce == null)
                {
                    log.Debug("Collection cache miss: {0}", ck);
                }
                else
                {
                    log.Debug("Collection cache hit: {0}", ck);
                }

                if (ce == null)
                {
                    return(false);
                }
                else
                {
                    IPersistenceContext persistenceContext = source.PersistenceContext;

                    CollectionCacheEntry cacheEntry = (CollectionCacheEntry)persister.CacheEntryStructure.Destructure(ce, factory);
                    await(cacheEntry.AssembleAsync(collection, persister, persistenceContext.GetCollectionOwner(id, persister), cancellationToken)).ConfigureAwait(false);

                    persistenceContext.GetCollectionEntry(collection).PostInitialize(collection);
                    return(true);
                }
            }
        }
		/// <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 & CacheMode.Get) == CacheMode.Get);

			if (!useCache)
			{
				return false;
			}
			else
			{
				ISessionFactoryImplementor factory = source.Factory;

				CacheKey ck = new CacheKey(id, persister.KeyType, persister.Role, source.EntityMode, factory);
				object ce = persister.Cache.Get(ck, source.Timestamp);

				if (factory.Statistics.IsStatisticsEnabled)
				{
					if (ce == null)
					{
						factory.StatisticsImplementor.SecondLevelCacheMiss(persister.Cache.RegionName);
					}
					else
					{
						factory.StatisticsImplementor.SecondLevelCacheHit(persister.Cache.RegionName);
					}
				}

				if (ce == null)
				{
					log.DebugFormat("Collection cache miss: {0}", ck);
				}
				else
				{
					log.DebugFormat("Collection cache hit: {0}", ck);
				}

				if (ce == null)
				{
					return false;
				}
				else
				{
					IPersistenceContext persistenceContext = source.PersistenceContext;

					CollectionCacheEntry cacheEntry = (CollectionCacheEntry)persister.CacheEntryStructure.Destructure(ce, factory);
					cacheEntry.Assemble(collection, persister, persistenceContext.GetCollectionOwner(id, persister));

					persistenceContext.GetCollectionEntry(collection).PostInitialize(collection);
					return true;
				}
			}
		}
Пример #3
0
        /// <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 & CacheMode.Get) == CacheMode.Get);

            if (!useCache)
            {
                return(false);
            }
            else
            {
                ISessionFactoryImplementor factory = source.Factory;

                CacheKey ck = new CacheKey(id, persister.KeyType, persister.Role, source.EntityMode, factory);
                object   ce = persister.Cache.Get(ck, source.Timestamp);

                if (factory.Statistics.IsStatisticsEnabled)
                {
                    if (ce == null)
                    {
                        factory.StatisticsImplementor.SecondLevelCacheMiss(persister.Cache.RegionName);
                    }
                    else
                    {
                        factory.StatisticsImplementor.SecondLevelCacheHit(persister.Cache.RegionName);
                    }
                }

                if (ce == null)
                {
                    log.DebugFormat("Collection cache miss: {0}", ck);
                }
                else
                {
                    log.DebugFormat("Collection cache hit: {0}", ck);
                }

                if (ce == null)
                {
                    return(false);
                }
                else
                {
                    IPersistenceContext persistenceContext = source.PersistenceContext;

                    CollectionCacheEntry cacheEntry = (CollectionCacheEntry)persister.CacheEntryStructure.Destructure(ce, factory);
                    cacheEntry.Assemble(collection, persister, persistenceContext.GetCollectionOwner(id, persister));

                    persistenceContext.GetCollectionEntry(collection).PostInitialize(collection);
                    return(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="cancellationToken">A cancellation token that can be used to cancel the work</param>
        private async Task AddCollectionToCacheAsync(LoadingCollectionEntry lce, ICollectionPersister persister, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            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    = new CollectionCacheEntry(lce.Collection, persister);
            CacheKey             cacheKey = session.GenerateCacheKey(lce.Key, persister.KeyType, persister.Role);
            bool put = await(persister.Cache.PutAsync(cacheKey, persister.CacheEntryStructure.Structure(entry),
                                                      session.Timestamp, version, versionComparator,
                                                      factory.Settings.IsMinimalPutsEnabled && session.CacheMode != CacheMode.Refresh, cancellationToken)).ConfigureAwait(false);

            if (put && factory.Statistics.IsStatisticsEnabled)
            {
                factory.StatisticsImplementor.SecondLevelCachePut(persister.Cache.RegionName);
            }
        }
Пример #5
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>
		private void AddCollectionToCache(LoadingCollectionEntry lce, ICollectionPersister persister)
		{
			ISessionImplementor session = LoadContext.PersistenceContext.Session;
			ISessionFactoryImplementor factory = session.Factory;

			if (log.IsDebugEnabled)
			{
				log.Debug("Caching collection: " + MessageHelper.InfoString(persister, lce.Key, factory));
			}

			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);
				version = LoadContext.PersistenceContext.GetEntry(collectionOwner).Version;
			}
			else
			{
				version = null;
				versionComparator = null;
			}

			CollectionCacheEntry entry = new CollectionCacheEntry(lce.Collection, persister);
			CacheKey cacheKey = session.GenerateCacheKey(lce.Key, persister.KeyType, persister.Role);
			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);
			}
		}
Пример #8
0
        public override void Execute()
        {
            object id = Key;
            ISessionImplementor   session    = Session;
            ICollectionPersister  persister  = Persister;
            IPersistentCollection collection = Collection;
            bool affectedByFilters           = persister.IsAffectedByEnabledFilters(session);

            bool      statsEnabled = session.Factory.Statistics.IsStatisticsEnabled;
            Stopwatch stopwatch    = null;

            if (statsEnabled)
            {
                stopwatch = Stopwatch.StartNew();
            }

            PreUpdate();

            if (!collection.WasInitialized)
            {
                if (!collection.HasQueuedOperations)
                {
                    throw new AssertionFailure("no queued adds");
                }
                //do nothing - we only need to notify the cache...
            }
            else if (!affectedByFilters && collection.Empty)
            {
                if (!emptySnapshot)
                {
                    persister.Remove(id, session);
                }
            }
            else if (collection.NeedsRecreate(persister))
            {
                if (affectedByFilters)
                {
                    throw new HibernateException("cannot recreate collection while filter is enabled: "
                                                 + MessageHelper.CollectionInfoString(persister, collection, id, session));
                }
                if (!emptySnapshot)
                {
                    persister.Remove(id, session);
                }
                persister.Recreate(collection, id, session);
            }
            else
            {
                persister.DeleteRows(collection, id, session);
                persister.UpdateRows(collection, id, session);
                persister.InsertRows(collection, id, session);
            }

            Session.PersistenceContext.GetCollectionEntry(collection).AfterAction(collection);

            Evict();

            PostUpdate();

            if (statsEnabled)
            {
                stopwatch.Stop();
                Session.Factory.StatisticsImplementor.UpdateCollection(Persister.Role, stopwatch.Elapsed);
            }
        }
Пример #9
0
        public override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            object id = await(GetKeyAsync(cancellationToken)).ConfigureAwait(false);
            ISessionImplementor   session    = Session;
            ICollectionPersister  persister  = Persister;
            IPersistentCollection collection = Collection;
            bool affectedByFilters           = persister.IsAffectedByEnabledFilters(session);

            bool      statsEnabled = session.Factory.Statistics.IsStatisticsEnabled;
            Stopwatch stopwatch    = null;

            if (statsEnabled)
            {
                stopwatch = Stopwatch.StartNew();
            }

            await(PreUpdateAsync(cancellationToken)).ConfigureAwait(false);

            if (!collection.WasInitialized)
            {
                if (!collection.HasQueuedOperations)
                {
                    throw new AssertionFailure("no queued adds");
                }
                //do nothing - we only need to notify the cache...
            }
            else if (!affectedByFilters && collection.Empty)
            {
                if (!emptySnapshot)
                {
                    await(persister.RemoveAsync(id, session, cancellationToken)).ConfigureAwait(false);
                }
            }
            else if (collection.NeedsRecreate(persister))
            {
                if (affectedByFilters)
                {
                    throw new HibernateException("cannot recreate collection while filter is enabled: "
                                                 + MessageHelper.CollectionInfoString(persister, collection, id, session));
                }
                if (!emptySnapshot)
                {
                    await(persister.RemoveAsync(id, session, cancellationToken)).ConfigureAwait(false);
                }
                await(persister.RecreateAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
            }
            else
            {
                await(persister.DeleteRowsAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
                await(persister.UpdateRowsAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
                await(persister.InsertRowsAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
            }

            var entry = Session.PersistenceContext.GetCollectionEntry(collection);

            entry.AfterAction(collection);

            await(EvictAsync(cancellationToken)).ConfigureAwait(false);

            await(PostUpdateAsync(cancellationToken)).ConfigureAwait(false);

            if (statsEnabled)
            {
                stopwatch.Stop();
                Session.Factory.StatisticsImplementor.UpdateCollection(Persister.Role, stopwatch.Elapsed);
            }
        }