Skip to content

Commit

Permalink
Merge remote branch 'remotes/abo/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
lanwin committed Jul 6, 2010
2 parents 9ad8a6f + e3863d1 commit 69e7c91
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 32 deletions.
3 changes: 0 additions & 3 deletions source/MongoDB/Configuration/Mapping/Model/ClassMapBase.cs
Expand Up @@ -275,9 +275,6 @@ private static bool AreObjectsEqual(object a, object b)
return true;
}

if(a is IEnumerable && b is IEnumerable)
return false;

return a.Equals(b);
}
}
Expand Down
101 changes: 73 additions & 28 deletions source/MongoDB/Configuration/Mapping/Util/MemberReflectionOptimizer.cs
Expand Up @@ -13,6 +13,7 @@ public static class MemberReflectionOptimizer
{
private static readonly Dictionary<string, Func<object, object>> GetterCache = new Dictionary<string, Func<object, object>>();
private static readonly Dictionary<string, Action<object, object>> SetterCache = new Dictionary<string, Action<object, object>>();
private static readonly object SyncObject = new object();

/// <summary>
/// Gets the getter.
Expand Down Expand Up @@ -46,20 +47,32 @@ public static class MemberReflectionOptimizer
throw new ArgumentNullException("fieldInfo");

var key = CreateKey(fieldInfo);
if(GetterCache.ContainsKey(key))
return GetterCache[key];

var instanceParameter = Expression.Parameter(typeof(object), "target");
Func<object, object> getter;
lock (SyncObject)
{
if (GetterCache.TryGetValue(key, out getter))
return getter;
}
//We release the lock here, so the relatively time consuming compiling
//does not imply contention. The price to pay is potential multiple compilations
//of the same expression...
var instanceParameter = Expression.Parameter(typeof (object), "target");

var member = Expression.Field(Expression.Convert(instanceParameter, fieldInfo.DeclaringType), fieldInfo);

var lambda = Expression.Lambda<Func<object, object>>(
Expression.Convert(member, typeof(object)),
Expression.Convert(member, typeof (object)),
instanceParameter);

var result = lambda.Compile();
GetterCache[key] = result;
return result;
getter = lambda.Compile();

lock(SyncObject)
{
GetterCache[key] = getter;
}

return getter;
}

/// <summary>
Expand All @@ -73,8 +86,14 @@ public static class MemberReflectionOptimizer
throw new ArgumentNullException("propertyInfo");

var key = CreateKey(propertyInfo);
if(GetterCache.ContainsKey(key))
return GetterCache[key];

Func<object, object> getter;

lock (SyncObject)
{
if (GetterCache.TryGetValue(key, out getter))
return getter;
}

if(!propertyInfo.CanRead)
throw new InvalidOperationException("Cannot create a getter for a writeonly property.");
Expand All @@ -87,9 +106,13 @@ public static class MemberReflectionOptimizer
Expression.Convert(member, typeof(object)),
instanceParameter);

var result = lambda.Compile();
GetterCache[key] = result;
return result;
getter = lambda.Compile();

lock (SyncObject)
{
GetterCache[key] = getter;
}
return getter;
}

/// <summary>
Expand Down Expand Up @@ -124,14 +147,20 @@ public static class MemberReflectionOptimizer
throw new ArgumentNullException("fieldInfo");

var key = CreateKey(fieldInfo);
if(SetterCache.ContainsKey(key))
return SetterCache[key];

if(fieldInfo.IsInitOnly || fieldInfo.IsLiteral)
throw new InvalidOperationException("Cannot create a setter for a readonly field.");
Action<object, object> setter;

lock (SyncObject)
{
if (SetterCache.TryGetValue(key, out setter))
return setter;
}

if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral)
throw new InvalidOperationException("Cannot create a setter for a readonly field.");

var sourceType = fieldInfo.DeclaringType;
var method = new DynamicMethod("Set" + fieldInfo.Name, null, new[] {typeof(object), typeof(object)}, true);
var method = new DynamicMethod("Set" + fieldInfo.Name, null, new[] {typeof (object), typeof (object)}, true);
var gen = method.GetILGenerator();

gen.Emit(OpCodes.Ldarg_0);
Expand All @@ -141,9 +170,14 @@ public static class MemberReflectionOptimizer
gen.Emit(OpCodes.Stfld, fieldInfo);
gen.Emit(OpCodes.Ret);

var result = (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>));
SetterCache[key] = result;
return result;
setter = (Action<object, object>) method.CreateDelegate(typeof (Action<object, object>));

lock (SyncObject)
{
SetterCache[key] = setter;
}

return setter;
}

/// <summary>
Expand All @@ -157,14 +191,20 @@ public static class MemberReflectionOptimizer
throw new ArgumentNullException("propertyInfo");

var key = CreateKey(propertyInfo);
if(SetterCache.ContainsKey(key))
return SetterCache[key];

if(!propertyInfo.CanWrite)
Action<object, object> setter;

lock (SyncObject)
{
if (SetterCache.TryGetValue(key, out setter))
return setter;
}

