Skip to content

Commit

Permalink
Various fixes (#460)
Browse files Browse the repository at this point in the history
* Use ConcurrentDictionary instead of ThreadStatic Dictionary for improved perf and memory usage
* Fix interlocked usage, they return incremented/decremented value
* change 'compare(a,b) == 0' to 'a == b'
* implement IReadOnlyCollection for LoadResult
  • Loading branch information
Daniel-Svensson authored Nov 13, 2023
1 parent 29b3ecd commit fedc04f
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 42 deletions.
10 changes: 3 additions & 7 deletions src/OpenRiaServices.Client/Framework/DomainContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ private static void ApplyMemberSynchronizations(IEnumerable<ChangeSetEntry> chan
/// <param name="e">The event args</param>
private void EntityContainerPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (string.CompareOrdinal(e.PropertyName, "HasChanges") == 0)
if (e.PropertyName == nameof(HasChanges))
{
// just pass the event on
this.RaisePropertyChanged(nameof(HasChanges));
Expand Down Expand Up @@ -933,9 +933,7 @@ private void IncrementLoadCount()
{
Debug.Assert(this._activeLoadCount >= 0, "Load count should never be less than zero.");

Interlocked.Increment(ref this._activeLoadCount);

if (this._activeLoadCount == 1)
if (Interlocked.Increment(ref this._activeLoadCount) == 1)
{
this.RaisePropertyChanged(nameof(IsLoading));
}
Expand All @@ -945,9 +943,7 @@ private void DecrementLoadCount()
{
Debug.Assert(this._activeLoadCount > 0, "Load count out of sync.");

Interlocked.Decrement(ref this._activeLoadCount);

if (this._activeLoadCount == 0)
if (Interlocked.Decrement(ref this._activeLoadCount) == 0)
{
this.RaisePropertyChanged(nameof(IsLoading));
}
Expand Down
2 changes: 1 addition & 1 deletion src/OpenRiaServices.Client/Framework/EntityContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ internal void AddEntitySet(EntitySet set, EntitySetOperations supportedOperation
/// <param name="propertyName">The property that has changed</param>
internal void SetPropertyChanged(EntitySet entitySet, string propertyName)
{
if (string.CompareOrdinal(propertyName, "HasChanges") == 0)
if (propertyName == nameof(EntitySet.HasChanges))
{
if (entitySet.HasChanges)
{
Expand Down
34 changes: 4 additions & 30 deletions src/OpenRiaServices.Client/Framework/Internal/MetaType.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace OpenRiaServices.Client.Internal
Expand All @@ -24,13 +23,7 @@ namespace OpenRiaServices.Client.Internal
[DebuggerDisplay("Type = {Type.Name}")]
public sealed class MetaType
{
/// <summary>
/// We're using TLS for performance to avoid taking locks. In multithreaded
/// scenarios this means that there may be multiple MetaType caches around
/// but that shouldn't be a problem.
/// </summary>
[ThreadStatic]
private static Dictionary<Type, MetaType> s_metaTypes;
private static readonly ConcurrentDictionary<Type, MetaType> s_metaTypes = new();
private readonly bool _requiresValidation;
private readonly bool _requiresObjectValidation;
private readonly Type[] _childTypes;
Expand All @@ -48,13 +41,7 @@ public static MetaType GetMetaType(Type type)
{
Debug.Assert(!TypeUtility.IsPredefinedType(type), "Should never attempt to create a MetaType for a base type.");

MetaType metaType = null;
if (!MetaTypes.TryGetValue(type, out metaType))
{
metaType = new MetaType(type);
MetaTypes[type] = metaType;
}
return metaType;
return s_metaTypes.GetOrAdd(type, static key => new MetaType(key));
}

private MetaType(Type type)
Expand Down Expand Up @@ -158,8 +145,7 @@ public MetaMember this[string memberName]
{
get
{
MetaMember mm = null;
if (this._metaMembers.TryGetValue(memberName, out mm))
if (this._metaMembers.TryGetValue(memberName, out MetaMember mm))
{
return mm;
}
Expand Down Expand Up @@ -188,18 +174,6 @@ public IEnumerable<EntityActionAttribute> GetEntityActions()
return _customUpdateMethods.Values;
}

private static Dictionary<Type, MetaType> MetaTypes
{
get
{
if (s_metaTypes == null)
{
s_metaTypes = new Dictionary<Type, MetaType>();
}
return s_metaTypes;
}
}

/// <summary>
/// Gets the underlying CLR type for this MetaType
/// </summary>
Expand Down
5 changes: 1 addition & 4 deletions src/OpenRiaServices.Client/Framework/LoadResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;

namespace OpenRiaServices.Client
{
/// <summary>
/// The result of a sucessfully completed load operation
/// </summary>
/// <typeparam name="TEntity">The type of the entity loaded.</typeparam>
public class LoadResult<TEntity> : IEnumerable<TEntity>, ICollection, ILoadResult where TEntity : Entity
public class LoadResult<TEntity> : IReadOnlyCollection<TEntity>, ICollection, ILoadResult where TEntity : Entity
{
private readonly ReadOnlyCollection<TEntity> _loadedEntites;

Expand Down

0 comments on commit fedc04f

Please sign in to comment.