client-cpp  0.0.1-SNAPSHOT
AvroDatumsComparator.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014 CyberVision, Inc.
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 #ifndef AVRODATUMSCOMPARATOR_HPP_
18 #define AVRODATUMSCOMPARATOR_HPP_
19 
20 #include <avro/Generic.hh>
21 #include <boost/cstdint.hpp>
22 
24 
25 namespace kaa {
26 
28 
29 bool operator ()(const avro::GenericDatum &left, const avro::GenericDatum &right)
30 {
31  return compareDatumsLess(left, right);
32 }
33 
34 private:
35 
36 bool compareDatumsLess(const avro::GenericDatum &left, const avro::GenericDatum &right)
37 {
38  int ltype = left.type(), rtype = right.type();
39  if (ltype != rtype) {
40  if (avro::Type::AVRO_RECORD > avro::Type::AVRO_STRING) {
41  if (ltype < avro::Type::AVRO_RECORD) {
42  ltype += avro::Type::AVRO_RECORD;
43  } else {
44  ltype -= avro::Type::AVRO_RECORD;
45  }
46 
47  if (rtype < avro::Type::AVRO_RECORD) {
48  rtype += avro::Type::AVRO_RECORD;
49  } else {
50  rtype -= avro::Type::AVRO_RECORD;
51  }
52  }
53 
54  return ltype < rtype;
55  }
56  avro::Type type = left.type();
57  switch (type) {
58  case avro::Type::AVRO_STRING:
59  return std::less<std::string>()(left.value<std::string>(), right.value<std::string>());
60  case avro::Type::AVRO_INT:
61  return std::less<boost::int32_t>()(left.value<boost::int32_t>(), right.value<boost::int32_t>());
62  case avro::Type::AVRO_LONG:
63  return std::less<boost::int64_t>()(left.value<boost::int64_t>(), right.value<boost::int64_t>());
64  case avro::Type::AVRO_FLOAT:
65  return std::less<float>()(left.value<float>(), right.value<float>());
66  case avro::Type::AVRO_DOUBLE:
67  return std::less<double>()(left.value<double>(), right.value<double>());
68  case avro::Type::AVRO_BOOL:
69  return std::less<bool>()(left.value<bool>(), right.value<bool>());
70  case avro::Type::AVRO_BYTES: {
71  std::vector<boost::uint8_t> l_vec = left.value<std::vector<boost::uint8_t> >();
72  std::vector<boost::uint8_t> r_vec = right.value<std::vector<boost::uint8_t> >();
73  return std::less<std::vector<boost::uint8_t> >()(l_vec, r_vec);
74  }
75 
76  case avro::Type::AVRO_RECORD: {
77  const avro::GenericRecord &leftRecord = left.value<avro::GenericRecord>();
78  const avro::GenericRecord &rightRecord = right.value<avro::GenericRecord>();
79 
80  size_t leftFieldCount = leftRecord.schema()->names();
81  size_t rightFieldCount = rightRecord.schema()->names();
82  if (leftFieldCount != rightFieldCount) {
83  throw KaaException("Can not compare records with different count of fields");
84  }
85 
86  for (size_t l = 0; l < leftFieldCount; ++l) {
87  std::string fieldName = leftRecord.schema()->nameAt(l);
88  bool isLess = compareDatumsLess(leftRecord.field(fieldName), rightRecord.field(fieldName));
89  if ( !(!isLess && !compareDatumsLess(rightRecord.field(fieldName), leftRecord.field(fieldName)))) {
90  return isLess;
91  }
92  }
93  return false;
94  }
95  case avro::Type::AVRO_ENUM: {
96  return left.value<avro::GenericEnum>().value() < right.value<avro::GenericEnum>().value();
97  }
98  case avro::Type::AVRO_ARRAY: {
99  const avro::GenericArray &leftArray = left.value<avro::GenericArray>();
100  const avro::GenericArray &rightArray = right.value<avro::GenericArray>();
101  const avro::GenericArray::Value l_value = leftArray.value();
102  const avro::GenericArray::Value r_value = rightArray.value();
103  for (size_t l = 0, r = 0; l < l_value.size() && r < r_value.size(); ++l, ++r) {
104  bool isLess = compareDatumsLess(l_value[l], r_value[r]);
105  if (!(!isLess && !compareDatumsLess(r_value[r], l_value[l]))) {
106  return isLess;
107  }
108  }
109  return l_value.size() > r_value.size();
110  }
111 
112  case avro::Type::AVRO_FIXED: {
113  std::vector<boost::uint8_t> l_vec = left.value<avro::GenericFixed>().value();
114  std::vector<boost::uint8_t> r_vec = right.value<avro::GenericFixed>().value();
115  return std::less<std::vector<boost::uint8_t> >()(l_vec, r_vec);
116  }
117 
118  case avro::Type::AVRO_NULL:
119  return false;
120 
121  case avro::Type::AVRO_MAP:
122  case avro::Type::AVRO_UNION:
123  default:
124  throw KaaException(boost::format("Can not compare datums of \"%1%\" type") % avro::toString(type));
125  }
126 }
127 
128 };
129 
130 } // namespace kaa
131 
132 
133 #endif /* AVRODATUMSCOMPARATOR_HPP_ */
bool operator()(const avro::GenericDatum &left, const avro::GenericDatum &right)