private static CacheStore GetCacheStore( UniqingScope uniqingScope, string scopeDelimiter, CacheContentType contentType ) { // make sure we always get the global cache if scope is global if( scope == UniqingScope.Application ) { scopeDelimiter = null; } else if( scopeDelimiter == null ) { scopeDelimiter = GetScopeDelimiter(); } // determine which cache to use - first get array of cache stores for the specified scope string scopeKey = String.Format( "{0}|{1}", uniqingScope, scopeDelimiter ); CacheStore[] cacheStores = stores[ scopeKey ] as CacheStore[]; if( cacheStores == null ) { cacheStores = new CacheStore[Enum.GetNames( typeof(CacheContentType) ).Length]; stores[ scopeKey ] = cacheStores; } // get specific cache store by content type CacheStore cacheStore = cacheStores[ (int) contentType ]; if( cacheStore == null ) { cacheStore = new CacheStore(); cacheStores[ (int) contentType ] = cacheStore; } return cacheStore; }
private CacheScope GetCacheScopeIfExists(string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { CacheScope cacheScope = null; // Default the version to the default engine version if (scopeToolsVersion == null) { scopeToolsVersion = defaultToolsVersion; } // Retrieve list of scopes by this name if (cacheContents[(int)cacheContentType].ContainsKey(scopeName)) { List<CacheScope> scopesByName = (List<CacheScope>)cacheContents[(int)cacheContentType][scopeName]; // If the list exists search for matching scope properties otherwise create the list if (scopesByName != null) { lock (cacheManagerLock) { for (int i = 0; i < scopesByName.Count; i++) { if (scopesByName[i].ScopeProperties.IsEquivalent(scopeProperties) && (String.Compare(scopeToolsVersion, scopesByName[i].ScopeToolsVersion, StringComparison.OrdinalIgnoreCase) == 0)) { cacheScope = scopesByName[i]; break; } } } } } return cacheScope; }
/// <summary> /// Called on the main node only. /// </summary> public Exception PostCacheEntriesToHost(int nodeId, CacheEntry[] entries, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { try { parentEngine.CacheManager.SetCacheEntries(entries, scopeName, scopeProperties, scopeToolsVersion, cacheContentType); } catch (InvalidOperationException e) { return e; } return null; }
internal LocalCallDescriptorForPostingCacheEntriesToHost(CacheEntry[] entries, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) : base(LocalCallType.PostCacheEntriesToHost) { this.entries = entries; this.scopeName = scopeName; this.scopeProperties = scopeProperties; this.scopeToolsVersion = scopeToolsVersion; this.cacheContentType = cacheContentType; this.exception = null; }
/// <summary> /// This method return a cache scope with particular name and properties. If the cache /// scope doesn't exist it will be created. This method is thread safe. /// </summary> internal CacheScope GetCacheScope(string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { // If the version is not specified default to the engine version if (scopeToolsVersion == null) { scopeToolsVersion = defaultToolsVersion; } // Retrieve the cache scope if it exists CacheScope cacheScope = GetCacheScopeIfExists(scopeName, scopeProperties, scopeToolsVersion, cacheContentType); // If the scope doesn't exist create it if (cacheScope == null) { lock (cacheManagerLock) { cacheScope = GetCacheScopeIfExists(scopeName, scopeProperties, scopeToolsVersion, cacheContentType); if (cacheScope == null) { // If the list of scopes doesn't exist create it if (!cacheContents[(int)cacheContentType].ContainsKey(scopeName)) { cacheContents[(int)cacheContentType].Add(scopeName, new List<CacheScope>()); } // Create the scope and add it to the list List<CacheScope> scopesByName = (List<CacheScope>)cacheContents[(int)cacheContentType][scopeName]; cacheScope = new CacheScope(scopeName, scopeProperties, scopeToolsVersion); scopesByName.Add(cacheScope); } } } return cacheScope; }
private static CacheStore GetCacheStore(UniqingScope uniqingScope, string scopeDelimiter, CacheContentType contentType) { // make sure we always get the global cache if scope is global if (scope == UniqingScope.Application) { scopeDelimiter = null; } else if (scopeDelimiter == null) { scopeDelimiter = GetScopeDelimiter(); } // determine which cache to use - first get array of cache stores for the specified scope string scopeKey = String.Format("{0}|{1}", uniqingScope, scopeDelimiter); CacheStore[] cacheStores = stores[scopeKey] as CacheStore[]; if (cacheStores == null) { cacheStores = new CacheStore[Enum.GetNames(typeof(CacheContentType)).Length]; stores[scopeKey] = cacheStores; } // get specific cache store by content type CacheStore cacheStore = cacheStores[(int)contentType]; if (cacheStore == null) { cacheStore = new CacheStore(); cacheStores[(int)contentType] = cacheStore; } return(cacheStore); }
/// <summary> /// Posts the given set of cache entries to the parent engine. /// </summary> /// <param name="entries"></param> /// <param name="scopeName"></param> /// <param name="scopeProperties"></param> internal Exception PostCacheEntriesToHost(CacheEntry[] entries, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { try { return parentCallback.PostCacheEntriesToHost(this.nodeId /* ignored */, entries, scopeName, scopeProperties, scopeToolsVersion, cacheContentType); } catch (Exception e) { ReportUnhandledError(e); return null; } }
/// <summary> /// Called either on the main or child node. This is the routing method for setting cache entries. /// </summary> public void SetCacheEntries ( int handleId, CacheEntry[] entries, string cacheScope, string cacheKey, string cacheVersion, CacheContentType cacheContentType, bool localNodeOnly ) { TaskExecutionContext executionContext = GetTaskContextFromHandleId(handleId); BuildPropertyGroup scopeProperties; if (cacheKey == null) { Project parentProject = executionContext.ParentProject; scopeProperties = parentProject.GlobalProperties; } else { // Property values are compared using case sensitive comparisons because the case of property values do have meaning. // In this case we are using properties in a manner where we do not want case sensitive comparisons. // There is not enough benefit for this one special case to add case insensitive // comparisons to build properties. We instead uppercase all of the keys for both get and set CachedEntries. scopeProperties = new BuildPropertyGroup(); scopeProperties.SetProperty("CacheKey", cacheKey.ToUpper(CultureInfo.InvariantCulture)); } if (cacheScope == null) { cacheScope = executionContext.ParentProject.FullFileName; } if (cacheVersion == null) { cacheVersion = executionContext.ParentProject.ToolsVersion; } parentEngine.CacheManager.SetCacheEntries(entries, cacheScope, scopeProperties, cacheVersion, cacheContentType); // Also send these to the parent if we're allowed to if (parentEngine.Router.ChildMode && !localNodeOnly) { Exception exception = parentEngine.Router.ParentNode.PostCacheEntriesToHost(entries, cacheScope, scopeProperties, cacheVersion, cacheContentType); // If we had problems on the parent node, rethrow the exception here if (exception != null) { throw exception; } } }
private static CacheStore GetCacheStore( CacheContentType contentType ) { return GetCacheStore( scope, null, contentType ); }
/// <summary> /// Return the number of items currently in the cache. The cache store to use is determined from /// the scope parameter (combined with the global UniqingScope setting). If null is passed this /// method returns the same as the Count property (current scope). /// </summary> public static int GetCount( string scopeDelimiter, CacheContentType contentType ) { CacheStore cacheStore = GetCacheStore( scope, scopeDelimiter, contentType ); // we need a writer lock because computing the count also removes collected entries cacheStore.Lock.AcquireWriterLock( rwLockTimeOut ); try { return cacheStore.Count; } finally { cacheStore.Lock.ReleaseWriterLock(); } }
/// <summary> /// Clear all entries belonging to the specified scope from the cache. /// </summary> public static void Clear( string scopeDelimiter, CacheContentType contentType ) { // determine which cache to use CacheStore cacheStore = GetCacheStore( scope, scopeDelimiter, contentType ); // access cache cacheStore.Lock.AcquireWriterLock( rwLockTimeOut ); try { cacheStore.Clear(); GentleStatistics.Reset( LogCategories.Cache ); } finally { cacheStore.Lock.ReleaseWriterLock(); } }
/// <summary> /// Send the cache entries to the parent engine /// </summary> /// <param name="nodeId"></param> /// <param name="entries"></param> /// <param name="scopeName"></param> /// <param name="scopeProperties"></param> public Exception PostCacheEntriesToHost(int nodeId, CacheEntry[] entries, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { LocalCallDescriptorForPostingCacheEntriesToHost callDescriptor = new LocalCallDescriptorForPostingCacheEntriesToHost(entries, scopeName, scopeProperties, scopeToolsVersion, cacheContentType); return (Exception)GetReplyForCallDescriptor(callDescriptor); }
/// <summary> /// This method retrieves the cache entries from the master cache /// </summary> /// <param name="nodeId"></param> /// <param name="names"></param> /// <param name="scopeName"></param> /// <param name="scopeProperties"></param> /// <returns></returns> public CacheEntry[] GetCachedEntriesFromHost(int nodeId, string[] names, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { LocalCallDescriptorForGettingCacheEntriesFromHost callDescriptor = new LocalCallDescriptorForGettingCacheEntriesFromHost(names, scopeName, scopeProperties, scopeToolsVersion, cacheContentType); return (CacheEntry[])GetReplyForCallDescriptor(callDescriptor); }
internal LocalCallDescriptorForGettingCacheEntriesFromHost(string[] names, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) : base(LocalCallType.GetCacheEntriesFromHost) { this.names = names; this.scopeName = scopeName; this.scopeProperties = scopeProperties; this.scopeToolsVersion = scopeToolsVersion; this.cacheContentType = cacheContentType; }
internal override void CreateFromStream(BinaryReader reader) { base.CreateFromStream(reader); #region Names if (reader.ReadByte() == 0) { names = null; } else { int numberOfEntries = reader.ReadInt32(); names = new string[numberOfEntries]; for (int i = 0; i < names.Length; i++) { if (reader.ReadByte() != 0) { names[i] = reader.ReadString(); } else { names[i] = null; } } } #endregion #region ScopeName if (reader.ReadByte() == 0) { scopeName = null; } else { scopeName = reader.ReadString(); } #endregion #region ScopeProperties if (reader.ReadByte() == 0) { scopeProperties = null; } else { scopeProperties = new BuildPropertyGroup(); scopeProperties.CreateFromStream(reader); } #endregion #region ScopeToolsVersion if (reader.ReadByte() == 0) { scopeToolsVersion = null; } else { scopeToolsVersion = reader.ReadString(); } #endregion cacheContentType = (CacheContentType)reader.ReadByte(); }
/// <summary> /// Sets multiple cache entries for the given scope /// </summary> /// <param name="entries"></param> /// <param name="scopeName"></param> /// <param name="scopeProperties"></param> internal void SetCacheEntries(CacheEntry[] entries, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { // If the list exists search for matching scope properties otherwise create the list CacheScope cacheScope = GetCacheScope(scopeName, scopeProperties, scopeToolsVersion, cacheContentType); // Add the entry to the right scope cacheScope.AddCacheEntries(entries); }
/// <summary> /// Called either on the main or child node. This is the routing method for getting cache entries. /// </summary> public CacheEntry[] GetCacheEntries ( int handleId, string[] names, string cacheScope, string cacheKey, string cacheVersion, CacheContentType cacheContentType, bool localNodeOnly ) { TaskExecutionContext executionContext = GetTaskContextFromHandleId(handleId); BuildPropertyGroup scopeProperties; if (cacheKey == null) { Project parentProject = executionContext.ParentProject; scopeProperties = parentProject.GlobalProperties; } else { // Property values are compared using case sensitive comparisons because the case of property values do have meaning. // In this case we are using properties in a manner where we do not want case sensitive comparisons. // There is not enough benefit for this one special case to add case insensitive // comparisons to build properties. We instead uppercase all of the keys for both get and set CachedEntries. scopeProperties = new BuildPropertyGroup(); scopeProperties.SetProperty("CacheKey", cacheKey.ToUpper(CultureInfo.InvariantCulture)); } if (cacheScope == null) { cacheScope = executionContext.ParentProject.FullFileName; } if (cacheVersion == null) { cacheVersion = executionContext.ParentProject.ToolsVersion; } CacheEntry[] result = parentEngine.CacheManager.GetCacheEntries(names, cacheScope, scopeProperties, cacheVersion, cacheContentType); bool haveCompleteResult = (result.Length == names.Length); if (haveCompleteResult) { for (int i = 0; i < result.Length; i++) { if (result[i] == null) { haveCompleteResult = false; break; } } } // If we didn't have the complete result locally, check with the parent if allowed. if (!haveCompleteResult && parentEngine.Router.ChildMode && !localNodeOnly) { result = parentEngine.Router.ParentNode.GetCachedEntriesFromHost(names, cacheScope, scopeProperties, cacheVersion, cacheContentType); parentEngine.CacheManager.SetCacheEntries(result, cacheScope, scopeProperties, cacheVersion, cacheContentType); } return result; }
/// <summary> /// Gets multiple cache entries from the given scope. /// </summary> /// <param name="names"></param> /// <param name="scopeName"></param> /// <param name="scopeProperties"></param> /// <returns></returns> internal CacheEntry[] GetCacheEntries(string[] names, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { CacheScope cacheScope = GetCacheScopeIfExists(scopeName, scopeProperties, scopeToolsVersion, cacheContentType); if (cacheScope != null) { return cacheScope.GetCacheEntries(names); } return new CacheEntry[names.Length]; }
/// <summary> /// Called on the main node only. /// </summary> public CacheEntry[] GetCachedEntriesFromHost(int nodeId, string[] names, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { return parentEngine.CacheManager.GetCacheEntries(names, scopeName, scopeProperties, scopeToolsVersion, cacheContentType); }
/// <summary> /// Clear a particular scope /// </summary> /// <param name="projectName"></param> /// <param name="buildPropertyGroup"></param> /// <param name="toolsVersion"></param> internal void ClearCacheScope(string projectName, BuildPropertyGroup buildPropertyGroup, string toolsVersion, CacheContentType cacheContentType) { // Retrieve list of scopes by this name if (cacheContents[(int)cacheContentType].ContainsKey(projectName)) { List<CacheScope> scopesByName = (List<CacheScope>)cacheContents[(int)cacheContentType][projectName]; // If the list exists search for matching scope properties otherwise create the list if (scopesByName != null) { // If the version is not specified default to the engine version if (toolsVersion == null) { toolsVersion = defaultToolsVersion; } lock (cacheManagerLock) { for (int i = 0; i < scopesByName.Count; i++) { if (scopesByName[i].ScopeProperties.IsEquivalent(buildPropertyGroup) && (String.Compare(toolsVersion, scopesByName[i].ScopeToolsVersion, StringComparison.OrdinalIgnoreCase) == 0)) { scopesByName.RemoveAt(i); break; } } } } } }
/// <summary> /// Retrieves the requested set of cache entries from the engine. /// </summary> /// <param name="names"></param> /// <param name="scopeName"></param> /// <param name="scopeProperties"></param> /// <returns></returns> internal CacheEntry[] GetCachedEntriesFromHost(string[] names, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType) { try { return parentCallback.GetCachedEntriesFromHost(this.nodeId /* ignored */, names, scopeName, scopeProperties, scopeToolsVersion, cacheContentType); } catch (Exception e) { ReportUnhandledError(e); return new CacheEntry[0]; } }
private static CacheStore GetCacheStore(CacheContentType contentType) { return(GetCacheStore(scope, null, contentType)); }