source: XIOS3/trunk/src/parse_expr/filter_expr_node.cpp @ 2426

Last change on this file since 2426 was 2194, checked in by yushan, 3 years ago

workflow graph : bug fix (check if attribute is defined before querying its value)

File size: 15.2 KB
Line 
1#include "filter_expr_node.hpp"
2#include "unary_arithmetic_filter.hpp"
3#include "binary_arithmetic_filter.hpp"
4#include "ternary_arithmetic_filter.hpp"
5#include "field.hpp"
6
7namespace xios
8{
9  CFilterFieldExprNode::CFilterFieldExprNode(const std::string& fieldId)
10    : fieldId(fieldId)
11  { /* Nothing to do */ }
12
13 
14  std::shared_ptr<COutputPin> CFilterFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
15  {
16    std::shared_ptr<COutputPin> outputPin;
17
18    if (fieldId == "this") outputPin = thisField.getSelfReference(gc);
19    else
20    {
21      string id ;
22
23      if (fieldId == "this_ref")
24      {
25        if (thisField.field_ref.isEmpty())
26        {
27          ERROR("shared_ptr<COutputPin> CFilterFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const",
28                << "field_ref attribute is empty.");
29        }
30        else id = thisField.field_ref ;
31      }
32      else id= fieldId ;
33       
34      if (CField::has(id))
35      {
36        CField* field = CField::get(id);
37        if (field == &thisField)
38          ERROR("shared_ptr<COutputPin> CFilterFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const",
39                << "The field " << id << " has an invalid reference to itself. "
40                << "Use the keyword \"this\" if you want to reference the input data sent to this field.");
41
42        bool ret=field->buildWorkflowGraph(gc);
43        if(!field->build_workflow_graph.isEmpty()) thisField.build_workflow_graph.set(field->build_workflow_graph);
44        if (ret) outputPin = field->getInstantDataFilter(); // if dependency is complete build the graph other return nullptr
45       
46      }
47      else ERROR("boost::shared_ptr<COutputPin> CFilterFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const",
48                  << "The field " << id << " does not exist.");
49    }
50    return outputPin;
51  }
52
53
54  CFilterTemporalFieldExprNode::CFilterTemporalFieldExprNode(const std::string& fieldId)
55    : fieldId(fieldId)
56  { /* Nothing to do */ }
57
58
59  std::shared_ptr<COutputPin> CFilterTemporalFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
60  {
61    std::shared_ptr<COutputPin> outputPin;
62
63    if (fieldId == "this")
64      outputPin = thisField.getSelfTemporalDataFilter(gc, thisField.freq_op.isEmpty() ? TimeStep : thisField.freq_op);
65    else
66    {
67      string id ;
68
69      if (fieldId == "this_ref")
70      {
71        if (thisField.field_ref.isEmpty())
72        {
73          ERROR("shared_ptr<COutputPin> CFilterFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const",
74                << "field_ref attribute is empty.");
75        }
76        else id = thisField.field_ref ;
77      }
78      else id = fieldId ;
79
80      if (CField::has(id))
81      {
82        CField* field = CField::get(id);
83        if (field == &thisField)
84          ERROR("shared_ptr<COutputPin> CFilterTemporalFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const",
85                << "The field " << fieldId << " has an invalid reference to itself. "
86                << "Use the keyword \"this\" if you want to reference the input data sent to this field.");
87
88        bool ret=field->buildWorkflowGraph(gc);
89        if (ret) outputPin = field->getTemporalDataFilter(gc, thisField.freq_op.isEmpty() ? TimeStep : thisField.freq_op);
90      }
91      else
92        ERROR("shared_ptr<COutputPin> CFilterTemporalFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const",
93              << "The field " << fieldId << " does not exist.");
94    }
95    return outputPin;
96  }
97
98
99  CFilterUnaryOpExprNode::CFilterUnaryOpExprNode(const std::string& opId, IFilterExprNode* child)
100    : opId(opId)
101    , child(child)
102  {
103    if (!child)
104      ERROR("CFilterUnaryOpExprNode::CFilterUnaryOpExprNode(const std::string& opId, IFilterExprNode* child)",
105            "Impossible to create the new expression node, an invalid child node was provided.");
106  }
107
108  std::shared_ptr<COutputPin> CFilterUnaryOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
109  {
110    std::shared_ptr<CUnaryArithmeticFilter> filter(new CUnaryArithmeticFilter(gc, opId));
111    auto ret=child->reduce(gc, thisField) ;
112    if (ret) ret->connectOutput(filter, 0);
113    else filter.reset() ;
114   
115    const bool buildGraph_ = !(thisField.build_workflow_graph.isEmpty()) && thisField.build_workflow_graph == true ;
116    if(buildGraph_)
117    {
118      filter->graphPackage = new CGraphPackage;
119      filter->graphEnabled = true;
120      filter->graphPackage->inFields.push_back(&thisField);
121    }
122
123    return filter;
124  }
125
126  CFilterScalarFieldOpExprNode::CFilterScalarFieldOpExprNode(IScalarExprNode* child1, const std::string& opId, IFilterExprNode* child2)
127    : child1(child1)
128    , opId(opId)
129    , child2(child2)
130  {
131    if (!child1 || !child2)
132      ERROR("CFilterScalarFieldOpExprNode::CFilterScalarFieldOpExprNode(IScalarExprNode* child1, const std::string& opId, IFilterExprNode* child2)",
133            "Impossible to create the new expression node, an invalid child node was provided.");
134  }
135
136  std::shared_ptr<COutputPin> CFilterScalarFieldOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
137  {
138    std::shared_ptr<CScalarFieldArithmeticFilter> filter(new CScalarFieldArithmeticFilter(gc, opId, child1->reduce()));
139   
140    auto ret=child2->reduce(gc, thisField) ;
141    if (ret) ret->connectOutput(filter, 0);
142    else filter.reset() ;
143   
144    const bool buildGraph_ = !(thisField.build_workflow_graph.isEmpty()) && thisField.build_workflow_graph == true ;
145    if(buildGraph_)
146    {
147      filter->graphPackage = new CGraphPackage;
148      filter->graphEnabled = true;
149      filter->graphPackage->inFields.push_back(&thisField);
150    }
151
152    return filter;
153  }
154
155  CFilterFieldScalarOpExprNode::CFilterFieldScalarOpExprNode(IFilterExprNode* child1, const std::string& opId, IScalarExprNode* child2)
156    : child1(child1)
157    , opId(opId)
158    , child2(child2)
159  {
160    if (!child1 || !child2)
161      ERROR("CFilterFieldScalarOpExprNode::CFilterFieldScalarOpExprNode(IFilterExprNode* child1, const std::string& opId, IScalarExprNode* child2)",
162            "Impossible to create the new expression node, an invalid child node was provided.");
163  }
164
165  std::shared_ptr<COutputPin> CFilterFieldScalarOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
166  {
167    std::shared_ptr<CFieldScalarArithmeticFilter> filter(new CFieldScalarArithmeticFilter(gc, opId, child2->reduce()));
168    auto ret=child1->reduce(gc, thisField) ;
169    if (ret) ret->connectOutput(filter, 0);
170    else filter.reset() ;
171   
172    const bool buildGraph_ = !(thisField.build_workflow_graph.isEmpty()) && thisField.build_workflow_graph == true ;
173    if(buildGraph_)
174    {
175      filter->graphPackage = new CGraphPackage;
176      filter->graphEnabled = true;
177      filter->graphPackage->inFields.push_back(&thisField);
178    }
179    return filter;
180  }
181
182  CFilterFieldFieldOpExprNode::CFilterFieldFieldOpExprNode(IFilterExprNode* child1, const std::string& opId, IFilterExprNode* child2)
183    : child1(child1)
184    , opId(opId)
185    , child2(child2)
186  {
187    if (!child1 || !child2)
188      ERROR("CFilterFieldFieldOpExprNode::CFilterFieldFieldOpExprNode(IFilterExprNode* child1, const std::string& opId, IFilterExprNode* child2)",
189            "Impossible to create the new expression node, an invalid child node was provided.");
190  }
191
192  std::shared_ptr<COutputPin> CFilterFieldFieldOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
193  {
194    std::shared_ptr<CFieldFieldArithmeticFilter> filter(new CFieldFieldArithmeticFilter(gc, opId));
195    auto ret1 = child1->reduce(gc, thisField);
196    auto ret2 = child2->reduce(gc, thisField);
197    if (ret1 && ret2) 
198    {
199      ret1->connectOutput(filter, 0) ;
200      ret2->connectOutput(filter, 1) ;
201    }
202    else filter.reset() ;
203
204    const bool buildGraph_ = !(thisField.build_workflow_graph.isEmpty()) && thisField.build_workflow_graph == true ;
205    if(buildGraph_)
206    {
207      filter->graphPackage = new CGraphPackage;
208      filter->graphEnabled = true;
209      filter->graphPackage->inFields.push_back(&thisField);
210    }
211
212    return filter;
213  }
214
215
216
217
218  CFilterScalarScalarFieldOpExprNode::CFilterScalarScalarFieldOpExprNode(IScalarExprNode* child1, const std::string& opId, IScalarExprNode* child2, IFilterExprNode* child3)
219    : child1(child1)
220    , opId(opId)
221    , child2(child2)
222    , child3(child3)
223  {
224    if (!child1 || !child2 || !child3)
225      ERROR("  CFilterScalarScalarFieldOpExprNode::CFilterScalarScalarFieldOpExprNode(IScalarExprNode* child1, const std::string& opId, IScalarExprNode* child2, IFilterExprNode* child3)",
226            "Impossible to create the new expression node, an invalid child node was provided.");
227  }
228
229  std::shared_ptr<COutputPin> CFilterScalarScalarFieldOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
230  {
231    std::shared_ptr<CScalarScalarFieldArithmeticFilter> filter(new CScalarScalarFieldArithmeticFilter(gc, opId, child1->reduce(),child2->reduce()));
232    auto ret=child3->reduce(gc, thisField) ;
233    if (ret) ret->connectOutput(filter, 0);
234    else filter.reset() ;
235    return filter;
236  }
237
238
239  CFilterScalarFieldScalarOpExprNode::CFilterScalarFieldScalarOpExprNode(IScalarExprNode* child1, const std::string& opId, IFilterExprNode* child2, IScalarExprNode* child3)
240    : child1(child1)
241    , opId(opId)
242    , child2(child2)
243    , child3(child3)
244  {
245    if (!child1 || !child2 || !child3)
246      ERROR("  CFilterScalarFieldScalarOpExprNode::CFilterScalarFieldScalarOpExprNode(IScalarExprNode* child1, const std::string& opId, IFilterExprNode* child2, IScalarExprNode* child3)",
247            "Impossible to create the new expression node, an invalid child node was provided.");
248  }
249
250  std::shared_ptr<COutputPin> CFilterScalarFieldScalarOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
251  {
252    std::shared_ptr<CScalarFieldScalarArithmeticFilter> filter(new CScalarFieldScalarArithmeticFilter(gc, opId, child1->reduce(),child3->reduce()));
253    auto ret=child2->reduce(gc, thisField);
254    if (ret) ret->connectOutput(filter, 0);
255    else filter.reset() ;
256    return filter;
257  }
258
259
260  CFilterScalarFieldFieldOpExprNode::CFilterScalarFieldFieldOpExprNode(IScalarExprNode* child1, const std::string& opId, IFilterExprNode* child2, IFilterExprNode* child3)
261    : child1(child1)
262    , opId(opId)
263    , child2(child2)
264    , child3(child3)
265  {
266    if (!child1 || !child2 || !child3)
267      ERROR("  CFilterScalarFieldFieldOpExprNode::CFilterScalarFieldFieldOpExprNode(IScalarExprNode* child1, const std::string& opId, IFilterExprNode* child2, IFilterExprNode* child3)",
268            "Impossible to create the new expression node, an invalid child node was provided.");
269  }
270
271  std::shared_ptr<COutputPin> CFilterScalarFieldFieldOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
272  {
273    std::shared_ptr<CScalarFieldFieldArithmeticFilter> filter(new CScalarFieldFieldArithmeticFilter(gc, opId, child1->reduce()));
274    auto ret1=child2->reduce(gc, thisField);
275    auto ret2=child3->reduce(gc, thisField);
276    if (ret1 && ret2)
277    {
278      ret1->connectOutput(filter, 0);
279      ret2->connectOutput(filter, 1);
280    }
281    else filter.reset() ;
282    return filter;
283  }
284
285
286
287  CFilterFieldScalarScalarOpExprNode::CFilterFieldScalarScalarOpExprNode(IFilterExprNode* child1, const std::string& opId, IScalarExprNode* child2, IScalarExprNode* child3)
288    : child1(child1)
289    , opId(opId)
290    , child2(child2)
291    , child3(child3)
292  {
293    if (!child1 || !child2 || !child3)
294      ERROR("  CFilterFieldScalarScalarOpExprNode::CFilterFieldScalarScalarOpExprNode(IFilterExprNode* child1, const std::string& opId, IScalarExprNode* child2, IScalarExprNode* child3)",
295            "Impossible to create the new expression node, an invalid child node was provided.");
296  }
297
298  std::shared_ptr<COutputPin> CFilterFieldScalarScalarOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
299  {
300    std::shared_ptr<CFieldScalarScalarArithmeticFilter> filter(new CFieldScalarScalarArithmeticFilter(gc, opId, child2->reduce(),child3->reduce()));
301    auto ret = child1->reduce(gc, thisField) ;
302    if (ret) ret->connectOutput(filter, 0);
303    else filter.reset() ;
304    return filter;
305  }
306
307
308
309  CFilterFieldScalarFieldOpExprNode::CFilterFieldScalarFieldOpExprNode(IFilterExprNode* child1, const std::string& opId, IScalarExprNode* child2, IFilterExprNode* child3)
310    : child1(child1)
311    , opId(opId)
312    , child2(child2)
313    , child3(child3)
314  {
315    if (!child1 || !child2 || !child3)
316      ERROR("  CFilterFieldScalarFieldOpExprNode::CFilterFieldScalarFieldOpExprNode(IFilterExprNode* child1, const std::string& opId, IScalarExprNode* child2, IFilterExprNode* child3)",
317            "Impossible to create the new expression node, an invalid child node was provided.");
318  }
319
320  std::shared_ptr<COutputPin> CFilterFieldScalarFieldOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
321  {
322    std::shared_ptr<CFieldScalarFieldArithmeticFilter> filter(new CFieldScalarFieldArithmeticFilter(gc, opId, child2->reduce()));
323    auto ret1 = child1->reduce(gc, thisField);
324    auto ret2 = child3->reduce(gc, thisField);
325    if (ret1 && ret2)
326    {
327      ret1 -> connectOutput(filter, 0);
328      ret2 -> connectOutput(filter, 1);
329    }
330    else filter.reset() ;
331    return filter;
332  }
333
334
335
336  CFilterFieldFieldScalarOpExprNode::CFilterFieldFieldScalarOpExprNode(IFilterExprNode* child1, const std::string& opId, IFilterExprNode* child2, IScalarExprNode* child3)
337    : child1(child1)
338    , opId(opId)
339    , child2(child2)
340    , child3(child3)
341  {
342    if (!child1 || !child2 || !child3)
343      ERROR("  CFilterFieldFieldScalarOpExprNode::CFilterFieldFieldScalarOpExprNode(IFilterExprNode* child1, const std::string& opId, IFilterExprNode* child2, IScalarExprNode* child3)",
344            "Impossible to create the new expression node, an invalid child node was provided.");
345  }
346
347  std::shared_ptr<COutputPin> CFilterFieldFieldScalarOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
348  {
349    std::shared_ptr<CFieldFieldScalarArithmeticFilter> filter(new CFieldFieldScalarArithmeticFilter(gc, opId, child3->reduce()));
350    auto ret1 = child1->reduce(gc, thisField);
351    auto ret2 = child2->reduce(gc, thisField);
352    if (ret1 && ret2)
353    {
354      ret1->connectOutput(filter, 0);
355      ret2->connectOutput(filter, 1);
356    }
357    else filter.reset() ;
358    return filter;
359  }
360
361
362  CFilterFieldFieldFieldOpExprNode::CFilterFieldFieldFieldOpExprNode(IFilterExprNode* child1, const std::string& opId, IFilterExprNode* child2, IFilterExprNode* child3)
363    : child1(child1)
364    , opId(opId)
365    , child2(child2)
366    , child3(child3)
367  {
368    if (!child1 || !child2 || !child3)
369      ERROR("  CFilterFieldFieldFieldOpExprNode::CFilterFieldFieldFieldOpExprNode(IFilterExprNode* child1, const std::string& opId, IFilterExprNode* child2, IFilterExprNode* child3)",
370            "Impossible to create the new expression node, an invalid child node was provided.");
371  }
372
373  std::shared_ptr<COutputPin> CFilterFieldFieldFieldOpExprNode::reduce(CGarbageCollector& gc, CField& thisField) const
374  {
375    std::shared_ptr<CFieldFieldFieldArithmeticFilter> filter(new CFieldFieldFieldArithmeticFilter(gc, opId));
376    auto ret1=child1->reduce(gc, thisField);
377    auto ret2=child2->reduce(gc, thisField);
378    auto ret3=child3->reduce(gc, thisField);
379    if (ret1 && ret2 && ret3)
380    {
381      ret1->connectOutput(filter, 0);
382      ret2->connectOutput(filter, 1);
383      ret3->connectOutput(filter, 2);
384    }
385    else filter.reset() ;
386    return filter;
387  }
388 
389}
Note: See TracBrowser for help on using the repository browser.