diff options
Diffstat (limited to 'fluent-bit/lib/avro/src/datum_equal.c')
-rw-r--r-- | fluent-bit/lib/avro/src/datum_equal.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/fluent-bit/lib/avro/src/datum_equal.c b/fluent-bit/lib/avro/src/datum_equal.c new file mode 100644 index 000000000..2ef750f9b --- /dev/null +++ b/fluent-bit/lib/avro/src/datum_equal.c @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "avro_private.h" +#include <string.h> +#include "datum.h" + +static int +array_equal(struct avro_array_datum_t *a, struct avro_array_datum_t *b) +{ + if (!avro_schema_equal(a->schema, b->schema)) { + return 0; + } + + long i; + + if (a->els->num_entries != b->els->num_entries) { + return 0; + } + for (i = 0; i < a->els->num_entries; i++) { + union { + st_data_t data; + avro_datum_t datum; + } ael, bel; + st_lookup(a->els, i, &ael.data); + st_lookup(b->els, i, &bel.data); + if (!avro_datum_equal(ael.datum, bel.datum)) { + return 0; + } + } + return 1; +} + +struct st_equal_args { + int rval; + st_table *st; +}; + +static int +st_equal_foreach(char *key, avro_datum_t datum, struct st_equal_args *args) +{ + union { + avro_datum_t datum_other; + st_data_t data; + } val; + if (!st_lookup(args->st, (st_data_t) key, &(val.data))) { + args->rval = 0; + return ST_STOP; + } + if (!avro_datum_equal(datum, val.datum_other)) { + args->rval = 0; + return ST_STOP; + } + return ST_CONTINUE; +} + +static int map_equal(struct avro_map_datum_t *a, struct avro_map_datum_t *b) +{ + if (!avro_schema_equal(a->schema, b->schema)) { + return 0; + } + + struct st_equal_args args = { 1, b->map }; + if (a->map->num_entries != b->map->num_entries) { + return 0; + } + st_foreach(a->map, HASH_FUNCTION_CAST st_equal_foreach, (st_data_t) & args); + return args.rval; +} + +static int record_equal(struct avro_record_datum_t *a, + struct avro_record_datum_t *b) +{ + if (!avro_schema_equal(a->schema, b->schema)) { + return 0; + } + + struct st_equal_args args = { 1, b->fields_byname }; + if (a->fields_byname->num_entries != b->fields_byname->num_entries) { + return 0; + } + st_foreach(a->fields_byname, HASH_FUNCTION_CAST st_equal_foreach, (st_data_t) & args); + return args.rval; +} + +static int enum_equal(struct avro_enum_datum_t *a, struct avro_enum_datum_t *b) +{ + return avro_schema_equal(a->schema, b->schema) && a->value == b->value; +} + +static int fixed_equal(struct avro_fixed_datum_t *a, + struct avro_fixed_datum_t *b) +{ + if (!avro_schema_equal(a->schema, b->schema)) { + return 0; + } + + return a->size == b->size && memcmp(a->bytes, b->bytes, a->size) == 0; +} + +static int union_equal(struct avro_union_datum_t *a, + struct avro_union_datum_t *b) +{ + if (!avro_schema_equal(a->schema, b->schema)) { + return 0; + } + + return a->discriminant == b->discriminant && avro_datum_equal(a->value, b->value); +} + +int avro_datum_equal(const avro_datum_t a, const avro_datum_t b) +{ + if (!(is_avro_datum(a) && is_avro_datum(b))) { + return 0; + } + if (avro_typeof(a) != avro_typeof(b)) { + return 0; + } + switch (avro_typeof(a)) { + case AVRO_STRING: + return strcmp(avro_datum_to_string(a)->s, + avro_datum_to_string(b)->s) == 0; + case AVRO_BYTES: + return (avro_datum_to_bytes(a)->size == + avro_datum_to_bytes(b)->size) + && memcmp(avro_datum_to_bytes(a)->bytes, + avro_datum_to_bytes(b)->bytes, + avro_datum_to_bytes(a)->size) == 0; + case AVRO_INT32: + return avro_datum_to_int32(a)->i32 == + avro_datum_to_int32(b)->i32; + case AVRO_INT64: + return avro_datum_to_int64(a)->i64 == + avro_datum_to_int64(b)->i64; + case AVRO_FLOAT: + return avro_datum_to_float(a)->f == avro_datum_to_float(b)->f; + case AVRO_DOUBLE: + return avro_datum_to_double(a)->d == avro_datum_to_double(b)->d; + case AVRO_BOOLEAN: + return avro_datum_to_boolean(a)->i == + avro_datum_to_boolean(b)->i; + case AVRO_NULL: + return 1; + case AVRO_ARRAY: + return array_equal(avro_datum_to_array(a), + avro_datum_to_array(b)); + case AVRO_MAP: + return map_equal(avro_datum_to_map(a), avro_datum_to_map(b)); + + case AVRO_RECORD: + return record_equal(avro_datum_to_record(a), + avro_datum_to_record(b)); + + case AVRO_ENUM: + return enum_equal(avro_datum_to_enum(a), avro_datum_to_enum(b)); + + case AVRO_FIXED: + return fixed_equal(avro_datum_to_fixed(a), + avro_datum_to_fixed(b)); + + case AVRO_UNION: + return union_equal(avro_datum_to_union(a), + avro_datum_to_union(b)); + + case AVRO_LINK: + /* + * TODO + */ + return 0; + } + return 0; +} |