DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
Evaluator.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Linq.Expressions;
20 
21 namespace Deveel.Data.Linq {
22  static class Evaluator {
29  public static Expression PartialEval(Expression expression, Func<Expression, bool> fnCanBeEvaluated) {
30  return new SubtreeEvaluator(new Nominator(fnCanBeEvaluated).Nominate(expression)).Eval(expression);
31  }
32 
38  public static Expression PartialEval(Expression expression) {
39  return PartialEval(expression, CanBeEvaluatedLocally);
40  }
41 
42  private static bool CanBeEvaluatedLocally(Expression expression) {
43  return expression.NodeType != ExpressionType.Parameter;
44  }
45 
50  HashSet<Expression> candidates;
51 
52  internal SubtreeEvaluator(HashSet<Expression> candidates) {
53  this.candidates = candidates;
54  }
55 
56  internal Expression Eval(Expression exp) {
57  return this.Visit(exp);
58  }
59 
60  public override Expression Visit(Expression exp) {
61  if (exp == null) {
62  return null;
63  }
64  if (candidates.Contains(exp)) {
65  return Evaluate(exp);
66  }
67  return base.Visit(exp);
68  }
69 
70  private Expression Evaluate(Expression e) {
71  if (e.NodeType == ExpressionType.Constant) {
72  return e;
73  }
74  LambdaExpression lambda = Expression.Lambda(e);
75  Delegate fn = lambda.Compile();
76  return Expression.Constant(fn.DynamicInvoke(null), e.Type);
77  }
78  }
79 
85  Func<Expression, bool> fnCanBeEvaluated;
86  HashSet<Expression> candidates;
88 
89  internal Nominator(Func<Expression, bool> fnCanBeEvaluated) {
90  this.fnCanBeEvaluated = fnCanBeEvaluated;
91  }
92 
93  internal HashSet<Expression> Nominate(Expression expression) {
94  this.candidates = new HashSet<Expression>();
95  this.Visit(expression);
96  return this.candidates;
97  }
98 
99  public override Expression Visit(Expression expression) {
100  if (expression != null) {
101  bool saveCannotBeEvaluated = this.cannotBeEvaluated;
102  this.cannotBeEvaluated = false;
103  base.Visit(expression);
104  if (!this.cannotBeEvaluated) {
105  if (this.fnCanBeEvaluated(expression)) {
106  this.candidates.Add(expression);
107  } else {
108  this.cannotBeEvaluated = true;
109  }
110  }
111  this.cannotBeEvaluated |= saveCannotBeEvaluated;
112  }
113  return expression;
114  }
115  }
116  }
117 }
override Expression Visit(Expression expression)
Definition: Evaluator.cs:99
Performs bottom-up analysis to determine which nodes can possibly be part of an evaluated sub-tree...
Definition: Evaluator.cs:84
HashSet< Expression > Nominate(Expression expression)
Definition: Evaluator.cs:93
Evaluates & replaces sub-trees when first candidate is reached (top-down)
Definition: Evaluator.cs:49
SubtreeEvaluator(HashSet< Expression > candidates)
Definition: Evaluator.cs:52
static bool CanBeEvaluatedLocally(Expression expression)
Definition: Evaluator.cs:42
Expression Eval(Expression exp)
Definition: Evaluator.cs:56
Func< Expression, bool > fnCanBeEvaluated
Definition: Evaluator.cs:85
Expression Evaluate(Expression e)
Definition: Evaluator.cs:70
override Expression Visit(Expression exp)
Definition: Evaluator.cs:60
static Expression PartialEval(Expression expression, Func< Expression, bool > fnCanBeEvaluated)
Performs evaluation & replacement of independent sub-trees
Definition: Evaluator.cs:29
Nominator(Func< Expression, bool > fnCanBeEvaluated)
Definition: Evaluator.cs:89
static Expression PartialEval(Expression expression)
Performs evaluation & replacement of independent sub-trees
Definition: Evaluator.cs:38
HashSet< Expression > candidates
Definition: Evaluator.cs:86