public IndexedDocumentCache(CopyFromIndexComponent component, string keyXPath, string valueXPath, XmlNamespaceManager context, int cacheSize) { if (component == null) { throw new ArgumentNullException("component"); } if (cacheSize < 0) { throw new ArgumentOutOfRangeException("cacheSize"); } this.component = component; try { keyExpression = XPathExpression.Compile(keyXPath); } catch (XPathException) { component.WriteHelperMessage(MessageLevel.Error, String.Format("The key expression '{0}' is not a valid XPath expression.", keyXPath)); } keyExpression.SetContext(context); try { valueExpression = XPathExpression.Compile(valueXPath); } catch (XPathException) { component.WriteHelperMessage(MessageLevel.Error, String.Format("The value expression '{0}' is not a valid XPath expression.", valueXPath)); } valueExpression.SetContext(context); this.cacheSize = cacheSize; // set up the cache cache = new Dictionary <string, IndexedDocument>(cacheSize); queue = new Queue <string>(cacheSize); }
public IndexedDocumentCache(CopyFromIndexComponent component, string keyXPath, string valueXPath, XmlNamespaceManager context, int cacheSize) { if (component == null) throw new ArgumentNullException("component"); if (cacheSize < 0) throw new ArgumentOutOfRangeException("cacheSize"); this.component = component; try { keyExpression = XPathExpression.Compile(keyXPath); } catch (XPathException) { component.WriteHelperMessage(MessageLevel.Error, String.Format("The key expression '{0}' is not a valid XPath expression.", keyXPath)); } keyExpression.SetContext(context); try { valueExpression = XPathExpression.Compile(valueXPath); } catch (XPathException) { component.WriteHelperMessage(MessageLevel.Error, String.Format("The value expression '{0}' is not a valid XPath expression.", valueXPath)); } valueExpression.SetContext(context); this.cacheSize = cacheSize; // set up the cache cache = new Dictionary<string, IndexedDocument>(cacheSize); queue = new Queue<string>(cacheSize); }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="component">The <see cref="CopyFromIndexComponent"/> to which the indexed cache belongs</param> /// <param name="context">A context to use with the key and value XPath expressions</param> /// <param name="configuration">The configuration to use</param> public ESentIndexedCache(CopyFromIndexComponent component, XmlNamespaceManager context, XPathNavigator configuration) : base(component, context, configuration) { settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; esentCaches = new List<PersistentDictionary<string, string>>(); }
//===================================================================== /// <summary> /// Load a cached index /// </summary> /// <param name="index">The parent index node</param> /// <param name="name">The name of the index</param> /// <param name="cache">The cache settings</param> private void LoadCache(XPathNavigator index, string name, XPathNavigator cache) { XPathDocument xdoc; XPathNavigator nav; CopyFromIndexComponent copyComp = null; BinaryFormatter bf = new BinaryFormatter(); Dictionary<string, string> cachedIndex, actualIndex; FieldInfo field; Object cacheData; Type type; FileStream fs = null; string parent, config, path, cacheFile, tempName; cacheFile = cache.GetAttribute("cacheFile", String.Empty); if(String.IsNullOrEmpty(cacheFile)) throw new ConfigurationErrorsException("You must specify " + "a cacheFile value on the cache element."); // Create the folder if it doesn't exist cacheFile = Path.GetFullPath(Environment.ExpandEnvironmentVariables( cacheFile)); path = Path.GetDirectoryName(cacheFile); if(!Directory.Exists(path)) Directory.CreateDirectory(path); try { // If it doesn't exist, create it on first use if(!File.Exists(cacheFile)) { base.WriteMessage(MessageLevel.Warn, cacheFile + " does not exist and is being created"); parent = index.OuterXml; config = cache.OuterXml.Replace("<cache ", "<data "); tempName = "@" + name; parent = parent.Substring(0, parent.IndexOf('>') + 1).Replace( "\"" + name + "\"", "\"" + tempName + "\""); config = String.Format(CultureInfo.InvariantCulture, "<component>\r\n{0}\r\n{1}\r\n</index>\r\n</component>", parent, config); // Create a second CopyFromIndex component and pass it // just enough information to create the index. xdoc = new XPathDocument(new StringReader(config)); nav = xdoc.CreateNavigator().SelectSingleNode("component"); copyComp = new CopyFromIndexComponent(this.BuildAssembler, nav); // Get the data from the temporary index cacheData = BuildComponent.Data[tempName]; type = cacheData.GetType(); field = type.GetField("index", BindingFlags.NonPublic | BindingFlags.Instance); cachedIndex = (Dictionary<string, string>)field.GetValue( cacheData); // Save the cached data for use in subsequent builds fs = new FileStream(cacheFile, FileMode.Create); bf.Serialize(fs, cachedIndex); BuildComponent.Data.Remove(tempName); } else { // Load the existing cached index fs = new FileStream(cacheFile, FileMode.Open); cachedIndex = (Dictionary<string, string>)bf.Deserialize(fs); } } finally { if(fs != null) fs.Close(); if(copyComp != null) copyComp.Dispose(); } // Get the dictionary containing the user's index info cacheData = BuildComponent.Data[name]; type = cacheData.GetType(); field = type.GetField("index", BindingFlags.NonPublic | BindingFlags.Instance); actualIndex = (Dictionary<string, string>)field.GetValue(cacheData); // Add the cached info from the framework files. If there's a // duplicate, the later copy will take precedence. foreach(string key in cachedIndex.Keys) if(!actualIndex.ContainsKey(key)) actualIndex.Add(key, cachedIndex[key]); else { base.WriteMessage(MessageLevel.Warn, String.Format( CultureInfo.InvariantCulture, "Key '{0}' in " + "this framework cache matches an item from a prior " + "cache with the same key. The item from this cache " + "will take precedence.", key)); actualIndex[key] = cachedIndex[key]; } base.WriteMessage(MessageLevel.Info, String.Format( CultureInfo.InvariantCulture, "Loaded {0} items from the " + "cache file '{1}'", cachedIndex.Count, cacheFile)); }