2003-10-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Fri, 3 Oct 2003 02:46:07 +0000 (02:46 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Fri, 3 Oct 2003 02:46:07 +0000 (02:46 -0000)
* ConfigurationSettings.cs: patch by Eric Lindvall (eric@5stops.com)
that improves performance by not reading the file more than once.

svn path=/trunk/mcs/; revision=18534

mcs/class/System/System.Configuration/ChangeLog
mcs/class/System/System.Configuration/ConfigurationSettings.cs

index 6b1a3e7ca52d1e7c782b47417ff4ac419e1b42fd..fa443ff62ecb07d95515f11de5a77259552a8238 100644 (file)
@@ -1,3 +1,8 @@
+2003-10-03  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * ConfigurationSettings.cs: patch by Eric Lindvall (eric@5stops.com)
+       that improves performance by not reading the file more than once.
+
 2003-07-15  Andreas Nahr <ClassDevelopment@A-SoftTech.com>
 
        * ConfigurationSettings.cs: Removed unused exception variable, fixes
index 254196bb53ffb4920d17718f2fdc622140634ed7..9f2e2de656d435ba431e7fd5381fb092b2dde8cd 100644 (file)
@@ -4,6 +4,7 @@
 // Author:
 //   Christopher Podurgiel (cpodurgiel@msn.com)
 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//   Eric Lindvall (eric@5stops.com)
 //
 // C) Christopher Podurgiel
 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
@@ -129,6 +130,68 @@ namespace System.Configuration
                }
        }
 
+        //
+        // TODO: this should be changed to use the FileSystemWatcher
+        //
+        //  -eric@5stops.com 9.20.2003
+        //
+        class FileWatcherCache
+        {
+                Hashtable _cacheTable;
+                FileInfo _lastInfo;
+                string _filename;
+
+                public FileWatcherCache (string filename)
+                {
+                        _cacheTable = Hashtable.Synchronized (new Hashtable());
+                        _lastInfo = new FileInfo (filename);
+                        _filename = filename;
+                }
+
+                private bool HasFileChanged()
+                {
+                        FileInfo currentInfo = new FileInfo (_filename);
+
+                        if (currentInfo.Exists == false)
+                                return (true);
+
+                        if (_lastInfo.LastWriteTime != currentInfo.LastWriteTime)
+                                return (true);
+
+                        if (_lastInfo.CreationTime != currentInfo.CreationTime)
+                                return (true);
+
+                        if (_lastInfo.Length != currentInfo.Length)
+                                return (true);
+
+                        return (false);
+                }
+
+                private void CheckFileChange()
+                {
+                        if (HasFileChanged() == true)
+                        {
+                                _lastInfo = new FileInfo (_filename);
+
+                                _cacheTable.Clear();
+                        }
+                }
+
+                public void Set (string key, object value)
+                {
+                        CheckFileChange();
+
+                        _cacheTable[key] = value;
+                }
+
+                public object Get (string key)
+                {
+                        CheckFileChange();
+
+                        return (_cacheTable[key]);
+                }
+        }
+
        class ConfigurationData
        {
                ConfigurationData parent;
@@ -136,6 +199,28 @@ namespace System.Configuration
                string fileName;
                object removedMark = new object ();
                object groupMark = new object ();
+                object emptyMark = new object ();
+                FileWatcherCache fileCache = null;
+
+                private FileWatcherCache FileCache
+                {
+                        get
+                        {
+                                if (fileCache == null)
+                                {
+                                        if (fileName != null)
+                                        {
+                                                fileCache = new FileWatcherCache (fileName);
+                                        }
+                                        else
+                                        {
+                                                fileCache = parent.FileCache;
+                                        }
+                                }
+
+                                return (fileCache);
+                        }
+                }
 
                public ConfigurationData () : this (null)
                {
@@ -242,7 +327,7 @@ namespace System.Configuration
                        return doc;
                }
                
-               public object GetConfig (string sectionName)
+               object GetConfigInternal (string sectionName)
                {
                        object handler = GetHandler (sectionName);
                        if (handler == null)
@@ -266,6 +351,30 @@ namespace System.Configuration
                        return ((IConfigurationSectionHandler) handler).Create (parentConfig, null, doc.DocumentElement);
                }
 
+               public object GetConfig (string sectionName)
+               {
+                        object config;
+
+                        // check to see if the handler is in the cache
+                        config = this.FileCache.Get (sectionName);
+
+                        if (config == emptyMark)
+                                return (null);
+                        else if (config != null)
+                                return (config);
+                        else
+                        {
+                                config = GetConfigInternal (sectionName);
+
+                                if (config == null)
+                                        this.FileCache.Set (sectionName, emptyMark);
+                                else
+                                        this.FileCache.Set (sectionName, config);
+
+                                return (config);
+                        }
+                }
+
                private object LookForFactory (string key)
                {
                        object o = factories [key];