Skip to content

Commit 72ed0e2

Browse files
committed
Performance Optimization by lot
1 parent a057813 commit 72ed0e2

File tree

3 files changed

+38
-41
lines changed

3 files changed

+38
-41
lines changed

src/Comparer/KeyEqualityComparer.cs renamed to src/Comparer/PropertyEqualityComparer.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,39 @@
44
namespace DbSyncKit.Core.Comparer
55
{
66
/// <summary>
7-
/// Compares instances of data contracts based on specified key Properties.
7+
/// Compares instances of data contracts based on specified properties, which can be either key or comparable properties.
88
/// </summary>
99
/// <typeparam name="T">Type of the data contract implementing <see cref="IDataContractComparer"/>.</typeparam>
10-
public class KeyEqualityComparer<T> : IEqualityComparer<T> where T : IDataContractComparer
10+
public class PropertyEqualityComparer<T> : IEqualityComparer<T> where T : IDataContractComparer
1111
{
1212
/// <summary>
13-
/// Gets the array of <see cref="PropertyInfo"/> objects representing key properties used for unique identification of objects.
13+
/// Gets the array of <see cref="PropertyInfo"/> objects representing properties used for equality comparison.
14+
/// These properties can serve as either key or comparable properties.
1415
/// </summary>
15-
public readonly PropertyInfo[] keyProperties;
16+
public readonly PropertyInfo[] properties;
1617

1718
/// <summary>
18-
/// Initializes a new instance of the <see cref="KeyEqualityComparer{T}"/> class.
19+
/// Initializes a new instance of the <see cref="PropertyEqualityComparer{T}"/> class.
1920
/// </summary>
20-
/// <param name="KeyProperties">An array of <see cref="PropertyInfo"/> objects representing key properties used for unique identification of objects.</param>
21-
public KeyEqualityComparer(PropertyInfo[] CompariableProperties, PropertyInfo[] KeyProperties)
21+
/// <param name="Properties">An array of <see cref="PropertyInfo"/> objects representing properties used for equality comparison. These can be either key or comparable properties.</param>
22+
public PropertyEqualityComparer(PropertyInfo[] Properties)
2223
{
23-
//compariableProperties = CompariableProperties;
24-
keyProperties = KeyProperties;
24+
properties = Properties;
2525
}
2626

2727
/// <summary>
28-
/// Determines whether two instances of the data contract are equal based on key properties.
28+
/// Determines whether two instances of the data contract are equal based on the specified properties.
2929
/// </summary>
3030
/// <param name="x">The first instance to compare.</param>
3131
/// <param name="y">The second instance to compare.</param>
3232
/// <returns><c>true</c> if the instances are equal; otherwise, <c>false</c>.</returns>
3333
public bool Equals(T? x, T? y)
3434
{
35-
return keyProperties.All(prop => Equals(prop.GetValue(x), prop.GetValue(y)));
35+
return properties.All(prop => Equals(prop.GetValue(x), prop.GetValue(y)));
3636
}
3737

3838
/// <summary>
39-
/// Returns a hash code for the specified instance of the data contract based on key properties.
39+
/// Returns a hash code for the specified instance of the data contract based on the specified properties.
4040
/// </summary>
4141
/// <param name="obj">The instance for which to get the hash code.</param>
4242
/// <returns>A hash code for the specified instance.</returns>
@@ -46,7 +46,7 @@ public int GetHashCode(T obj)
4646
{
4747
int hash = 17;
4848

49-
foreach (var prop in keyProperties)
49+
foreach (var prop in properties)
5050
{
5151
var value = prop.GetValue(obj);
5252
hash = hash ^ ((value?.GetHashCode() ?? 0) + 23);

src/Helper/DataMetadataComparisonHelper.cs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@ public class DataMetadataComparisonHelper<T> where T : IDataContractComparer
2121
/// </summary>
2222
/// <param name="sourceList">The source set of data contracts.</param>
2323
/// <param name="destinationList">The destination set of data contracts.</param>
24-
/// <param name="keyComparer">An instance of <see cref="KeyEqualityComparer{T}"/> used for key comparison.</param>
24+
/// <param name="keyComparer">An instance of <see cref="PropertyEqualityComparer{T}"/> used for key comparison.</param>
2525
/// <returns>A <see cref="Result{T}"/> object containing added, deleted, and edited data contracts, as well as data counts.</returns>
26-
public static Result<T> GetDifferences(HashSet<T> sourceList, HashSet<T> destinationList, KeyEqualityComparer<T> keyComparer, PropertyInfo[] CompariableProperties)
26+
public static Result<T> GetDifferences(HashSet<T> sourceList, HashSet<T> destinationList, PropertyEqualityComparer<T> keyComparer, PropertyInfo[] CompariableProperties)
2727
{
2828

2929
List<T> added = new List<T>();
3030
List<T> deleted = new List<T>();
3131
ConcurrentBag<(T edit, Dictionary<string, object> updatedProperties)> edited = new ConcurrentBag<(T, Dictionary<string, object>)>();
32+
PropertyEqualityComparer<T> CompariablePropertyComparer = new PropertyEqualityComparer<T>(CompariableProperties);
3233

3334
// Identify added entries
3435
added.AddRange(sourceList.Except(destinationList, keyComparer));
@@ -39,20 +40,20 @@ public static Result<T> GetDifferences(HashSet<T> sourceList, HashSet<T> destina
3940
// Identify edited entries
4041
var sourceKeyDictionary = sourceList
4142
.Except(added)
42-
.ToDictionary(row => GenerateCompositeKey(row, keyComparer.keyProperties), row => row);
43+
.ToDictionary(row => GenerateCompositeKey(row, keyComparer.properties), row => row);
4344

4445
var destinationKeyDictionary = destinationList
4546
.Except(deleted)
46-
.ToDictionary(row => GenerateCompositeKey(row, keyComparer.keyProperties), row => row);
47+
.ToDictionary(row => GenerateCompositeKey(row, keyComparer.properties), row => row);
4748

4849
Parallel.ForEach(sourceKeyDictionary, kvp =>
4950
{
5051
var sourceContract = kvp.Value;
5152

5253
T? destinationContract;
53-
if (destinationKeyDictionary.TryGetValue(GenerateCompositeKey(sourceContract, keyComparer.keyProperties), out destinationContract))
54+
if (destinationKeyDictionary.TryGetValue(GenerateCompositeKey(sourceContract, keyComparer.properties), out destinationContract))
5455
{
55-
var (isEdited, updatedProperties) = GetEdited(sourceContract, destinationContract, CompariableProperties);
56+
var (isEdited, updatedProperties) = GetEdited(sourceContract, destinationContract, CompariablePropertyComparer);
5657

5758
if (isEdited)
5859
{
@@ -77,40 +78,36 @@ public static Result<T> GetDifferences(HashSet<T> sourceList, HashSet<T> destina
7778
#region Private Methods
7879

7980
/// <summary>
80-
/// Compares two entities of type <typeparamref name="T"/> to identify if any properties
81-
/// have been edited during synchronization.
81+
/// Compares two instances of the data contract and identifies the properties that have been edited.
8282
/// </summary>
83-
/// <param name="source">The original entity before synchronization.</param>
84-
/// <param name="destination">The entity in the destination after synchronization.</param>
85-
/// <param name="compariableProperties">The properties to be compared for edits.</param>
83+
/// <param name="source">The source instance to compare.</param>
84+
/// <param name="destination">The destination instance to compare against.</param>
85+
/// <param name="comparablePropertyComparer">The comparer used to determine which properties are comparable.</param>
8686
/// <returns>
87-
/// A tuple where:
88-
/// - <see cref="ValueTuple{T1,T2}.Item1"/> is a boolean indicating if any properties were edited.
89-
/// - <see cref="ValueTuple{T1,T2}.Item2"/> is a dictionary of updated properties for the edited entity.
87+
/// A tuple indicating whether the instances are edited and a dictionary containing the names and values of the updated properties.
88+
/// If the instances are not edited, returns (false, null).
9089
/// </returns>
91-
private static (bool isEdited, Dictionary<string, object>? updatedProperties) GetEdited(T source, T destination, PropertyInfo[] compariableProperties)
90+
private static (bool isEdited, Dictionary<string, object>? updatedProperties) GetEdited(T source, T destination, PropertyEqualityComparer<T> comparablePropertyComparer)
9291
{
93-
if (source.Equals(destination))
92+
if(comparablePropertyComparer.Equals(source,destination))
9493
{
9594
return (false, null);
9695
}
9796

9897
Dictionary<string, object> updatedProperties = new();
99-
bool isEdited = false;
100-
foreach (PropertyInfo prop in compariableProperties)
98+
foreach (PropertyInfo prop in comparablePropertyComparer.properties)
10199
{
102100
object sourceValue = prop.GetValue(source)!;
103101
object destinationValue = prop.GetValue(destination)!;
104102

105103
// Compare values
106-
if (!EqualityComparer<object>.Default.Equals(sourceValue, destinationValue))
104+
if (!System.Collections.Generic.EqualityComparer<object>.Default.Equals(sourceValue, destinationValue))
107105
{
108-
isEdited = true;
109106
updatedProperties[prop.Name] = sourceValue;
110107
}
111108
}
112109

113-
return (isEdited, updatedProperties);
110+
return (true, updatedProperties);
114111
}
115112

116113
/// <summary>

src/Synchronization.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public Result<T> SyncData<T>(IDatabase source, IDatabase destination, Direction
6767
List<string> ColumnList = GetAllColumns<T>().Except(excludedProperty).ToList();
6868
PropertyInfo[] ComparableProperties = GetComparableProperties<T>();
6969
PropertyInfo[] keyProperties = GetKeyProperties<T>();
70-
KeyEqualityComparer<T> keyEqualityComparer = new KeyEqualityComparer<T>(ComparableProperties, keyProperties);
70+
PropertyEqualityComparer<T> keyEqualityComparer = new PropertyEqualityComparer<T>(keyProperties);
7171
HashSet<T> sourceList, destinationList;
7272

7373
#endregion
@@ -89,10 +89,10 @@ public Result<T> SyncData<T>(IDatabase source, IDatabase destination, Direction
8989
/// <param name="destination">The destination database from which to retrieve data.</param>
9090
/// <param name="tableName">The name of the table for which to retrieve data.</param>
9191
/// <param name="ColumnList">The list of columns to retrieve from the table.</param>
92-
/// <param name="keyEqualityComparer">An instance of <see cref="KeyEqualityComparer{T}"/> used for data comparison.</param>
92+
/// <param name="keyEqualityComparer">An instance of <see cref="PropertyEqualityComparer{T}"/> used for data comparison.</param>
9393
/// <param name="sourceList">Output parameter for the retrieved data from the source database.</param>
9494
/// <param name="destinationList">Output parameter for the retrieved data from the destination database.</param>
95-
public void RetrieveDataFromDatabases<T>(IDatabase source, IDatabase destination, string tableName, List<string> ColumnList, KeyEqualityComparer<T> keyEqualityComparer, out HashSet<T> sourceList, out HashSet<T> destinationList) where T : IDataContractComparer
95+
public void RetrieveDataFromDatabases<T>(IDatabase source, IDatabase destination, string tableName, List<string> ColumnList, Comparer.PropertyEqualityComparer<T> keyEqualityComparer, out HashSet<T> sourceList, out HashSet<T> destinationList) where T : IDataContractComparer
9696
{
9797
var sourceQueryGenerationManager = new QueryGenerationManager(QueryGeneratorFactory.GetQueryGenerator(source.Provider));
9898
sourceList = GetDataFromDatabase<T>(tableName, source, sourceQueryGenerationManager, ColumnList, keyEqualityComparer);
@@ -120,9 +120,9 @@ public void RetrieveDataFromDatabases<T>(IDatabase source, IDatabase destination
120120
/// <param name="connection">The database connection from which to retrieve data.</param>
121121
/// <param name="manager">The query generation manager to use for generating the select query.</param>
122122
/// <param name="columns">The list of columns to retrieve from the table.</param>
123-
/// <param name="keyEqualityComparer">An instance of <see cref="KeyEqualityComparer{T}"/> used for data comparison.</param>
123+
/// <param name="keyEqualityComparer">An instance of <see cref="PropertyEqualityComparer{T}"/> used for data comparison.</param>
124124
/// <returns>A <see cref="HashSet{T}"/> containing the retrieved data.</returns>
125-
public HashSet<T> GetDataFromDatabase<T>(string tableName, IDatabase connection, IQueryGenerator manager, List<string> columns, KeyEqualityComparer<T> keyEqualityComparer) where T : IDataContractComparer
125+
public HashSet<T> GetDataFromDatabase<T>(string tableName, IDatabase connection, IQueryGenerator manager, List<string> columns, Comparer.PropertyEqualityComparer<T> keyEqualityComparer) where T : IDataContractComparer
126126
{
127127
var query = manager.GenerateSelectQuery<T>(tableName, columns, string.Empty);
128128

@@ -140,9 +140,9 @@ public HashSet<T> GetDataFromDatabase<T>(string tableName, IDatabase connection,
140140
/// <typeparam name="T">The type of objects being compared. Must implement <see cref="IDataContractComparer"/>.</typeparam>
141141
/// <param name="sourceList">The HashSet containing data from the source.</param>
142142
/// <param name="destinationList">The HashSet containing data from the destination.</param>
143-
/// <param name="keyEqualityComparer">An instance of <see cref="KeyEqualityComparer{T}"/> used for key comparison.</param>
143+
/// <param name="keyEqualityComparer">An instance of <see cref="PropertyEqualityComparer{T}"/> used for key comparison.</param>
144144
/// <returns>A <see cref="Result{T}"/> containing the differences between the source and destination data.</returns>
145-
public Result<T> GetDifferences<T>(HashSet<T> sourceList, HashSet<T> destinationList, KeyEqualityComparer<T> keyEqualityComparer, PropertyInfo[] ComparableProperties) where T : IDataContractComparer
145+
public Result<T> GetDifferences<T>(HashSet<T> sourceList, HashSet<T> destinationList, Comparer.PropertyEqualityComparer<T> keyEqualityComparer, PropertyInfo[] ComparableProperties) where T : IDataContractComparer
146146
{
147147
return DataMetadataComparisonHelper<T>.GetDifferences(sourceList, destinationList, keyEqualityComparer, ComparableProperties);
148148
}

0 commit comments

Comments
 (0)