Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbradwilson <dotnetguy@gmail.com>2012-03-23 03:16:25 +0400
committerbradwilson <dotnetguy@gmail.com>2012-03-27 02:39:15 +0400
commitb3638e50c6369c0ccd49ed74d84342b26c95d782 (patch)
tree145b63cc6362f7107a683e7f81bbef0e9afbeefb /src/System.Web.Mvc
parent2f53e34a549fca4024fbe1d91e2d5c6881115b9c (diff)
383115/383116: Faster model binding prefix handling
Diffstat (limited to 'src/System.Web.Mvc')
-rw-r--r--src/System.Web.Mvc/DictionaryValueProvider.cs (renamed from src/System.Web.Mvc/DictionaryValueProvider`1.cs)27
-rw-r--r--src/System.Web.Mvc/NameValueCollectionValueProvider.cs27
-rw-r--r--src/System.Web.Mvc/System.Web.Mvc.csproj5
-rw-r--r--src/System.Web.Mvc/ValueProviderUtil.cs83
4 files changed, 17 insertions, 125 deletions
diff --git a/src/System.Web.Mvc/DictionaryValueProvider`1.cs b/src/System.Web.Mvc/DictionaryValueProvider.cs
index d1abfa94..5a442aa7 100644
--- a/src/System.Web.Mvc/DictionaryValueProvider`1.cs
+++ b/src/System.Web.Mvc/DictionaryValueProvider.cs
@@ -5,7 +5,7 @@ namespace System.Web.Mvc
{
public class DictionaryValueProvider<TValue> : IValueProvider, IEnumerableValueProvider
{
- private readonly HashSet<string> _prefixes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+ private readonly Lazy<PrefixContainer> _prefixContainer;
private readonly Dictionary<string, ValueProviderResult> _values = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase);
public DictionaryValueProvider(IDictionary<string, TValue> dictionary, CultureInfo culture)
@@ -15,34 +15,19 @@ namespace System.Web.Mvc
throw new ArgumentNullException("dictionary");
}
- AddValues(dictionary, culture);
- }
-
- private void AddValues(IDictionary<string, TValue> dictionary, CultureInfo culture)
- {
- if (dictionary.Count > 0)
- {
- _prefixes.Add(String.Empty);
- }
-
- foreach (var entry in dictionary)
+ foreach (KeyValuePair<string, TValue> entry in dictionary)
{
- _prefixes.UnionWith(ValueProviderUtil.GetPrefixes(entry.Key));
-
object rawValue = entry.Value;
string attemptedValue = Convert.ToString(rawValue, culture);
_values[entry.Key] = new ValueProviderResult(rawValue, attemptedValue, culture);
}
+
+ _prefixContainer = new Lazy<PrefixContainer>(() => new PrefixContainer(_values.Keys), isThreadSafe: true);
}
public virtual bool ContainsPrefix(string prefix)
{
- if (prefix == null)
- {
- throw new ArgumentNullException("prefix");
- }
-
- return _prefixes.Contains(prefix);
+ return _prefixContainer.Value.ContainsPrefix(prefix);
}
public virtual ValueProviderResult GetValue(string key)
@@ -59,7 +44,7 @@ namespace System.Web.Mvc
public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix)
{
- return ValueProviderUtil.GetKeysFromPrefix(_prefixes, prefix);
+ return _prefixContainer.Value.GetKeysFromPrefix(prefix);
}
}
}
diff --git a/src/System.Web.Mvc/NameValueCollectionValueProvider.cs b/src/System.Web.Mvc/NameValueCollectionValueProvider.cs
index 0db898e2..f9ea26a9 100644
--- a/src/System.Web.Mvc/NameValueCollectionValueProvider.cs
+++ b/src/System.Web.Mvc/NameValueCollectionValueProvider.cs
@@ -7,11 +7,11 @@ namespace System.Web.Mvc
{
public class NameValueCollectionValueProvider : IValueProvider, IUnvalidatedValueProvider, IEnumerableValueProvider
{
- private readonly HashSet<string> _prefixes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+ private readonly Lazy<PrefixContainer> _prefixContainer;
private readonly Dictionary<string, ValueProviderResultPlaceholder> _values = new Dictionary<string, ValueProviderResultPlaceholder>(StringComparer.OrdinalIgnoreCase);
public NameValueCollectionValueProvider(NameValueCollection collection, CultureInfo culture)
- : this(collection, null /* unvalidatedCollection */, culture)
+ : this(collection, unvalidatedCollection: null, culture: culture)
{
}
@@ -22,40 +22,27 @@ namespace System.Web.Mvc
throw new ArgumentNullException("collection");
}
- AddValues(collection, unvalidatedCollection ?? collection, culture);
- }
+ unvalidatedCollection = unvalidatedCollection ?? collection;
- private void AddValues(NameValueCollection validatedCollection, NameValueCollection unvalidatedCollection, CultureInfo culture)
- {
// Need to read keys from the unvalidated collection, as M.W.I's granular request validation is a bit touchy
// and validated entries at the time the key or value is looked at. For example, GetKey() will throw if the
// value fails request validation, even though the value's not being looked at (M.W.I can't tell the difference).
- if (unvalidatedCollection.Count > 0)
- {
- _prefixes.Add(String.Empty);
- }
+ _prefixContainer = new Lazy<PrefixContainer>(() => new PrefixContainer(unvalidatedCollection.AllKeys), isThreadSafe: true);
foreach (string key in unvalidatedCollection)
{
if (key != null)
{
- _prefixes.UnionWith(ValueProviderUtil.GetPrefixes(key));
-
// need to look up values lazily, as eagerly looking at the collection might trigger validation
- _values[key] = new ValueProviderResultPlaceholder(key, validatedCollection, unvalidatedCollection, culture);
+ _values[key] = new ValueProviderResultPlaceholder(key, collection, unvalidatedCollection, culture);
}
}
}
public virtual bool ContainsPrefix(string prefix)
{
- if (prefix == null)
- {
- throw new ArgumentNullException("prefix");
- }
-
- return _prefixes.Contains(prefix);
+ return _prefixContainer.Value.ContainsPrefix(prefix);
}
public virtual ValueProviderResult GetValue(string key)
@@ -84,7 +71,7 @@ namespace System.Web.Mvc
public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix)
{
- return ValueProviderUtil.GetKeysFromPrefix(_prefixes, prefix);
+ return _prefixContainer.Value.GetKeysFromPrefix(prefix);
}
// Placeholder that can store a validated (in relation to request validation) or unvalidated
diff --git a/src/System.Web.Mvc/System.Web.Mvc.csproj b/src/System.Web.Mvc/System.Web.Mvc.csproj
index eb19b321..7b8cb5c0 100644
--- a/src/System.Web.Mvc/System.Web.Mvc.csproj
+++ b/src/System.Web.Mvc/System.Web.Mvc.csproj
@@ -67,6 +67,9 @@
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
+ <Compile Include="..\Common\PrefixContainer.cs">
+ <Link>Common\PrefixContainer.cs</Link>
+ </Compile>
<Compile Include="..\Common\TaskHelpers.cs">
<Link>Common\TaskHelpers.cs</Link>
</Compile>
@@ -229,7 +232,7 @@
<Compile Include="ValueProviderFactory.cs" />
<Compile Include="ValueProviderFactoryCollection.cs" />
<Compile Include="ValueProviderCollection.cs" />
- <Compile Include="DictionaryValueProvider`1.cs" />
+ <Compile Include="DictionaryValueProvider.cs" />
<Compile Include="NameValueCollectionValueProvider.cs" />
<Compile Include="ValueProviderUtil.cs" />
<Compile Include="IValueProvider.cs" />
diff --git a/src/System.Web.Mvc/ValueProviderUtil.cs b/src/System.Web.Mvc/ValueProviderUtil.cs
index 3a56a3c8..1bc1b738 100644
--- a/src/System.Web.Mvc/ValueProviderUtil.cs
+++ b/src/System.Web.Mvc/ValueProviderUtil.cs
@@ -4,26 +4,6 @@ namespace System.Web.Mvc
{
internal static class ValueProviderUtil
{
- // Given "foo.bar[baz].quux", this method will return:
- // - "foo.bar[baz].quux"
- // - "foo.bar[baz]"
- // - "foo.bar"
- // - "foo"
- public static IEnumerable<string> GetPrefixes(string key)
- {
- yield return key;
- for (int i = key.Length - 1; i >= 0; i--)
- {
- switch (key[i])
- {
- case '.':
- case '[':
- yield return key.Substring(0, i);
- break;
- }
- }
- }
-
public static bool CollectionContainsPrefix(IEnumerable<string> collection, string prefix)
{
foreach (string key in collection)
@@ -56,68 +36,5 @@ namespace System.Web.Mvc
return false; // nothing found
}
-
- // Given "foo.bar", "foo.hello", "something.other", foo[abc].baz and asking for prefix "foo" will return:
- // - "bar"/"foo.bar"
- // - "hello"/"foo.hello"
- // - "abc"/"foo[abc]"
- public static IDictionary<string, string> GetKeysFromPrefix(IEnumerable<string> collection, string prefix)
- {
- IDictionary<string, string> keys = new Dictionary<string, string>();
- foreach (var entry in collection)
- {
- if (entry != null)
- {
- string key = null;
- string fullName = null;
-
- if (entry.Length == prefix.Length)
- {
- // No key in this entry
- continue;
- }
-
- if (entry.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
- {
- int keyPosition = prefix.Length + 1;
- switch (entry[prefix.Length])
- {
- case '.':
- int dotPosition = entry.IndexOf('.', keyPosition);
- if (dotPosition == -1)
- {
- dotPosition = entry.Length;
- }
-
- key = entry.Substring(keyPosition, dotPosition - keyPosition);
- fullName = entry.Substring(0, dotPosition);
- break;
-
- case '[':
- int bracketPosition = entry.IndexOf(']', keyPosition);
- if (bracketPosition == -1)
- {
- // Malformed for dictionary
- continue;
- }
-
- key = entry.Substring(keyPosition, bracketPosition - keyPosition);
- fullName = entry.Substring(0, bracketPosition + 1);
- break;
-
- default:
- continue;
- }
-
- if (!keys.ContainsKey(key))
- {
- keys.Add(key, fullName);
- }
- }
- }
- }
-
- return keys;
- }
}
}