//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="component">The build component that owns the dictionary. This is useful for logging /// messages during initialization.</param> /// <param name="configuration">The target dictionary configuration</param> /// <param name="connectionString">The connection string to use</param> /// <param name="groupId">The group ID to use</param> /// <param name="localCacheSize">The local cache size to use</param> /// <param name="reload">True to reload the cache or false to leave it alone. This is used to reload /// project data so that it is always current.</param> /// <returns>A target dictionary instance that uses a simple in-memory /// <see cref="Dictionary{TKey, TValue}"/> instance to store the targets.</returns> public SqlTargetDictionary(BuildComponentCore component, XPathNavigator configuration, string connectionString, string groupId, int localCacheSize, bool reload) : base(component, configuration) { this.connectionString = connectionString; base.DictionaryId = groupId; index = new SqlDictionary<Target>(connectionString, "Targets", "TargetKey", "TargetValue", "GroupId", groupId) { LocalCacheSize = localCacheSize }; int filesToLoad = 0; if(reload) { filesToLoad = Directory.EnumerateFiles(this.DirectoryPath, this.FilePattern, this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Count(); } else foreach(string file in Directory.EnumerateFiles(this.DirectoryPath, this.FilePattern, this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) if((this.NamespaceFileFilter.Count == 0 || this.NamespaceFileFilter.Contains( Path.GetFileName(file))) && !this.ContainsKey("N:" + Path.GetFileNameWithoutExtension(file))) filesToLoad++; // Loading new targets can take a while so issue a diagnostic message as an alert. The time estimate // is a ballpark figure and depends on the system. if(filesToLoad != 0) { component.WriteMessage(MessageLevel.Diagnostic, "{0} file(s) need to be added to the SQL " + "reflection target cache database. Indexing them will take about {1:N0} minute(s), " + "please be patient. Cache location: {2}", filesToLoad, Math.Ceiling(filesToLoad / 60.0), connectionString); this.LoadTargetDictionary(); } }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="component">The build component that owns the dictionary. This is useful for logging /// messages during initialization.</param> /// <param name="configuration">The target dictionary configuration</param> /// <returns>A target dictionary instance that uses a simple in-memory /// <see cref="Dictionary{TKey, TValue}"/> instance to store the targets.</returns> public ESentTargetDictionary(BuildComponentCore component, XPathNavigator configuration) : base(component, configuration) { bool noReload = false; int localCacheSize; string cachePath = configuration.GetAttribute("cachePath", String.Empty); if(String.IsNullOrWhiteSpace(cachePath)) throw new ArgumentException("The cachePath attribute must contain a value", "configuration"); string cacheSize = configuration.GetAttribute("localCacheSize", String.Empty); if(String.IsNullOrWhiteSpace(cacheSize) || !Int32.TryParse(cacheSize, out localCacheSize)) localCacheSize = 1000; // This is a slightly modified version of Managed ESENT that provides the option to serialize // reference types. In this case, we don't care about potential issues of persisted copies not // matching the original if modified as they are never updated once written to the cache. We can // also turn off column compression for a slight performance increase since it doesn't benefit the // binary data that is serialized. PersistentDictionaryFile.AllowReferenceTypeSerialization = true; index = new PersistentDictionary<string, Target>(cachePath, false) { LocalCacheSize = localCacheSize }; string noReloadValue = configuration.GetAttribute("noReload", String.Empty); // If noReload is true, skip reloading the dictionary if it contains any data. This is used on // project targets to prevent reloading the data in the reference build if already loaded by the // conceptual build. if(!String.IsNullOrWhiteSpace(noReloadValue) && Boolean.TryParse(noReloadValue, out noReload) && noReload && index.Count != 0) return; // Loading new targets can take a while so issue a diagnostic message as an alert int filesToLoad = 0; foreach(string file in Directory.EnumerateFiles(this.DirectoryPath, this.FilePattern, this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) if((this.NamespaceFileFilter.Count == 0 || this.NamespaceFileFilter.Contains( Path.GetFileName(file))) && !this.ContainsKey("N:" + Path.GetFileNameWithoutExtension(file))) filesToLoad++; // The time estimate is a ballpark figure and depends on the system if(filesToLoad != 0) { component.WriteMessage(MessageLevel.Diagnostic, "{0} file(s) need to be added to the ESENT " + "reflection target cache database. Indexing them will take about {1:N0} minute(s), " + "please be patient. Cache location: {2}", filesToLoad, Math.Ceiling(filesToLoad * 10 / 60.0), cachePath); // Limit the degree of parallelism or it overwhelms the ESENT version store this.LoadTargetDictionary(3); } }