17 #ifndef AVRODATUMSCOMPARATOR_HPP_
18 #define AVRODATUMSCOMPARATOR_HPP_
22 #ifdef KAA_USE_CONFIGURATION
24 #include <avro/Generic.hh>
31 struct avro_comparator {
33 bool operator ()(
const avro::GenericDatum &left,
const avro::GenericDatum &right)
35 return compareDatumsLess(left, right);
40 bool compareDatumsLess(
const avro::GenericDatum &left,
const avro::GenericDatum &right)
42 int ltype = left.type(), rtype = right.type();
44 if (avro::Type::AVRO_RECORD > avro::Type::AVRO_STRING) {
45 if (ltype < avro::Type::AVRO_RECORD) {
46 ltype += avro::Type::AVRO_RECORD;
48 ltype -= avro::Type::AVRO_RECORD;
51 if (rtype < avro::Type::AVRO_RECORD) {
52 rtype += avro::Type::AVRO_RECORD;
54 rtype -= avro::Type::AVRO_RECORD;
60 avro::Type type = left.type();
62 case avro::Type::AVRO_STRING:
63 return std::less<std::string>()(left.value<std::string>(), right.value<std::string>());
64 case avro::Type::AVRO_INT:
65 return std::less<std::int32_t>()(left.value<std::int32_t>(), right.value<std::int32_t>());
66 case avro::Type::AVRO_LONG:
67 return std::less<std::int64_t>()(left.value<std::int64_t>(), right.value<std::int64_t>());
68 case avro::Type::AVRO_FLOAT:
69 return std::less<float>()(left.value<
float>(), right.value<
float>());
70 case avro::Type::AVRO_DOUBLE:
71 return std::less<double>()(left.value<
double>(), right.value<
double>());
72 case avro::Type::AVRO_BOOL:
73 return std::less<bool>()(left.value<
bool>(), right.value<
bool>());
74 case avro::Type::AVRO_BYTES: {
75 std::vector<std::uint8_t> l_vec = left.value<std::vector<std::uint8_t> >();
76 std::vector<std::uint8_t> r_vec = right.value<std::vector<std::uint8_t> >();
77 return std::less<std::vector<std::uint8_t> >()(l_vec, r_vec);
80 case avro::Type::AVRO_RECORD: {
81 const avro::GenericRecord &leftRecord = left.value<avro::GenericRecord>();
82 const avro::GenericRecord &rightRecord = right.value<avro::GenericRecord>();
84 size_t leftFieldCount = leftRecord.schema()->names();
85 size_t rightFieldCount = rightRecord.schema()->names();
86 if (leftFieldCount != rightFieldCount) {
87 throw KaaException(
"Can not compare records with different count of fields");
90 for (
size_t l = 0; l < leftFieldCount; ++l) {
91 std::string fieldName = leftRecord.schema()->nameAt(l);
92 bool isLess = compareDatumsLess(leftRecord.field(fieldName), rightRecord.field(fieldName));
93 if ( !(!isLess && !compareDatumsLess(rightRecord.field(fieldName), leftRecord.field(fieldName)))) {
99 case avro::Type::AVRO_ENUM: {
100 return left.value<avro::GenericEnum>().value() < right.value<avro::GenericEnum>().value();
102 case avro::Type::AVRO_ARRAY: {
103 const avro::GenericArray &leftArray = left.value<avro::GenericArray>();
104 const avro::GenericArray &rightArray = right.value<avro::GenericArray>();
105 const avro::GenericArray::Value l_value = leftArray.value();
106 const avro::GenericArray::Value r_value = rightArray.value();
107 for (
size_t l = 0, r = 0; l < l_value.size() && r < r_value.size(); ++l, ++r) {
108 bool isLess = compareDatumsLess(l_value[l], r_value[r]);
109 if (!(!isLess && !compareDatumsLess(r_value[r], l_value[l]))) {
113 return l_value.size() > r_value.size();
116 case avro::Type::AVRO_FIXED: {
117 std::vector<std::uint8_t> l_vec = left.value<avro::GenericFixed>().value();
118 std::vector<std::uint8_t> r_vec = right.value<avro::GenericFixed>().value();
119 return std::less<std::vector<std::uint8_t> >()(l_vec, r_vec);
122 case avro::Type::AVRO_NULL:
125 case avro::Type::AVRO_MAP:
126 case avro::Type::AVRO_UNION:
128 throw KaaException(boost::format(
"Can not compare datums of \"%1%\" type") % avro::toString(type));