~ubuntu-branches/ubuntu/trusty/smuxi/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/SODAMethodBuilder.cs

  • Committer: Package Import Robot
  • Author(s): Mirco Bauer
  • Date: 2013-05-25 22:11:31 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20130525221131-nd2mc0kzubuwyx20
Tags: 0.8.11-1
* [22d13d5] Imported Upstream version 0.8.11
* [6d2b95a] Refreshed patches
* [89eb66e] Added ServiceStack libraries to smuxi-engine package
* [848ab10] Enable Campfire engine
* [c6dbdc7] Always build db4o for predictable build result
* [13ec489] Exclude OS X specific libraries from dh_clideps

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
2
 
 
3
 
using System;
4
 
using System.Collections;
5
 
using Db4objects.Db4o.Foundation;
6
 
using Db4objects.Db4o.Instrumentation.Api;
7
 
using Db4objects.Db4o.Internal.Query;
8
 
using Db4objects.Db4o.NativeQueries.Expr;
9
 
using Db4objects.Db4o.NativeQueries.Expr.Cmp;
10
 
using Db4objects.Db4o.NativeQueries.Expr.Cmp.Operand;
11
 
using Db4objects.Db4o.NativeQueries.Instrumentation;
12
 
using Db4objects.Db4o.NativeQueries.Optimization;
13
 
using Db4objects.Db4o.Query;
14
 
 
15
 
namespace Db4objects.Db4o.NativeQueries.Instrumentation
16
 
