You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by dc...@apache.org on 2011/10/15 15:38:44 UTC
svn commit: r1183638 - in /avro/trunk: CHANGES.txt lang/c/src/avro/value.h
lang/c/src/value.c lang/c/tests/test_avro_values.c
Author: dcreager
Date: Sat Oct 15 13:38:44 2011
New Revision: 1183638
URL: http://svn.apache.org/viewvc?rev=1183638&view=rev
Log:
AVRO-922. C: Value comparison function
This patch adds the avro_value_cmp and avro_value_cmp_fast functions,
which compare two avro_value_t instances using the sort order from the
Avro specification. Like the avro_value_equal and avro_value_copy
methods, we don't require the two values to have the same value
implementation, but they do need to be instances of the same schema.
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/c/src/avro/value.h
avro/trunk/lang/c/src/value.c
avro/trunk/lang/c/tests/test_avro_values.c
Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1183638&r1=1183637&r2=1183638&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Sat Oct 15 13:38:44 2011
@@ -33,6 +33,8 @@ Avro 1.6.0 (unreleased)
AVRO-921. C: Default wrapped buffer implementation is zero-copy.
(dcreager)
+ AVRO-922. C: Comparison function for new value interface. (dcreager)
+
AVRO-890: Java: Add Maven archetype for creating Avro service
projects. (Stephen Gargan via cutting)
Modified: avro/trunk/lang/c/src/avro/value.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/avro/value.h?rev=1183638&r1=1183637&r2=1183638&view=diff
==============================================================================
--- avro/trunk/lang/c/src/avro/value.h (original)
+++ avro/trunk/lang/c/src/avro/value.h Sat Oct 15 13:38:44 2011
@@ -325,6 +325,33 @@ int
avro_value_equal_fast(avro_value_t *val1, avro_value_t *val2);
/**
+ * Compares two values using the sort order defined in the Avro
+ * specification. The two values don't need to have the same
+ * implementation of the value interface, but they do need to represent
+ * Avro values of the same schema. This function ensures that the
+ * schemas match; if you want to skip this check, use
+ * avro_value_cmp_fast.
+ */
+
+int
+avro_value_cmp(avro_value_t *val1, avro_value_t *val2);
+
+/**
+ * Compares two values using the sort order defined in the Avro
+ * specification. The two values don't need to have the same
+ * implementation of the value interface, but they do need to represent
+ * Avro values of the same schema. This function assumes that the
+ * schemas match; if you can't guarantee this, you should use
+ * avro_value_cmp, which compares the schemas before comparing the
+ * values.
+ */
+
+int
+avro_value_cmp_fast(avro_value_t *val1, avro_value_t *val2);
+
+
+
+/**
* Copies the contents of src into dest. The two values don't need to
* have the same implementation of the value interface, but they do need
* to represent Avro values of the same schema. This function ensures
Modified: avro/trunk/lang/c/src/value.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/value.c?rev=1183638&r1=1183637&r2=1183638&view=diff
==============================================================================
--- avro/trunk/lang/c/src/value.c (original)
+++ avro/trunk/lang/c/src/value.c Sat Oct 15 13:38:44 2011
@@ -289,6 +289,225 @@ avro_value_equal(avro_value_t *val1, avr
}
+#define cmp(v1, v2) \
+ (((v1) == (v2))? 0: \
+ ((v1) < (v2))? -1: 1)
+int
+avro_value_cmp_fast(avro_value_t *val1, avro_value_t *val2)
+{
+ avro_type_t type1 = avro_value_get_type(val1);
+ avro_type_t type2 = avro_value_get_type(val2);
+ if (type1 != type2) {
+ return -1;
+ }
+
+ switch (type1) {
+ case AVRO_BOOLEAN:
+ {
+ int v1;
+ int v2;
+ check_return(0, avro_value_get_boolean(val1, &v1));
+ check_return(0, avro_value_get_boolean(val2, &v2));
+ return cmp(!!v1, !!v2);
+ }
+
+ case AVRO_BYTES:
+ {
+ const void *buf1;
+ const void *buf2;
+ size_t size1;
+ size_t size2;
+ size_t min_size;
+ int result;
+
+ check_return(0, avro_value_get_bytes(val1, &buf1, &size1));
+ check_return(0, avro_value_get_bytes(val2, &buf2, &size2));
+
+ min_size = (size1 < size2)? size1: size2;
+ result = memcmp(buf1, buf2, min_size);
+ if (result != 0) {
+ return result;
+ } else {
+ return cmp(size1, size2);
+ }
+ }
+
+ case AVRO_DOUBLE:
+ {
+ double v1;
+ double v2;
+ check_return(0, avro_value_get_double(val1, &v1));
+ check_return(0, avro_value_get_double(val2, &v2));
+ return cmp(v1, v2);
+ }
+
+ case AVRO_FLOAT:
+ {
+ float v1;
+ float v2;
+ check_return(0, avro_value_get_float(val1, &v1));
+ check_return(0, avro_value_get_float(val2, &v2));
+ return cmp(v1, v2);
+ }
+
+ case AVRO_INT32:
+ {
+ int32_t v1;
+ int32_t v2;
+ check_return(0, avro_value_get_int(val1, &v1));
+ check_return(0, avro_value_get_int(val2, &v2));
+ return cmp(v1, v2);
+ }
+
+ case AVRO_INT64:
+ {
+ int64_t v1;
+ int64_t v2;
+ check_return(0, avro_value_get_long(val1, &v1));
+ check_return(0, avro_value_get_long(val2, &v2));
+ return cmp(v1, v2);
+ }
+
+ case AVRO_NULL:
+ {
+ check_return(0, avro_value_get_null(val1));
+ check_return(0, avro_value_get_null(val2));
+ return 0;
+ }
+
+ case AVRO_STRING:
+ {
+ const char *buf1;
+ const char *buf2;
+ size_t size1;
+ size_t size2;
+ size_t min_size;
+ int result;
+
+ min_size = (size1 < size2)? size1: size2;
+ result = memcmp(buf1, buf2, min_size);
+ if (result != 0) {
+ return result;
+ } else {
+ return cmp(size1, size2);
+ }
+ }
+
+ case AVRO_ARRAY:
+ {
+ size_t count1;
+ size_t count2;
+ size_t min_count;
+ size_t i;
+ check_return(0, avro_value_get_size(val1, &count1));
+ check_return(0, avro_value_get_size(val2, &count2));
+
+ min_count = (count1 < count2)? count1: count2;
+ for (i = 0; i < min_count; i++) {
+ avro_value_t child1;
+ avro_value_t child2;
+ int result;
+ check_return(0, avro_value_get_by_index
+ (val1, i, &child1, NULL));
+ check_return(0, avro_value_get_by_index
+ (val2, i, &child2, NULL));
+ result = avro_value_cmp_fast(&child1, &child2);
+ if (result != 0) {
+ return result;
+ }
+ }
+
+ return cmp(count1, count2);
+ }
+
+ case AVRO_ENUM:
+ {
+ int v1;
+ int v2;
+ check_return(0, avro_value_get_enum(val1, &v1));
+ check_return(0, avro_value_get_enum(val2, &v2));
+ return cmp(v1, v2);
+ }
+
+ case AVRO_FIXED:
+ {
+ const void *buf1;
+ const void *buf2;
+ size_t size1;
+ size_t size2;
+ check_return(0, avro_value_get_fixed(val1, &buf1, &size1));
+ check_return(0, avro_value_get_fixed(val2, &buf2, &size2));
+ if (size1 != size2) {
+ return -1;
+ }
+ return memcmp(buf1, buf2, size1);
+ }
+
+ case AVRO_MAP:
+ {
+ return -1;
+ }
+
+ case AVRO_RECORD:
+ {
+ size_t count1;
+ check_return(0, avro_value_get_size(val1, &count1));
+
+ size_t i;
+ for (i = 0; i < count1; i++) {
+ avro_value_t child1;
+ avro_value_t child2;
+ int result;
+
+ check_return(0, avro_value_get_by_index
+ (val1, i, &child1, NULL));
+ check_return(0, avro_value_get_by_index
+ (val2, i, &child2, NULL));
+ result = avro_value_cmp_fast(&child1, &child2);
+ if (result != 0) {
+ return result;
+ }
+ }
+
+ return 0;
+ }
+
+ case AVRO_UNION:
+ {
+ int disc1;
+ int disc2;
+ check_return(0, avro_value_get_discriminant(val1, &disc1));
+ check_return(0, avro_value_get_discriminant(val2, &disc2));
+
+ if (disc1 == disc2) {
+ avro_value_t branch1;
+ avro_value_t branch2;
+ check_return(0, avro_value_get_current_branch(val1, &branch1));
+ check_return(0, avro_value_get_current_branch(val2, &branch2));
+ return avro_value_cmp_fast(&branch1, &branch2);
+ } else {
+ return cmp(disc1, disc2);
+ }
+ }
+
+ default:
+ return 0;
+ }
+}
+
+int
+avro_value_cmp(avro_value_t *val1, avro_value_t *val2)
+{
+ avro_schema_t schema1 = avro_value_get_schema(val1);
+ avro_schema_t schema2 = avro_value_get_schema(val2);
+ if (!avro_schema_equal(schema1, schema2)) {
+ return 0;
+ }
+
+ return avro_value_cmp_fast(val1, val2);
+}
+
+
int
avro_value_copy_fast(avro_value_t *dest, const avro_value_t *src)
{
Modified: avro/trunk/lang/c/tests/test_avro_values.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_avro_values.c?rev=1183638&r1=1183637&r2=1183638&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_values.c (original)
+++ avro/trunk/lang/c/tests/test_avro_values.c Sat Oct 15 13:38:44 2011
@@ -422,6 +422,28 @@ test_boolean(void)
check_copy(&val);
avro_value_decref(&val);
}
+
+ avro_value_t val1;
+ avro_value_t val2;
+ try(avro_generic_boolean_new(&val1, 0),
+ "Cannot create boolean");
+ try(avro_generic_boolean_new(&val2, 1),
+ "Cannot create boolean");
+ if (avro_value_cmp_fast(&val1, &val2) != -1) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ if (avro_value_cmp_fast(&val2, &val1) != 1) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ if (avro_value_cmp_fast(&val1, &val1) != 0) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ avro_value_decref(&val1);
+ avro_value_decref(&val2);
+
return 0;
}
@@ -478,6 +500,36 @@ test_bytes(void)
check_write_read(&val);
check_copy(&val);
avro_value_decref(&val);
+
+ avro_value_t val1;
+ avro_value_t val2;
+ avro_value_t val3;
+ try(avro_generic_bytes_new(&val1, "abcd", 4),
+ "Cannot create bytes");
+ try(avro_generic_bytes_new(&val2, "abcde", 5),
+ "Cannot create bytes");
+ try(avro_generic_bytes_new(&val3, "abce", 4),
+ "Cannot create bytes");
+ if (avro_value_cmp_fast(&val1, &val2) != -1) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ if (avro_value_cmp_fast(&val2, &val1) != 1) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ if (avro_value_cmp_fast(&val1, &val3) != -1) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ if (avro_value_cmp_fast(&val1, &val1) != 0) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ avro_value_decref(&val1);
+ avro_value_decref(&val2);
+ avro_value_decref(&val3);
+
return 0;
}
@@ -586,6 +638,28 @@ test_int(void)
check_copy(&val);
avro_value_decref(&val);
}
+
+ avro_value_t val1;
+ avro_value_t val2;
+ try(avro_generic_int_new(&val1, -10),
+ "Cannot create int");
+ try(avro_generic_int_new(&val2, 42),
+ "Cannot create int");
+ if (avro_value_cmp_fast(&val1, &val2) != -1) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ if (avro_value_cmp_fast(&val2, &val1) != 1) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ if (avro_value_cmp_fast(&val1, &val1) != 0) {
+ fprintf(stderr, "Incorrect sort order\n");
+ return EXIT_FAILURE;
+ }
+ avro_value_decref(&val1);
+ avro_value_decref(&val2);
+
return 0;
}