/// <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; } } }
/// <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); } }
/// <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); } }
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); } }
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); } }