{
17
 
        public class SODAMethodBuilder
18
 
        {
19
 
                private const bool LogBytecode = false;
20
 
 
21
 
                private IMethodRef descendRef;
22
 
 
23
 
                private IMethodRef constrainRef;
24
 
 
25
 
                private IMethodRef greaterRef;
26
 
 
27
 
                private IMethodRef smallerRef;
28
 
 
29
 
                private IMethodRef containsRef;
30
 
 
31
 
                private IMethodRef startsWithRef;
32
 
 
33
 
                private IMethodRef endsWithRef;
34
 
 
35
 
                private IMethodRef notRef;
36
 
 
37
 
                private IMethodRef andRef;
38
 
 
39
 
                private IMethodRef orRef;
40
 
 
41
 
                private IMethodRef identityRef;
42
 
 
43
 
                private readonly ITypeEditor _editor;
44
 
 
45
 
                private IMethodBuilder _builder;
46
 
 
47
 
                public static readonly string OptimizeQueryMethodName = "optimizeQuery";
48
 
 
49
 
                private class SODAExpressionBuilder : IExpressionVisitor
50
 
                {
51
 
                        private ITypeRef predicateClass;
52
 
 
53
 
                        public SODAExpressionBuilder(SODAMethodBuilder _enclosing, ITypeRef predicateClass
54
 
                                )
55
 
                        {
56
 
                                this._enclosing = _enclosing;
57
 
                                this.predicateClass = predicateClass;
58
 
                        }
59
 
 
60
 
                        public virtual void Visit(AndExpression expression)
61
 
                        {
62
 
                                expression.Left().Accept(this);
63
 
                                expression.Right().Accept(this);
64
 
                                this._enclosing.Invoke(this._enclosing.andRef);
65
 
                        }
66
 
 
67
 
                        public virtual void Visit(BoolConstExpression expression)
68
 
                        {
69
 
                                this.LoadQuery();
70
 
                        }
71
 
 
72
 
                        //throw new RuntimeException("No boolean constants expected in parsed expression tree");
73
 
                        private void LoadQuery()
74
 
                        {
75
 
                                this._enclosing.LoadArgument(1);
76
 
                        }
77
 
 
78
 
                        public virtual void Visit(OrExpression expression)
79
 
                        {
80
 
                                expression.Left().Accept(this);
81
 
                                expression.Right().Accept(this);
82
 
                                this._enclosing.Invoke(this._enclosing.orRef);
83
 
                        }
84
 
 
85
 
                        public virtual void Visit(ComparisonExpression expression)
86
 
                        {
87
 
                                this.LoadQuery();
88
 
                                this.Descend(this.FieldNames(expression.Left()));
89
 
                                expression.Right().Accept(this.ComparisonEmitter());
90
 
                                this.Constrain(expression.Op());
91
 
                        }
92
 
 
93
 
                        private void Descend(IEnumerator fieldNames)
94
 
                        {
95
 
                                while (fieldNames.MoveNext())
96
 
                                {
97
 
                                        this.Descend(fieldNames.Current);
98
 
                                }
99
 
                        }
100
 
 
101
 
                        private ComparisonBytecodeGeneratingVisitor ComparisonEmitter()
102
 
                        {
103
 
                                return new ComparisonBytecodeGeneratingVisitor(this._enclosing._builder, this.predicateClass
104
 
                                        );
105
 
                        }
106
 
 
107
 
                        private void Constrain(ComparisonOperator op)
108
 
                        {
109
 
                                this._enclosing.Invoke(this._enclosing.constrainRef);
110
 
                                if (op.Equals(ComparisonOperator.ValueEquality))
111
 
                                {
112
 
                                        return;
113
 
                                }
114
 
                                if (op.Equals(ComparisonOperator.ReferenceEquality))
115
 
                                {
116
 
                                        this._enclosing.Invoke(this._enclosing.identityRef);
117
 
                                        return;
118
 
                                }
119
 
                                if (op.Equals(ComparisonOperator.Greater))
120
 
                                {
121
 
                                        this._enclosing.Invoke(this._enclosing.greaterRef);
122
 
                                        return;
123
 
                                }
124
 
                                if (op.Equals(ComparisonOperator.Smaller))
125
 
                                {
126
 
                                        this._enclosing.Invoke(this._enclosing.smallerRef);
127
 
                                        return;
128
 
                                }
129
 
                                if (op.Equals(ComparisonOperator.Contains))
130
 
                                {
131
 
                                        this._enclosing.Invoke(this._enclosing.containsRef);
132
 
                                        return;
133
 
                                }
134
 
                                if (op.Equals(ComparisonOperator.StartsWith))
135
 
                                {
136
 
                                        this._enclosing.Ldc(1);
137
 
                                        this._enclosing.Invoke(this._enclosing.startsWithRef);
138
 
                                        return;
139
 
                                }
140
 
                                if (op.Equals(ComparisonOperator.EndsWith))
141
 
                                {
142
 
                                        this._enclosing.Ldc(1);
143
 
                                        this._enclosing.Invoke(this._enclosing.endsWithRef);
144
 
                                        return;
145
 
                                }
146
 
                                throw new Exception("Cannot interpret constraint: " + op);
147
 
                        }
148
 
 
149
 
                        private void Descend(object fieldName)
150
 
                        {
151
 
                                this._enclosing.Ldc(fieldName);
152
 
                                this._enclosing.Invoke(this._enclosing.descendRef);
153
 
                        }
154
 
 
155
 
                        public virtual void Visit(NotExpression expression)
156
 
                        {
157
 
                                expression.Expr().Accept(this);
158
 
                                this._enclosing.Invoke(this._enclosing.notRef);
159
 
                        }
160
 
 
161
 
                        private IEnumerator FieldNames(FieldValue fieldValue)
162
 
                        {
163
 
                                Collection4 coll = new Collection4();
164
 
                                IComparisonOperand curOp = fieldValue;
165
 
                                while (curOp is FieldValue)
166
 
                                {
167
 
                                        FieldValue curField = (FieldValue)curOp;
168
 
                                        coll.Prepend(curField.FieldName());
169
 
                                        curOp = curField.Parent();
170
 
                                }
171
 
                                return coll.GetEnumerator();
172
 
                        }
173
 
 
174
 
                        private readonly SODAMethodBuilder _enclosing;
175
 
                }
176
 
 
177
 
                public SODAMethodBuilder(ITypeEditor editor)
178
 
                {
179
 
                        _editor = editor;
180
 
                        BuildMethodReferences();
181
 
                }
182
 
 
183
 
                public virtual void InjectOptimization(IExpression expr)
184
 
                {
185
 
                        _editor.AddInterface(TypeRef(typeof(IDb4oEnhancedFilter)));
186
 
                        _builder = _editor.NewPublicMethod(PlatformName(OptimizeQueryMethodName), TypeRef
187
 
                                (typeof(void)), new ITypeRef[] { TypeRef(typeof(IQuery)) });
188
 
                        ITypeRef predicateClass = _editor.Type;
189
 
                        expr.Accept(new SODAMethodBuilder.SODAExpressionBuilder(this, predicateClass));
190
 
                        _builder.Pop();
191
 
                        _builder.EndMethod();
192
 
                }
193
 
 
194
 
                private ITypeRef TypeRef(Type type)
195
 
                {
196
 
                        return _editor.References.ForType(type);
197
 
                }
198
 
 
199
 
                private string PlatformName(string name)
200
 
                {
201
 
                        return NativeQueriesPlatform.ToPlatformName(name);
202
 
                }
203
 
 
204
 
                private void LoadArgument(int index)
205
 
                {
206
 
                        _builder.LoadArgument(index);
207
 
                }
208
 
 
209
 
                private void Invoke(IMethodRef method)
210
 
                {
211
 
                        _builder.Invoke(method, CallingConvention.Interface);
212
 
                }
213
 
 
214
 
                private void Ldc(object value)
215
 
                {
216
 
                        _builder.Ldc(value);
217
 
                }
218
 
 
219
 
                private void BuildMethodReferences()
220
 
                {
221
 
                        descendRef = MethodRef(typeof(IQuery), "descend", new Type[] { typeof(string) });
222
 
                        constrainRef = MethodRef(typeof(IQuery), "constrain", new Type[] { typeof(object)
223
 
                                 });
224
 
                        greaterRef = MethodRef(typeof(IConstraint), "greater", new Type[] {  });
225
 
                        smallerRef = MethodRef(typeof(IConstraint), "smaller", new Type[] {  });
226
 
                        containsRef = MethodRef(typeof(IConstraint), "contains", new Type[] {  });
227
 
                        startsWithRef = MethodRef(typeof(IConstraint), "startsWith", new Type[] { typeof(
228
 
                                bool) });
229
 
                        endsWithRef = MethodRef(typeof(IConstraint), "endsWith", new Type[] { typeof(bool
230
 
                                ) });
231
 
                        notRef = MethodRef(typeof(IConstraint), "not", new Type[] {  });
232
 
                        andRef = MethodRef(typeof(IConstraint), "and", new Type[] { typeof(IConstraint) }
233
 
                                );
234
 
                        orRef = MethodRef(typeof(IConstraint), "or", new Type[] { typeof(IConstraint) });
235
 
                        identityRef = MethodRef(typeof(IConstraint), "identity", new Type[] {  });
236
 
                }
237
 
 
238
 
                private IMethodRef MethodRef(Type parent, string name, Type[] args)
239
 
                {
240
 
                        try
241
 
                        {
242
 
                                return _editor.References.ForMethod(parent.GetMethod(PlatformName(name), args));
243
 
                        }
244
 
                        catch (Exception e)
245
 
                        {
246
 
                                throw new InstrumentationException(e);
247
 
                        }
248
 
                }
249
 
        }
250
 
}