NIFI-5800: Do not recursively call hashCode on child schema for Record Field Types

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #3157.
This commit is contained in:
Mark Payne 2018-11-07 17:00:51 -05:00 committed by Pierre Villard
parent 5cf58b42e0
commit a9045d54a1
3 changed files with 34 additions and 6 deletions

View File

@ -40,6 +40,7 @@ public class SimpleRecordSchema implements RecordSchema {
private final SchemaIdentifier schemaIdentifier;
private String schemaName;
private String schemaNamespace;
private volatile int hashCode;
public SimpleRecordSchema(final List<RecordField> fields) {
this(fields, createText(fields), null, false, SchemaIdentifier.EMPTY);
@ -171,7 +172,12 @@ public class SimpleRecordSchema implements RecordSchema {
@Override
public int hashCode() {
return 143 + 3 * fields.hashCode();
int computed = this.hashCode;
if (computed == 0) {
computed = this.hashCode = 143 + 3 * fields.hashCode();
}
return computed;
}
private static String createText(final List<RecordField> fields) {

View File

@ -42,7 +42,7 @@ public class RecordDataType extends DataType {
@Override
public int hashCode() {
return 31 + 41 * getFieldType().hashCode() + 41 * (childSchema == null ? 0 : childSchema.hashCode());
return 31 + 41 * getFieldType().hashCode();
}
@Override

View File

@ -17,15 +17,18 @@
package org.apache.nifi.serialization;
import org.apache.nifi.serialization.record.RecordField;
import org.apache.nifi.serialization.record.RecordFieldType;
import org.apache.nifi.serialization.record.SchemaIdentifier;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.nifi.serialization.record.RecordField;
import org.apache.nifi.serialization.record.RecordFieldType;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class TestSimpleRecordSchema {
@ -68,6 +71,25 @@ public class TestSimpleRecordSchema {
}
}
@Test
public void testHashCodeAndEqualsWithSelfReferencingSchema() {
final SimpleRecordSchema schema = new SimpleRecordSchema(SchemaIdentifier.EMPTY);
final List<RecordField> personFields = new ArrayList<>();
personFields.add(new RecordField("name", RecordFieldType.STRING.getDataType()));
personFields.add(new RecordField("sibling", RecordFieldType.RECORD.getRecordDataType(schema)));
schema.setFields(personFields);
schema.hashCode();
assertTrue(schema.equals(schema));
final SimpleRecordSchema secondSchema = new SimpleRecordSchema(SchemaIdentifier.EMPTY);
secondSchema.setFields(personFields);
assertTrue(schema.equals(secondSchema));
assertTrue(secondSchema.equals(schema));
}
private Set<String> set(final String... values) {
final Set<String> set = new HashSet<>();
for (final String value : values) {