Skip to content

Commit f0f2a53

Browse files
bahusoidfredericDelaporte
authored andcommitted
Optimize DistinctRootEntityResultTransformer (nhibernate#1999)
1 parent e59d124 commit f0f2a53

File tree

2 files changed

+22
-17
lines changed

2 files changed

+22
-17
lines changed

src/NHibernate/Linq/IntermediateHqlTree.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public void AddDistinctRootOperator()
110110
if (!_hasDistinctRootOperator)
111111
{
112112
Expression<Func<IEnumerable<object>, IList>> x =
113-
l => new DistinctRootEntityResultTransformer().TransformList(l.ToList());
113+
l => DistinctRootEntityResultTransformer.TransformList(l);
114114

115115
_listTransformers.Add(x);
116116
_hasDistinctRootOperator = true;

src/NHibernate/Transform/DistinctRootEntityResultTransformer.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using System.Runtime.CompilerServices;
56

67

@@ -12,24 +13,16 @@ public class DistinctRootEntityResultTransformer : IResultTransformer, ITupleSub
1213
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(DistinctRootEntityResultTransformer));
1314
internal static readonly DistinctRootEntityResultTransformer Instance = new DistinctRootEntityResultTransformer();
1415

15-
internal sealed class Identity
16+
sealed class IdentityComparer<T> : IEqualityComparer<T>
1617
{
17-
internal readonly object entity;
18-
19-
internal Identity(object entity)
20-
{
21-
this.entity = entity;
22-
}
23-
24-
public override bool Equals(object other)
18+
public bool Equals(T x, T y)
2519
{
26-
Identity that = (Identity) other;
27-
return ReferenceEquals(entity, that.entity);
20+
return ReferenceEquals(x, y);
2821
}
2922

30-
public override int GetHashCode()
23+
public int GetHashCode(T obj)
3124
{
32-
return RuntimeHelpers.GetHashCode(entity);
25+
return RuntimeHelpers.GetHashCode(obj);
3326
}
3427
}
3528

@@ -40,13 +33,16 @@ public object TransformTuple(object[] tuple, string[] aliases)
4033

4134
public IList TransformList(IList list)
4235
{
43-
IList result = (IList)Activator.CreateInstance(list.GetType());
44-
var distinct = new HashSet<Identity>();
36+
if (list.Count < 2)
37+
return list;
38+
39+
IList result = (IList) Activator.CreateInstance(list.GetType());
40+
var distinct = new HashSet<object>(new IdentityComparer<object>());
4541

4642
for (int i = 0; i < list.Count; i++)
4743
{
4844
object entity = list[i];
49-
if (distinct.Add(new Identity(entity)))
45+
if (distinct.Add(entity))
5046
{
5147
result.Add(entity);
5248
}
@@ -59,6 +55,15 @@ public IList TransformList(IList list)
5955
return result;
6056
}
6157

58+
internal static List<T> TransformList<T>(IEnumerable<T> list)
59+
{
60+
var result = list.Distinct(new IdentityComparer<T>()).ToList();
61+
if (log.IsDebugEnabled())
62+
{
63+
log.Debug("transformed: {0} rows to: {1} distinct results", list.Count(), result.Count);
64+
}
65+
return result;
66+
}
6267

6368
public bool[] IncludeInTransform(String[] aliases, int tupleLength)
6469
{

0 commit comments

Comments
 (0)