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));