55// Created: 2010.01.21
66
77using System ;
8- using System . Linq ;
98using System . Linq . Expressions ;
10- using Xtensive . Collections ;
119using Xtensive . Core ;
1210
1311namespace Xtensive . Orm . Linq
1412{
1513 internal sealed class TranslatorState
1614 {
15+ [ Flags ]
16+ private enum TranslatorStateFlags
17+ {
18+ JoinLocalCollectionEntity = 1 ,
19+ AllowCalculableColumnCombine = 1 << 1 ,
20+ IsBuildingProjection = 1 << 2 ,
21+ CalculateExpressions = 1 << 3 ,
22+ IsGroupingKey = 1 << 4 ,
23+ IsTailMethod = 1 << 5 ,
24+ ShouldOmitConvertToObject = 1 << 6 ,
25+ RequestCalculateExpressions = 1 << 7 ,
26+ RequestCalculateExpressionsOnce = 1 << 8
27+ }
28+
29+ internal readonly ref struct TranslatorScope
30+ {
31+ private readonly TranslatorState previousState ;
32+ private readonly Translator translator ;
33+
34+ public void Dispose ( ) => translator . state = previousState ;
35+
36+ public TranslatorScope ( Translator translator , TranslatorState previousState )
37+ {
38+ this . translator = translator ;
39+ this . previousState = previousState ;
40+ }
41+ }
42+
1743 private readonly Translator translator ;
1844
45+ private TranslatorStateFlags flags ;
46+
1947 public ParameterExpression [ ] Parameters { get ; set ; }
2048
2149 public ParameterExpression [ ] OuterParameters { get ; set ; }
@@ -26,43 +54,96 @@ internal sealed class TranslatorState
2654
2755 public Type TypeOfEntityStoredInKey { get ; set ; }
2856
29- public bool JoinLocalCollectionEntity { get ; set ; }
57+ public bool JoinLocalCollectionEntity
58+ {
59+ get => ( flags & TranslatorStateFlags . JoinLocalCollectionEntity ) != 0 ;
60+ set => flags = value
61+ ? flags | TranslatorStateFlags . JoinLocalCollectionEntity
62+ : flags & ~ TranslatorStateFlags . JoinLocalCollectionEntity ;
63+ }
3064
31- public bool AllowCalculableColumnCombine { get ; set ; }
65+ public bool AllowCalculableColumnCombine {
66+ get => ( flags & TranslatorStateFlags . AllowCalculableColumnCombine ) != 0 ;
67+ set => flags = value
68+ ? flags | TranslatorStateFlags . AllowCalculableColumnCombine
69+ : flags & ~ TranslatorStateFlags . AllowCalculableColumnCombine ;
70+ }
3271
33- public bool BuildingProjection { get ; set ; }
72+ public bool BuildingProjection
73+ {
74+ get => ( flags & TranslatorStateFlags . IsBuildingProjection ) != 0 ;
75+ set => flags = value
76+ ? flags | TranslatorStateFlags . IsBuildingProjection
77+ : flags & ~ TranslatorStateFlags . IsBuildingProjection ;
78+ }
3479
35- public bool CalculateExpressions { get ; set ; }
80+ public bool CalculateExpressions
81+ {
82+ get => ( flags & TranslatorStateFlags . CalculateExpressions ) != 0 ;
83+ set => flags = value
84+ ? flags | TranslatorStateFlags . CalculateExpressions
85+ : flags & ~ TranslatorStateFlags . CalculateExpressions ;
86+ }
3687
37- public bool GroupingKey { get ; set ; }
88+ public bool GroupingKey
89+ {
90+ get => ( flags & TranslatorStateFlags . IsGroupingKey ) != 0 ;
91+ set => flags = value
92+ ? flags | TranslatorStateFlags . IsGroupingKey
93+ : flags & ~ TranslatorStateFlags . IsGroupingKey ;
94+ }
3895
39- public bool IsTailMethod { get ; set ; }
96+ public bool IsTailMethod
97+ {
98+ get => ( flags & TranslatorStateFlags . IsTailMethod ) != 0 ;
99+ set => flags = value
100+ ? flags | TranslatorStateFlags . IsTailMethod
101+ : flags & ~ TranslatorStateFlags . IsTailMethod ;
102+ }
40103
41- public bool ShouldOmmitConvertToObject { get ; set ; }
104+ public bool ShouldOmitConvertToObject
105+ {
106+ get => ( flags & TranslatorStateFlags . ShouldOmitConvertToObject ) != 0 ;
107+ set => flags = value
108+ ? flags | TranslatorStateFlags . ShouldOmitConvertToObject
109+ : flags & ~ TranslatorStateFlags . ShouldOmitConvertToObject ;
110+ }
42111
43- public bool RequestCalculateExpressions { get ; set ; }
112+ public bool RequestCalculateExpressions
113+ {
114+ get => ( flags & TranslatorStateFlags . RequestCalculateExpressions ) != 0 ;
115+ set => flags = value
116+ ? flags | TranslatorStateFlags . RequestCalculateExpressions
117+ : flags & ~ TranslatorStateFlags . RequestCalculateExpressions ;
118+ }
44119
45- public bool RequestCalculateExpressionsOnce { get ; set ; }
120+ public bool RequestCalculateExpressionsOnce
121+ {
122+ get => ( flags & TranslatorStateFlags . RequestCalculateExpressionsOnce ) != 0 ;
123+ set => flags = value
124+ ? flags | TranslatorStateFlags . RequestCalculateExpressionsOnce
125+ : flags & ~ TranslatorStateFlags . RequestCalculateExpressionsOnce ;
126+ }
46127
47- public IDisposable CreateScope ( )
128+ public TranslatorScope CreateScope ( )
48129 {
49130 var currentState = translator . state ;
50- var newState = new TranslatorState ( currentState ) ;
51- translator . state = newState ;
52- return new Disposable ( _ => translator . state = currentState ) ;
131+ translator . state = new TranslatorState ( currentState ) ;
132+ return new TranslatorScope ( translator , currentState ) ;
53133 }
54134
55- public IDisposable CreateLambdaScope ( LambdaExpression le )
135+ public TranslatorScope CreateLambdaScope ( LambdaExpression le )
56136 {
57137 var currentState = translator . state ;
58138 var newState = new TranslatorState ( currentState ) ;
59- newState . OuterParameters = newState . OuterParameters . Concat ( newState . Parameters ) . ToArray ( ) ;
60- newState . Parameters = Enumerable . ToArray ( le . Parameters ) ;
139+ var newOuterParameters = new ParameterExpression [ newState . OuterParameters . Length + newState . Parameters . Length ] ;
140+ newState . OuterParameters . CopyTo ( newOuterParameters , 0 ) ;
141+ newState . Parameters . CopyTo ( newOuterParameters , newState . OuterParameters . Length ) ;
142+ newState . OuterParameters = newOuterParameters ;
143+ newState . Parameters = le . Parameters . ToArray ( le . Parameters . Count ) ;
61144 newState . CurrentLambda = le ;
62- newState . IncludeAlgorithm = IncludeAlgorithm ;
63- newState . IsTailMethod = IsTailMethod ;
64145 translator . state = newState ;
65- return new Disposable ( _ => translator . state = currentState ) ;
146+ return new TranslatorScope ( translator , currentState ) ;
66147 }
67148
68149
@@ -71,30 +152,21 @@ public IDisposable CreateLambdaScope(LambdaExpression le)
71152 public TranslatorState ( Translator translator )
72153 {
73154 this . translator = translator ;
155+ flags = TranslatorStateFlags . IsBuildingProjection | TranslatorStateFlags . IsTailMethod ;
156+ OuterParameters = Parameters = Array . Empty < ParameterExpression > ( ) ;
74157 IncludeAlgorithm = IncludeAlgorithm . Auto ;
75- BuildingProjection = true ;
76- IsTailMethod = true ;
77158 TypeOfEntityStoredInKey = null ;
78- OuterParameters = Parameters = ArrayUtils < ParameterExpression > . EmptyArray ;
79159 }
80160
81161 private TranslatorState ( TranslatorState currentState )
82162 {
83163 translator = currentState . translator ;
164+ flags = currentState . flags ;
84165 Parameters = currentState . Parameters ;
85166 OuterParameters = currentState . OuterParameters ;
86- CalculateExpressions = currentState . CalculateExpressions ;
87- BuildingProjection = currentState . BuildingProjection ;
88167 CurrentLambda = currentState . CurrentLambda ;
89- JoinLocalCollectionEntity = currentState . JoinLocalCollectionEntity ;
90- AllowCalculableColumnCombine = currentState . AllowCalculableColumnCombine ;
91168 IncludeAlgorithm = currentState . IncludeAlgorithm ;
92- IsTailMethod = currentState . IsTailMethod ;
93- GroupingKey = currentState . GroupingKey ;
94- RequestCalculateExpressionsOnce = currentState . RequestCalculateExpressionsOnce ;
95- RequestCalculateExpressions = currentState . RequestCalculateExpressions ;
96169 TypeOfEntityStoredInKey = currentState . TypeOfEntityStoredInKey ;
97- ShouldOmmitConvertToObject = currentState . ShouldOmmitConvertToObject ;
98170 }
99171 }
100172}
0 commit comments