public virtual bool IsUpToDate(ISet <string> spaces, long timestamp /* H2.1 has Long here */)
        {
            if (spaces.Count == 0)
            {
                return(true);
            }

            var lastUpdates = _updateTimestamps.GetMany(spaces.ToArray <object>());

            return(lastUpdates.All(lastUpdate => !IsOutdated(lastUpdate as long?, timestamp)));
        }
Пример #2
0
        public virtual bool IsUpToDate(ISet <string> spaces, long timestamp /* H2.1 has Long here */)
        {
            if (spaces.Count == 0)
            {
                return(true);
            }

            var keys  = new object[spaces.Count];
            var index = 0;

            foreach (var space in spaces)
            {
                keys[index++] = space;
            }
            var lastUpdates = _updateTimestamps.GetMany(keys);

            return(lastUpdates.All(lastUpdate => !IsOutdated(lastUpdate as long?, timestamp)));
        }
        /// <inheritdoc />
        public IList[] GetMany(
            QueryKey[] keys,
            QueryParameters[] queryParameters,
            ICacheAssembler[][] returnTypes,
            ISet <string>[] spaces,
            ISessionImplementor session)
        {
            if (Log.IsDebugEnabled())
            {
                Log.Debug("checking cached query results in region: '{0}'; {1}", _regionName, StringHelper.CollectionToString(keys));
            }

            var cacheables = _cache.GetMany(keys);

            var spacesToCheck          = new List <ISet <string> >();
            var checkedSpacesIndexes   = new HashSet <int>();
            var checkedSpacesTimestamp = new List <long>();

            for (var i = 0; i < keys.Length; i++)
            {
                var cacheable = (IList)cacheables[i];
                if (cacheable == null)
                {
                    Log.Debug("query results were not found in cache: {0}", keys[i]);
                    continue;
                }

                var querySpaces = spaces[i];
                if (queryParameters[i].NaturalKeyLookup || querySpaces.Count == 0)
                {
                    continue;
                }

                spacesToCheck.Add(querySpaces);
                checkedSpacesIndexes.Add(i);
                // The timestamp is the first element of the cache result.
                checkedSpacesTimestamp.Add((long)cacheable[0]);
                if (Log.IsDebugEnabled())
                {
                    Log.Debug("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(querySpaces));
                }
            }

            var upToDates = spacesToCheck.Count > 0
                                ? _updateTimestampsCache.AreUpToDate(spacesToCheck.ToArray(), checkedSpacesTimestamp.ToArray())
                                : Array.Empty <bool>();

            var upToDatesIndex      = 0;
            var persistenceContext  = session.PersistenceContext;
            var defaultReadOnlyOrig = persistenceContext.DefaultReadOnly;
            var results             = new IList[keys.Length];
            var finalReturnTypes    = new ICacheAssembler[keys.Length][];

            try
            {
                session.PersistenceContext.BatchFetchQueue.InitializeQueryCacheQueue();

                for (var i = 0; i < keys.Length; i++)
                {
                    var cacheable = (IList)cacheables[i];
                    if (cacheable == null)
                    {
                        continue;
                    }

                    var key = keys[i];
                    if (checkedSpacesIndexes.Contains(i) && !upToDates[upToDatesIndex++])
                    {
                        Log.Debug("cached query results were not up to date for: {0}", key);
                        continue;
                    }

                    var queryParams = queryParameters[i];
                    if (queryParams.IsReadOnlyInitialized)
                    {
                        persistenceContext.DefaultReadOnly = queryParams.ReadOnly;
                    }
                    else
                    {
                        queryParams.ReadOnly = persistenceContext.DefaultReadOnly;
                    }

                    Log.Debug("returning cached query results for: {0}", key);

                    finalReturnTypes[i] = GetReturnTypes(key, returnTypes[i], cacheable);
                    PerformBeforeAssemble(finalReturnTypes[i], session, cacheable);
                }

                for (var i = 0; i < keys.Length; i++)
                {
                    if (finalReturnTypes[i] == null)
                    {
                        continue;
                    }

                    var queryParams = queryParameters[i];
                    // Adjust the session cache mode, as PerformAssemble assemble types which may cause
                    // entity loads, which may interact with the cache.
                    using (session.SwitchCacheMode(queryParams.CacheMode))
                    {
                        try
                        {
                            results[i] = PerformAssemble(keys[i], finalReturnTypes[i], queryParams.NaturalKeyLookup, session, (IList)cacheables[i]);
                        }
                        finally
                        {
                            persistenceContext.DefaultReadOnly = defaultReadOnlyOrig;
                        }
                    }
                }

                for (var i = 0; i < keys.Length; i++)
                {
                    if (finalReturnTypes[i] == null)
                    {
                        continue;
                    }

                    var queryParams = queryParameters[i];
                    // Adjust the session cache mode, as InitializeCollections will initialize collections,
                    // which may interact with the cache.
                    using (session.SwitchCacheMode(queryParams.CacheMode))
                    {
                        try
                        {
                            InitializeCollections(finalReturnTypes[i], session, results[i], (IList)cacheables[i]);
                        }
                        finally
                        {
                            persistenceContext.DefaultReadOnly = defaultReadOnlyOrig;
                        }
                    }
                }
            }
            finally
            {
                session.PersistenceContext.BatchFetchQueue.TerminateQueryCacheQueue();
            }

            return(results);
        }