.\" Copyright 2003 Ximian, Inc.
.\" Copyright 2004-2011 Novell, Inc.
.\" Copyright 2011-2012 Xamarin Inc
+.\" Copyright 2013 7digital Media Ltd.
.\" Author:
.\" Miguel de Icaza (miguel@gnu.org)
.\"
-.TH Mono "Mono 2.11"
+.TH Mono "Mono 3.0"
.SH NAME
mono \- Mono's ECMA-CLI native code generator (Just-in-Time and Ahead-of-Time)
.SH SYNOPSIS
variable in your environment before starting the application and no action will
be taken.
.TP
+\fBMONO_ASPNET_WEBCONFIG_CACHESIZE\fR
+Mono has a cache of ConfigSection objects for speeding up WebConfigurationManager
+queries. Its default size is 100 items, and when more items are needed, cache
+evictions start happening. If evictions are too frequent this could impose
+unnecessary overhead, which could be avoided by using this environment variable
+to set up a higher cache size (or to lower memory requirements by decreasing it).
+.TP
\fBMONO_CFG_DIR\fR
If set, this variable overrides the default system configuration directory
($PREFIX/etc). It's used to locate machine.config file.
--- /dev/null
+//
+// A simple LRU cache
+//
+// Authors:
+// Miguel de Icaza (miguel@gnome.org)
+// Andres G. Aragoneses (andres@7digital.com)
+//
+// Copyright 2010 Miguel de Icaza
+// Copyright 2013 7digital Media Ltd.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+
+namespace System.Web.Configuration {
+
+ class LruCache<TKey, TValue> {
+ Dictionary<TKey, LinkedListNode <TValue>> dict;
+ Dictionary<LinkedListNode<TValue>, TKey> revdict;
+ LinkedList<TValue> list;
+ int entry_limit;
+
+ bool eviction_warning_shown;
+ int evictions;
+ bool size_overriden;
+
+ internal string EvictionWarning { set; private get; }
+
+ public LruCache (int entryLimit)
+ {
+ entry_limit = entryLimit;
+ dict = new Dictionary<TKey, LinkedListNode<TValue>> ();
+ revdict = new Dictionary<LinkedListNode<TValue>, TKey> ();
+ list = new LinkedList<TValue> ();
+ }
+
+ //for debugging: public int Count { get { return dict.Count; } }
+
+ void Evict ()
+ {
+ var last = list.Last;
+ if (last == null)
+ return;
+
+ var key = revdict [last];
+
+ dict.Remove (key);
+ revdict.Remove (last);
+ list.RemoveLast ();
+ DisposeValue (last.Value);
+ evictions++;
+
+ if (!String.IsNullOrEmpty (EvictionWarning) && !eviction_warning_shown && (evictions >= entry_limit)) {
+ Console.Error.WriteLine ("WARNING: " + EvictionWarning);
+ eviction_warning_shown = true;
+ }
+ }
+
+ public void Clear ()
+ {
+ foreach (var element in list) {
+ DisposeValue (element);
+ }
+
+ dict.Clear ();
+ revdict.Clear ();
+ list.Clear ();
+ eviction_warning_shown = false;
+ evictions = 0;
+ }
+
+ void DisposeValue (TValue value)
+ {
+ if (value is IDisposable) {
+ ((IDisposable)value).Dispose ();
+ }
+ }
+
+ public bool TryGetValue (TKey key, out TValue value)
+ {
+ LinkedListNode<TValue> node;
+
+ if (dict.TryGetValue (key, out node)){
+ list.Remove (node);
+ list.AddFirst (node);
+
+ value = node.Value;
+ return true;
+ }
+ value = default (TValue);
+ return false;
+ }
+
+ public void Add (TKey key, TValue value)
+ {
+ LinkedListNode<TValue> node;
+
+ if (dict.TryGetValue (key, out node)){
+
+ // If we already have a key, move it to the front
+ list.Remove (node);
+ list.AddFirst (node);
+
+ // Remove the old value
+ DisposeValue (node.Value);
+
+ node.Value = value;
+ return;
+ }
+
+ if (dict.Count >= entry_limit)
+ Evict ();
+
+ // Adding new node
+ node = new LinkedListNode<TValue> (value);
+ list.AddFirst (node);
+ dict [key] = node;
+ revdict [node] = key;
+ }
+
+ public override string ToString ()
+ {
+ return "LRUCache dict={0} revdict={1} list={2}";
+ }
+ }
+}
// See comment for the cacheLock field at top of System.Web.Caching/Cache.cs
static readonly ReaderWriterLockSlim sectionCacheLock;
-
+
#if !TARGET_J2EE
static IInternalConfigConfigurationFactory configFactory;
static Hashtable configurations = Hashtable.Synchronized (new Hashtable ());
- static Dictionary <int, object> sectionCache = new Dictionary <int, object> ();
static Hashtable configPaths = Hashtable.Synchronized (new Hashtable ());
static bool suppressAppReload;
#else
}
}
}
+
+ const int DEFAULT_SECTION_CACHE_SIZE = 100;
+ const string CACHE_SIZE_OVERRIDING_KEY = "MONO_ASPNET_WEBCONFIG_CACHESIZE";
+ static LruCache<int, object> sectionCache;
static WebConfigurationManager ()
{
+ var section_cache_size = DEFAULT_SECTION_CACHE_SIZE;
+ int section_cache_size_override;
+ bool size_overriden = false;
+ if (int.TryParse (Environment.GetEnvironmentVariable (CACHE_SIZE_OVERRIDING_KEY), out section_cache_size_override)) {
+ section_cache_size = section_cache_size_override;
+ size_overriden = true;
+ Console.WriteLine ("WebConfigurationManager's LRUcache Size overriden to: {0} (via {1})", section_cache_size_override, CACHE_SIZE_OVERRIDING_KEY);
+ }
+ sectionCache = new LruCache<int, object> (section_cache_size);
+ string eviction_warning = "WebConfigurationManager's LRUcache evictions count reached its max size";
+ if (!size_overriden)
+ eviction_warning += String.Format ("{0}Cache Size: {1} (overridable via {2})",
+ Environment.NewLine, section_cache_size, CACHE_SIZE_OVERRIDING_KEY);
+ sectionCache.EvictionWarning = eviction_warning;
+
configFactory = ConfigurationManager.ConfigurationFactory;
_Configuration.SaveStart += ConfigurationSaveHandler;
_Configuration.SaveEnd += ConfigurationSaveHandler;