source: XIOS/trunk/src/filter/binary_arithmetic_filter.cpp @ 2015

Last change on this file since 2015 was 1876, checked in by yushan, 4 years ago

trunk : Bug fixed in workflow graph. wrong connection happens when a chain of arithmetic operations is applied on a field.

File size: 11.9 KB
RevLine 
[642]1#include "binary_arithmetic_filter.hpp"
[1704]2#include "workflow_graph.hpp"
3#include "yacc_var.hpp"
4#include "file.hpp"
[642]5
[1704]6
[642]7namespace xios
8{
9  CScalarFieldArithmeticFilter::CScalarFieldArithmeticFilter(CGarbageCollector& gc, const std::string& op, double value)
10    : CFilter(gc, 1, this)
11    , op(operatorExpr.getOpScalarField(op))
12    , value(value)
[1876]13  { };
[642]14
[1704]15  std::tuple<int, int, int> CScalarFieldArithmeticFilter::buildGraph(std::vector<CDataPacketPtr> data)
16  {
17    bool building_graph = this->tag ? data[0]->timestamp >= this->start_graph && data[0]->timestamp <= this->end_graph : false;
18    int unique_filter_id;
19    bool firstround;
20
21    if(building_graph)
22    {
23      CWorkflowGraph::allocNodeEdge();
24
[1876]25      size_t filterhash = std::hash<StdString>{}(this->field->content+to_string(data[0]->timestamp)+this->field->getId());
[1704]26
27      // first round
28      if(CWorkflowGraph::mapHashFilterID_ptr->find(filterhash) == CWorkflowGraph::mapHashFilterID_ptr->end())
29      {
30        firstround = true;
31        this->filterID = InvalidableObject::filterIdGenerator++;
32        int edgeID = InvalidableObject::edgeIdGenerator++;
33
[1876]34        CWorkflowGraph::addNode(this->filterID, "Arithmetic Filter\\n("+this->field->content+")", 3, 1, 0, data[0]);
[1704]35        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].filter_tag = this->tag;
36        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].distance = data[0]->distance+1;
37
38
39        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].attributes = this->field->record4graphXiosAttributes();
40        if(this->field->file) (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].attributes += "</br>file attributes : </br>" +this->field->file->record4graphXiosAttributes();
41     
42
43        if(CWorkflowGraph::build_begin)
44        {
45          CWorkflowGraph::addEdge(edgeID, this->filterID, data[0]);
46          (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].expected_entry_nb ++;
47
48          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[0]->src_filterID].filter_filled = 0 ;
49        }
50        else CWorkflowGraph::build_begin = true;
51
52        (*CWorkflowGraph::mapHashFilterID_ptr)[filterhash] = this->filterID; 
53        unique_filter_id = this->filterID;
54      }
55      // not first round
56      else 
57      {
58        firstround=false;
59        unique_filter_id = (*CWorkflowGraph::mapHashFilterID_ptr)[filterhash];
60        if(data[0]->src_filterID != unique_filter_id)
61        {
62          int edgeID = InvalidableObject::edgeIdGenerator++;
63          CWorkflowGraph::addEdge(edgeID, unique_filter_id, data[0]); 
64          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[0]->src_filterID].filter_filled = 0 ; 
65          (*CWorkflowGraph::mapFilters_ptr_with_info)[unique_filter_id].expected_entry_nb ++;
66        }
67      } 
68    }
69
70    return std::make_tuple(building_graph, firstround, unique_filter_id);
71  }
72
73
[642]74  CDataPacketPtr CScalarFieldArithmeticFilter::apply(std::vector<CDataPacketPtr> data)
75  {
76    CDataPacketPtr packet(new CDataPacket);
[643]77    packet->date = data[0]->date;
[642]78    packet->timestamp = data[0]->timestamp;
79    packet->status = data[0]->status;
80
[1704]81    std::tuple<int, int, int> graph = buildGraph(data);
82
83    if(std::get<0>(graph)) packet->src_filterID = std::get<2>(graph);
84    if(std::get<0>(graph) && std::get<1>(graph)) packet->distance = data[0]->distance+1;
85    if(std::get<0>(graph) && !std::get<1>(graph)) packet->distance = data[0]->distance;
86
87    packet->field = this->field;
88
[642]89    if (packet->status == CDataPacket::NO_ERROR)
90      packet->data.reference(op(value, data[0]->data));
91
92    return packet;
93  }
94
95  CFieldScalarArithmeticFilter::CFieldScalarArithmeticFilter(CGarbageCollector& gc, const std::string& op, double value)
96    : CFilter(gc, 1, this)
97    , op(operatorExpr.getOpFieldScalar(op))
98    , value(value)
[1876]99  {  };
[642]100
[1704]101  std::tuple<int, int, int> CFieldScalarArithmeticFilter::buildGraph(std::vector<CDataPacketPtr> data)
102  {
103    bool building_graph = this->tag ? data[0]->timestamp >= this->start_graph && data[0]->timestamp <= this->end_graph : false;
104    int unique_filter_id;
105    bool firstround;
106
107    if(building_graph)
108    {
109      CWorkflowGraph::allocNodeEdge();
110
[1876]111      size_t filterhash = std::hash<StdString>{}(this->field->content+to_string(data[0]->timestamp)+this->field->getId());
[1704]112
113      // first round
114      if(CWorkflowGraph::mapHashFilterID_ptr->find(filterhash) == CWorkflowGraph::mapHashFilterID_ptr->end())
115      {
116        firstround = true;
117        this->filterID = InvalidableObject::filterIdGenerator++;
118        int edgeID = InvalidableObject::edgeIdGenerator++;
119
[1876]120        CWorkflowGraph::addNode(this->filterID, "Arithmetic Filter\\n("+this->field->content+")", 3, 1, 0, data[0]);
[1704]121        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].filter_tag = this->tag;
122        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].distance = data[0]->distance+1;
123
124
125        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].attributes = this->field->record4graphXiosAttributes();
126        if(this->field->file) (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].attributes += "</br>file attributes : </br>" +this->field->file->record4graphXiosAttributes();
127     
128
129        if(CWorkflowGraph::build_begin)
130        {
131          CWorkflowGraph::addEdge(edgeID, this->filterID, data[0]);
132          (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].expected_entry_nb ++;
133
134          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[0]->src_filterID].filter_filled = 0 ;
135        }
136        else CWorkflowGraph::build_begin = true;
137
138        (*CWorkflowGraph::mapHashFilterID_ptr)[filterhash] = this->filterID; 
139        unique_filter_id = this->filterID;
140      }
141      // not first round
142      else 
143      {
144        firstround=false;
145        unique_filter_id = (*CWorkflowGraph::mapHashFilterID_ptr)[filterhash];
146        if(data[0]->src_filterID != unique_filter_id)
147        {
148          int edgeID = InvalidableObject::edgeIdGenerator++;
149          CWorkflowGraph::addEdge(edgeID, unique_filter_id, data[0]); 
150          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[0]->src_filterID].filter_filled = 0 ; 
151          (*CWorkflowGraph::mapFilters_ptr_with_info)[unique_filter_id].expected_entry_nb ++;
152        }
153      } 
154    }
155
156    return std::make_tuple(building_graph, firstround, unique_filter_id);
157  }
158
[642]159  CDataPacketPtr CFieldScalarArithmeticFilter::apply(std::vector<CDataPacketPtr> data)
160  {
161    CDataPacketPtr packet(new CDataPacket);
[643]162    packet->date = data[0]->date;
[642]163    packet->timestamp = data[0]->timestamp;
164    packet->status = data[0]->status;
165
[1704]166    std::tuple<int, int, int> graph = buildGraph(data);
167
[1876]168    if(std::get<0>(graph))
169    { 
170      packet->src_filterID = std::get<2>(graph);
171      if(std::get<1>(graph)) packet->distance = data[0]->distance+1;
172      else  packet->distance = data[0]->distance+1;
173    }
174   
[1704]175    packet->field = this->field;
176
[642]177    if (packet->status == CDataPacket::NO_ERROR)
178      packet->data.reference(op(data[0]->data, value));
179
180    return packet;
181  }
182
183  CFieldFieldArithmeticFilter::CFieldFieldArithmeticFilter(CGarbageCollector& gc, const std::string& op)
[804]184    : CFilter(gc, 2, this)
[642]185    , op(operatorExpr.getOpFieldField(op))
[1876]186  { };
[642]187
[1704]188  std::tuple<int, int, int> CFieldFieldArithmeticFilter::buildGraph(std::vector<CDataPacketPtr> data)
189  {
190    bool building_graph = this->tag ? ((data[0]->timestamp >= this->field->field_graph_start && data[0]->timestamp <= this->field->field_graph_end) && (data[0]->timestamp == data[1]->timestamp)) : false;
191
192    int unique_filter_id;
193
194    bool firstround;
195
196    if(building_graph)
197    { 
198      CWorkflowGraph::allocNodeEdge();
199
200
[1876]201      size_t filterhash = std::hash<StdString>{}(this->field->content+to_string(data[0]->timestamp)+this->field->getId());
[1704]202
203      // first round
204      if(CWorkflowGraph::mapHashFilterID_ptr->find(filterhash) == CWorkflowGraph::mapHashFilterID_ptr->end())
205      {
206        firstround = true;
207        this->filterID = InvalidableObject::filterIdGenerator++;
208        int edgeID = InvalidableObject::edgeIdGenerator++;
209   
[1876]210        CWorkflowGraph::addNode(this->filterID, "Arithmetic Filter\\n("+this->field->content+")", 3, 1, 0, data[0]);
[1704]211        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].attributes = this->field->record4graphXiosAttributes();
212        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].distance = data[0]->distance+1;
213
214        if(this->field->file) (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].attributes += "</br>file attributes : </br>" +this->field->file->record4graphXiosAttributes();
215   
216        (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].filter_tag = this->tag;
217        if(CWorkflowGraph::build_begin)
218        {
219
220          CWorkflowGraph::addEdge(edgeID, this->filterID, data[0]);
221          (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].expected_entry_nb ++;
222
223          edgeID = InvalidableObject::edgeIdGenerator++;
224
225          CWorkflowGraph::addEdge(edgeID, this->filterID, data[1]);
226          (*CWorkflowGraph::mapFilters_ptr_with_info)[this->filterID].expected_entry_nb ++;
227
228          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[0]->src_filterID].filter_filled = 0 ;
229          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[1]->src_filterID].filter_filled = 0 ;
230        }
231        CWorkflowGraph::build_begin = true;
232
233        (*CWorkflowGraph::mapHashFilterID_ptr)[filterhash] = this->filterID; 
234        unique_filter_id = this->filterID;
235 
236      }
237      // not first round
238      else 
239      {
240        firstround = false;
241        unique_filter_id = (*CWorkflowGraph::mapHashFilterID_ptr)[filterhash];
242        if(data[0]->src_filterID != unique_filter_id)
243        {
244          int edgeID = InvalidableObject::edgeIdGenerator++;
245          CWorkflowGraph::addEdge(edgeID, unique_filter_id, data[0]); 
246          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[0]->src_filterID].filter_filled = 0 ; 
247          (*CWorkflowGraph::mapFilters_ptr_with_info)[unique_filter_id].expected_entry_nb ++;
[1876]248          data[0]->distance=max(data[0]->distance, (*CWorkflowGraph::mapFilters_ptr_with_info)[unique_filter_id].distance);
[1704]249        }
250        if(data[1]->src_filterID != unique_filter_id)
251        { 
252          int edgeID = InvalidableObject::edgeIdGenerator++;
253          CWorkflowGraph::addEdge(edgeID, unique_filter_id, data[1]); 
254          (*CWorkflowGraph::mapFilters_ptr_with_info)[data[1]->src_filterID].filter_filled = 0 ;
255          (*CWorkflowGraph::mapFilters_ptr_with_info)[unique_filter_id].expected_entry_nb ++;
[1876]256          data[1]->distance=max(data[1]->distance, (*CWorkflowGraph::mapFilters_ptr_with_info)[unique_filter_id].distance);   
[1704]257        }
258       
259      } 
260    }
261
262    return std::make_tuple(building_graph, firstround, unique_filter_id);
263  }
264
[642]265  CDataPacketPtr CFieldFieldArithmeticFilter::apply(std::vector<CDataPacketPtr> data)
266  {
267    CDataPacketPtr packet(new CDataPacket);
[643]268    packet->date = data[0]->date;
[642]269    packet->timestamp = data[0]->timestamp;
270
[1704]271    std::tuple<int, int, int> graph = buildGraph(data);
272
273    if(std::get<0>(graph)) packet->src_filterID = std::get<2>(graph);
[1876]274    if(std::get<0>(graph) && std::get<1>(graph)) packet->distance = max(data[0]->distance+1, data[1]->distance+1);
275    if(std::get<0>(graph) && !std::get<1>(graph)) packet->distance = max(data[0]->distance, data[1]->distance);
[1704]276   
277    packet->field = this->field;
278   
279
[642]280    if (data[0]->status != CDataPacket::NO_ERROR)
281      packet->status = data[0]->status;
282    else if (data[1]->status != CDataPacket::NO_ERROR)
283      packet->status = data[1]->status;
284    else
285    {
286      packet->status = CDataPacket::NO_ERROR;
287      packet->data.reference(op(data[0]->data, data[1]->data));
288    }
289
290    return packet;
291  }
[1704]292
293  StdString CScalarFieldArithmeticFilter::GetName(void)    { return StdString("CScalarFieldArithmeticFilter"); }
294  StdString CFieldScalarArithmeticFilter::GetName(void)    { return StdString("CFieldScalarArithmeticFilter"); }
295  StdString CFieldFieldArithmeticFilter::GetName(void)     { return StdString("CFieldFieldArithmeticFilter"); }
296
297
[642]298} // namespace xios
Note: See TracBrowser for help on using the repository browser.