Exemple #1
0
        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));
        }