if (!propertyInfo.CanWrite)
throw new InvalidOperationException("Cannot create a setter for a readonly property.");

var instanceParameter = Expression.Parameter(typeof(object), "target");
var valueParameter = Expression.Parameter(typeof(object), "value");
var instanceParameter = Expression.Parameter(typeof (object), "target");
var valueParameter = Expression.Parameter(typeof (object), "value");

var lambda = Expression.Lambda<Action<object, object>>(
Expression.Call(
Expand All @@ -174,9 +214,14 @@ public static class MemberReflectionOptimizer
instanceParameter,
valueParameter);

var result = lambda.Compile();
SetterCache[key] = result;
return result;
setter = lambda.Compile();

lock (SyncObject)
{
SetterCache[key] = setter;
}

return setter;
}

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions source/MongoDB/Exceptions/IdGenerationException.cs
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;

namespace MongoDB
{
Expand All @@ -13,5 +14,20 @@ public class IdGenerationException : MongoException
/// </summary>
/// <param name="message">The message.</param>
public IdGenerationException(string message) : base(message) { }

/// <summary>
/// Initializes a new instance of the <see cref="IdGenerationException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is null.
/// </exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">
/// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
/// </exception>
public IdGenerationException(SerializationInfo info, StreamingContext context) : base(info,context)
{
}
}
}
16 changes: 16 additions & 0 deletions source/MongoDB/Exceptions/MongoCommandException.cs
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;

namespace MongoDB
{
Expand Down Expand Up @@ -35,6 +36,21 @@ public MongoCommandException(string message, Document error, Document command, E
Command = command;
}

/// <summary>
/// Initializes a new instance of the <see cref="MongoCommandException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is null.
/// </exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">
/// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
/// </exception>
public MongoCommandException(SerializationInfo info, StreamingContext context) : base(info,context)
{
}

/// <summary>
/// Gets or sets the error.
/// </summary>
Expand Down
19 changes: 18 additions & 1 deletion source/MongoDB/Exceptions/MongoConnectionException.cs
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;
using MongoDB.Connections;

namespace MongoDB
Expand Down Expand Up @@ -65,6 +66,22 @@ internal MongoConnectionException(string message, Connection connection, Excepti
throw new ArgumentNullException("connection");
ConnectionString = connection.ConnectionString;
EndPoint = connection.EndPoint;
}
}

/// <summary>
/// Initializes a new instance of the <see cref="MongoConnectionException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is null.
/// </exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">
/// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
/// </exception>
public MongoConnectionException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}
17 changes: 17 additions & 0 deletions source/MongoDB/Exceptions/MongoDuplicateKeyException.cs
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;

namespace MongoDB
{
Expand All @@ -22,5 +23,21 @@ public class MongoDuplicateKeyException : MongoOperationException
/// <param name="error">The error.</param>
/// <param name="e">The e.</param>
public MongoDuplicateKeyException(string message, Document error, Exception e):base(message, error,e){}

/// <summary>
/// Initializes a new instance of the <see cref="MongoDuplicateKeyException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is null.
/// </exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">
/// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
/// </exception>
public MongoDuplicateKeyException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}
17 changes: 17 additions & 0 deletions source/MongoDB/Exceptions/MongoDuplicateKeyUpdateException.cs
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;

namespace MongoDB
{
Expand Down Expand Up @@ -26,5 +27,21 @@ public MongoDuplicateKeyUpdateException(string message, Document error)
/// <param name="error">The error.</param>
/// <param name="e">The e.</param>
public MongoDuplicateKeyUpdateException(string message, Document error, Exception e):base(message, error,e){}

/// <summary>
/// Initializes a new instance of the <see cref="MongoDuplicateKeyUpdateException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is null.
/// </exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">
/// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
/// </exception>
public MongoDuplicateKeyUpdateException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}
16 changes: 16 additions & 0 deletions source/MongoDB/Exceptions/MongoException.cs
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;

namespace MongoDB
{
Expand All @@ -20,5 +21,20 @@ public class MongoException : Exception
/// </summary>
/// <param name="message">The message.</param>
public MongoException(string message):base(message){}

/// <summary>
/// Initializes a new instance of the <see cref="MongoException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is null.
/// </exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">
/// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
/// </exception>
public MongoException(SerializationInfo info, StreamingContext context) : base(info,context)
{
}
}
}
17 changes: 17 additions & 0 deletions source/MongoDB/Exceptions/MongoMapReduceException.cs
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;
using MongoDB.Results;

namespace MongoDB
Expand All @@ -23,5 +24,21 @@ public MongoMapReduceException(MongoCommandException exception)
:base(exception.Message,exception.Error, exception.Command) {
MapReduceResult = new MapReduceResult(exception.Error);
}

/// <summary>
/// Initializes a new instance of the <see cref="MongoMapReduceException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is null.
/// </exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">
/// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
/// </exception>
public MongoMapReduceException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

0 comments on commit 69e7c91

Please sign in to comment.