m2etis  0.4
AttributeTypeInformation.h
Go to the documentation of this file.
1 /*
2  Copyright (2016) Michael Baer, Daniel Bonrath, All rights reserved.
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 
22 #ifndef __M2ETIS_PUBSUB_FILTER_ATTRIBUTETYPEINFORMATION_H__
23 #define __M2ETIS_PUBSUB_FILTER_ATTRIBUTETYPEINFORMATION_H__
24 
25 #include <memory>
26 
27 #include "m2etis/util/Exceptions.h"
28 
38 
39 #include "boost/make_shared.hpp"
40 
54 namespace m2etis {
55 namespace pubsub {
56 namespace filter {
57 
58  typedef int AttributeName;
59 
60  template<typename EventType, typename AttributeType> class AttributeFilter;
61  template<typename EventType, typename AttributeType> class EqualsAttributeFilter;
62  template<typename EventType, typename AttributeType> class NotEqualsAttributeFilter;
63  template<typename EventType, typename AttributeType> class GreaterThanAttributeFilter;
64  template<typename EventType, typename AttributeType> class LessThanAttributeFilter;
65 
66  template<typename EventType, typename NetworkType> class DecisionTreePreProcessVisitor;
67  template<typename EventType, typename NetworkType> class DecisionTreeFilter;
68  template<typename EventType, typename NetworkType> class DecisionTreeWalkerVisitor;
69 
70  template<typename EventType, typename NetworkType> class GeneralBooleanExpressionsPreProcessVisitor;
71  template<typename EventType, typename NetworkType> class GeneralBooleanExpressionsFilter;
72 
73  template<typename EventType> class PredicateIndex;
74 
75  // class to gain access to attribute type of filter:
76  // helpful to avoid writing duplicate code for different attribute type, e.g. in DecisionTreePreProcessVisitor
77  // or GeneralBooleanExpressionsPreProcessVisitor
78 
79  template<typename EventType, typename NetworkType>
81  public:
82  friend class DecisionTreePreProcessVisitor<EventType, NetworkType>;
83  friend class DecisionTreeWalkerVisitor<EventType, NetworkType>;
84 
85  template<typename AttributeType> void operator()(const AttributeFilter<EventType, AttributeType> * equals_predicate, DecisionTreeFilter<EventType, NetworkType> *) {
86  // DecisionTreeFilter parameter for overloading purposes
87 
88  if (!*decision_tree_node_ptr_) {
89  // node has to be added to subscription tree
90  *decision_tree_node_ptr_ = boost::make_shared<AttributeDecisionTreeNode<EventType, NetworkType, AttributeType> >(AttributeDecisionTreeNode<EventType, NetworkType, AttributeType>(equals_predicate->get_attribute_id()));
91  }
92 
93  if ((equals_predicate->get_constants()).empty()) {
94  // follow dont care edge
95  auto & dont_care_subnode_ptr_ = dynamic_cast<AttributeDecisionTreeNode<EventType, NetworkType, AttributeType>*>(decision_tree_node_ptr_->get())->dont_care_subnode_ptr_;
96 
97  decision_tree_node_ptr_ = &(dont_care_subnode_ptr_);
98  } else {
99  // look for edge with value of attribute type
100  auto & result_subnodes = dynamic_cast<AttributeDecisionTreeNode<EventType, NetworkType, AttributeType>*>(decision_tree_node_ptr_->get())->result_subnodes_;
101 
102  auto result_subnode_iterator = result_subnodes.find(equals_predicate->get_constants()[0]);
103 
104  if (result_subnode_iterator != result_subnodes.end()) {
105  // v has an edge e with the result -> follow the edge
106  decision_tree_node_ptr_ = &(result_subnode_iterator->second);
107  } else {
108  // create new edge and follow (shared pointer is null, initialized in this function when visiting the next node)
109  result_subnodes[equals_predicate->get_constants()[0]] = boost::shared_ptr<DecisionTreeNode<EventType, NetworkType> >();
110  // TODO: (Roland) check if really null
111  decision_tree_node_ptr_ = &(result_subnodes[equals_predicate->get_constants()[0]]);
112  }
113  }
114  }
115 
116  template<typename AttributeType> void operator()(const AttributeFilter<EventType, AttributeType> * equals_predicate, DecisionTreeFilter<EventType, NetworkType> *, int) {
117  // walks through the decision tree
118  // DecisionTreeFilter and int parameter for overloading purposes
119 
120  // look for edge with value of attribute in filte
121  if ((equals_predicate->get_constants()).empty()) {
122  // follow dont care edge
123  auto & dont_care_subnode_ptr_ = dynamic_cast<AttributeDecisionTreeNode<EventType, NetworkType, AttributeType>*>(decision_tree_node_ptr_->get())->dont_care_subnode_ptr_;
124 
125  decision_tree_node_ptr_ = &(dont_care_subnode_ptr_);
126  } else {
127  // look for edge with value of attribute type
128  auto & result_subnodes = dynamic_cast<AttributeDecisionTreeNode<EventType, NetworkType, AttributeType>*>(decision_tree_node_ptr_->get())->result_subnodes_;
129 
130  auto result_subnode_iterator = result_subnodes.find(equals_predicate->get_constants()[0]);
131 
132  if (result_subnode_iterator != result_subnodes.end()) {
133  // v has an edge e with the result -> follow the edge
134 
135  decision_tree_node_ptr_ = &(result_subnode_iterator->second);
136  } else {
137  // no edge contained <= filter not registered
138  // set decision_tree_node_ptr to null to signal
139  // not registered filter
140  decision_tree_node_ptr_ = nullptr;
141  }
142  }
143  } // operator() for walking decision trees with given filter
144 
145  friend class GeneralBooleanExpressionsPreProcessVisitor<EventType, NetworkType>;
146 
148  M2ETIS_THROW_API("AttributeTypeInformation", "function called for AttributeFilter. Should be called for special kind.");
149  }
150 
151  template<typename AttributeType> void operator()(const EqualsAttributeFilter<EventType, AttributeType>* equals_predicate, GeneralBooleanExpressionsFilter<EventType, NetworkType> *) { // overloaded for general boolean expressions
152  // check if predicate index for combination of attribute name and operator already exists:
153  bool has_predicate = false;
154 
155  for (auto predicate_index : (*predicate_indexes_)) {
156  if ((predicate_index)->get_operator() == EQUALS && (predicate_index)->get_attribute_id() == equals_predicate->get_attribute_id()) {
157  // add value to existing predicate index
158  has_predicate = true;
159  auto equals_predicate_index = std::dynamic_pointer_cast<EqualsPredicateIndex<EventType, AttributeType> >(predicate_index);
160 
161  auto new_predicate_id = equals_predicate_index->addPredicate(equals_predicate);
162  // store predicate identifier , that is returned, in predicate subscription association table
163  // maybe more than once
164 
165  if (predicate_subscription_association_table_->find(new_predicate_id) == predicate_subscription_association_table_->end()) {
166  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
167  } else {
168  (*predicate_subscription_association_table_)[new_predicate_id].insert(current_subscription_id_);
169  }
170  break;
171  }
172  }
173  if (!has_predicate) {
174  // create new predicate index and add value;
175  auto equals_predicate_index = std::make_shared<EqualsPredicateIndex<EventType, AttributeType> >(equals_predicate->get_attribute_id(), predicate_identifier_factory_);
176 
177  predicate_indexes_->push_back(equals_predicate_index);
178 
179  auto new_predicate_id = equals_predicate_index->addPredicate(equals_predicate);
180 
181  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
182  }
183  } // Equals for GeneralBooleanExpressions
184 
185  template<typename AttributeType> void operator()(const NotEqualsAttributeFilter<EventType, AttributeType> * notequals_predicate, GeneralBooleanExpressionsFilter<EventType, NetworkType> *) { // overloaded for general boolean expressions
186  // check if predicate index for combination of attribute name and operator already exists:
187  bool has_predicate = false;
188 
189  for (auto predicate_index : (*predicate_indexes_)) {
190  if ((predicate_index)->get_operator() == NOTEQUALS && (predicate_index)->get_attribute_id() == notequals_predicate->get_attribute_id()) {
191  // add value to existing predicate index
192  has_predicate = true;
193  auto notequals_predicate_index = std::dynamic_pointer_cast<NotEqualsPredicateIndex<EventType, AttributeType> >(predicate_index);
194 
195  auto new_predicate_id = notequals_predicate_index->addPredicate(notequals_predicate);
196  // store predicate identifier , that is returned, in predicate subscription association table
197  // maybe more than once
198 
199  if (predicate_subscription_association_table_->find(new_predicate_id) == predicate_subscription_association_table_->end()) {
200  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
201  } else {
202  (*predicate_subscription_association_table_)[new_predicate_id].insert(current_subscription_id_);
203  }
204  break;
205  }
206  }
207  if (!has_predicate) {
208  // create new predicate index and add value;
209  auto notequals_predicate_index = std::make_shared<NotEqualsPredicateIndex<EventType, AttributeType> >(notequals_predicate->get_attribute_id(), predicate_identifier_factory_);
210 
211  predicate_indexes_->push_back(notequals_predicate_index);
212 
213  auto new_predicate_id = notequals_predicate_index->addPredicate(notequals_predicate);
214 
215  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
216  }
217  } // NotEquals for GeneralBooleanExpressions
218 
219  template<typename AttributeType> void operator()(const GreaterThanAttributeFilter<EventType, AttributeType> * greater_than_predicate, GeneralBooleanExpressionsFilter<EventType, NetworkType> *) { // overloaded for general boolean expressions
220  // check if predicate index for combination of attribute name and operator already exists:
221  bool has_predicate = false;
222  for (auto predicate_index : (*predicate_indexes_)) {
223  if ((predicate_index)->get_operator() == GREATERTHAN && (predicate_index)->get_attribute_id() == greater_than_predicate->get_attribute_id()) {
224  // predicate index already exists
225 
226  // add value to existing predicate index
227  has_predicate = true;
228  auto greaterthan_predicate_index = std::dynamic_pointer_cast<GreaterThanPredicateIndex<EventType, AttributeType> >(predicate_index);
229 
230  auto new_predicate_id = greaterthan_predicate_index->addPredicate(greater_than_predicate);
231  // store predicate identifier , that is returned, in predicate subscription association table
232  // maybe more than once
233 
234  if (predicate_subscription_association_table_->find(new_predicate_id) == predicate_subscription_association_table_->end()) {
235  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
236  } else {
237  (*predicate_subscription_association_table_)[new_predicate_id].insert(current_subscription_id_);
238  }
239  break;
240  }
241  }
242  if (!has_predicate) {
243  // create new predicate index and add value;
244  auto greater_than_predicate_index = std::make_shared<GreaterThanPredicateIndex<EventType, AttributeType> >(greater_than_predicate->get_attribute_id(), predicate_identifier_factory_);
245 
246  predicate_indexes_->push_back(greater_than_predicate_index);
247 
248  auto new_predicate_id = greater_than_predicate_index->addPredicate(greater_than_predicate);
249 
250  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
251  }
252  } // GreaterThan
253 
254  template<typename AttributeType> void operator()(const LessThanAttributeFilter<EventType, AttributeType> * less_than_predicate, GeneralBooleanExpressionsFilter<EventType, NetworkType> *) { // overloaded for general boolean expressions
255  // check if predicate index for combination of attribute name and operator already exists:
256  bool has_predicate = false;
257  for (auto predicate_index : (*predicate_indexes_)) {
258  if ((predicate_index)->get_operator() == LESSTHAN && (predicate_index)->get_attribute_id() == less_than_predicate->get_attribute_id()) {
259  // add value to existing predicate index
260  has_predicate = true;
261  auto lessthan_predicate_index = std::dynamic_pointer_cast<LessThanPredicateIndex<EventType, AttributeType> >(predicate_index);
262 
263  auto new_predicate_id = lessthan_predicate_index->addPredicate(less_than_predicate);
264  // store predicate identifier , that is returned, in predicate subscription association table
265  // maybe more than once
266 
267  if (predicate_subscription_association_table_->find(new_predicate_id) == predicate_subscription_association_table_->end()) {
268  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
269  } else {
270  (*predicate_subscription_association_table_)[new_predicate_id].insert(current_subscription_id_);
271  }
272  break;
273  }
274  }
275  if (!has_predicate) {
276  // create new predicate index and add value;
277  auto less_than_predicate_index = std::make_shared<LessThanPredicateIndex<EventType, AttributeType> >(less_than_predicate->get_attribute_id(), predicate_identifier_factory_);
278 
279  predicate_indexes_->push_back(less_than_predicate_index);
280 
281  auto new_predicate_id = less_than_predicate_index->addPredicate(less_than_predicate);
282 
283  (*predicate_subscription_association_table_)[new_predicate_id] = std::multiset<SubscriptionIdentifierFactory::SubscriptionID>{current_subscription_id_};
284  }
285  } // LessThan
286 
287  private:
288  // the following attributes are usually set by the boolean expression visitor
289  // ******** attributes for decision tree filter ********************
290  boost::shared_ptr<DecisionTreeNode<EventType, NetworkType> > * decision_tree_node_ptr_;
291 
292  // ******** attributes for general boolean expressions filter ******
293  std::vector<std::shared_ptr<PredicateIndex<EventType> > > * predicate_indexes_;
294  std::map<PredicateIdentifierFactory::PredicateID, std::multiset<SubscriptionIdentifierFactory::SubscriptionID> > * predicate_subscription_association_table_;
295 
296  PredicateIdentifierFactory * predicate_identifier_factory_;
297 
298  SubscriptionIdentifierFactory::SubscriptionID current_subscription_id_;
299  };
300  // AttributeTypeInforamtion
301 
302 } /* namespace filter */
303 } /* namespace pubsub */
304 } /* namespace m2etis */
305 
306 #endif /* __M2ETIS_PUBSUB_FILTER_ATTRIBUTETYPEINFORMATION_H__ */
307 
PredicateIdentifierFactory::PredicateID addPredicate(const LessThanAttributeFilter< EventType, AttributeType > *less_than_attribute_filter)
void operator()(const GreaterThanAttributeFilter< EventType, AttributeType > *greater_than_predicate, GeneralBooleanExpressionsFilter< EventType, NetworkType > *)
PredicateIdentifierFactory::PredicateID addPredicate(const EqualsAttributeFilter< EventType, AttributeType > *equals_attribute_filter)
void operator()(const AttributeFilter< EventType, AttributeType > *equals_predicate, DecisionTreeFilter< EventType, NetworkType > *)
PredicateIdentifierFactory::PredicateID addPredicate(const GreaterThanAttributeFilter< EventType, AttributeType > *greater_than_attribute_filter)
const std::vector< AttributeType > get_constants() const
void operator()(const EqualsAttributeFilter< EventType, AttributeType > *equals_predicate, GeneralBooleanExpressionsFilter< EventType, NetworkType > *)
void operator()(const AttributeFilter< EventType, AttributeType > *equals_predicate, DecisionTreeFilter< EventType, NetworkType > *, int)
void operator()(const LessThanAttributeFilter< EventType, AttributeType > *less_than_predicate, GeneralBooleanExpressionsFilter< EventType, NetworkType > *)
PredicateIdentifierFactory::PredicateID addPredicate(const NotEqualsAttributeFilter< EventType, AttributeType > *notequals_attribute_filter)
void operator()(const NotEqualsAttributeFilter< EventType, AttributeType > *notequals_predicate, GeneralBooleanExpressionsFilter< EventType, NetworkType > *)
void operator()(const AttributeFilter< EventType, AttributeType > *, GeneralBooleanExpressionsFilter< EventType, NetworkType > *)
#define M2ETIS_THROW_API(module, message)
throws on wrong API usage
Definition: Exceptions.h:40