[Mono-devel-list] [PATCH] Optimization for ConfigurationSettings

eric lindvall eric at 5stops.com
Tue Sep 30 14:43:56 EDT 2003


This is a patch that helps improve the performance of reading the
.config files by only reading the file once per section.

It should really be using the FileSystemWatcher, but it didn't look like
that has been implemented yet.

e.


-------------- next part --------------
Index: class/System/System.Configuration/ConfigurationSettings.cs
===================================================================
RCS file: /mono/mcs/class/System/System.Configuration/ConfigurationSettings.cs,v
retrieving revision 1.21
diff -u -p -u -r1.21 ConfigurationSettings.cs
--- class/System/System.Configuration/ConfigurationSettings.cs	15 Jul 2003 10:08:31 -0000	1.21
+++ class/System/System.Configuration/ConfigurationSettings.cs	30 Sep 2003 18:38:45 -0000
@@ -4,6 +4,7 @@
 // Author:
 //   Christopher Podurgiel (cpodurgiel at msn.com)
 //   Gonzalo Paniagua Javier (gonzalo at ximian.com)
+//   Eric Lindvall (eric at 5stops.com)
 //
 // C) Christopher Podurgiel
 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
@@ -129,6 +130,65 @@ namespace System.Configuration
 		}
 	}
 
+        //
+        // TODO: this should be changed to use the FileSystemWatcher
+        //
+        //  -eric at 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 (_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 +196,8 @@ namespace System.Configuration
 		string fileName;
 		object removedMark = new object ();
 		object groupMark = new object ();
+                object emptyMark = new object ();
+                FileWatcherCache fileCache = null;
 
 		public ConfigurationData () : this (null)
 		{
@@ -170,6 +232,8 @@ namespace System.Configuration
 					reader.Close();
 			}
 
+                        fileCache = new FileWatcherCache (fileName);
+
 			return true;
 		}
 
@@ -242,7 +306,7 @@ namespace System.Configuration
 			return doc;
 		}
 		
-		public object GetConfig (string sectionName)
+		object GetConfigInternal (string sectionName)
 		{
 			object handler = GetHandler (sectionName);
 			if (handler == null)
@@ -265,6 +329,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 = fileCache.Get (sectionName);
+
+                        if (config == emptyMark)
+                                return (null);
+                        else if (config != null)
+                                return (config);
+                        else
+                        {
+                                config = GetConfigInternal (sectionName);
+
+                                if (config == null)
+                                        fileCache.Set (sectionName, emptyMark);
+                                else
+                                        fileCache.Set (sectionName, config);
+
+                                return (config);
+                        }
+                }
 
 		private object LookForFactory (string key)
 		{


More information about the Mono-devel-list mailing list