Repository: ignite Updated Branches: refs/heads/ignite-3191 [created] 3bb95531a
IGNITE-3191 - Consistent fields ordering in binary objects Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3bb95531 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3bb95531 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3bb95531 Branch: refs/heads/ignite-3191 Commit: 3bb95531a00f141de6f7e15695f36dac5bebd19d Parents: 98914fe Author: Valentin Kulichenko <valentin.luliche...@gmail.com> Authored: Wed Sep 14 16:06:27 2016 -0700 Committer: Valentin Kulichenko <valentin.luliche...@gmail.com> Committed: Wed Sep 14 16:06:27 2016 -0700 ---------------------------------------------------------------------- .../internal/binary/BinaryClassDescriptor.java | 16 ++-- .../binary/builder/BinaryObjectBuilderImpl.java | 24 ++--- .../binary/BinaryFieldOrderSelfTest.java | 93 ++++++++++++++++++++ .../IgniteBinaryObjectsTestSuite.java | 2 + 4 files changed, 116 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/3bb95531/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java index 083057d..830f04d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java @@ -25,7 +25,6 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.math.BigDecimal; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -33,6 +32,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import java.util.UUID; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryObjectException; @@ -263,10 +263,9 @@ public class BinaryClassDescriptor { case OBJECT: // Must not use constructor to honor transient fields semantics. ctor = null; - ArrayList<BinaryFieldAccessor> fields0 = new ArrayList<>(); stableFieldsMeta = metaDataEnabled ? new HashMap<String, Integer>() : null; - BinarySchema.Builder schemaBuilder = BinarySchema.Builder.newBuilder(); + Map<String, BinaryFieldAccessor> fields0 = new TreeMap<>(); Set<String> duplicates = duplicateFields(cls); @@ -294,9 +293,7 @@ public class BinaryClassDescriptor { BinaryFieldAccessor fieldInfo = BinaryFieldAccessor.create(f, fieldId); - fields0.add(fieldInfo); - - schemaBuilder.addField(fieldId); + fields0.put(name, fieldInfo); if (metaDataEnabled) stableFieldsMeta.put(name, fieldInfo.mode().typeId()); @@ -304,7 +301,12 @@ public class BinaryClassDescriptor { } } - fields = fields0.toArray(new BinaryFieldAccessor[fields0.size()]); + fields = fields0.values().toArray(new BinaryFieldAccessor[fields0.size()]); + + BinarySchema.Builder schemaBuilder = BinarySchema.Builder.newBuilder(); + + for (BinaryFieldAccessor field : fields) + schemaBuilder.addField(field.id); stableSchema = schemaBuilder.build(); http://git-wip-us.apache.org/repos/asf/ignite/blob/3bb95531/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java index 086da5c..9b3a79c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java @@ -17,32 +17,32 @@ package org.apache.ignite.internal.binary.builder; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; import org.apache.ignite.binary.BinaryInvalidTypeException; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryObjectBuilder; import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.binary.BinaryType; +import org.apache.ignite.internal.binary.BinaryContext; import org.apache.ignite.internal.binary.BinaryMetadata; import org.apache.ignite.internal.binary.BinaryObjectImpl; -import org.apache.ignite.internal.binary.BinaryWriterExImpl; -import org.apache.ignite.internal.binary.GridBinaryMarshaller; -import org.apache.ignite.internal.binary.BinaryContext; +import org.apache.ignite.internal.binary.BinaryObjectOffheapImpl; import org.apache.ignite.internal.binary.BinarySchema; import org.apache.ignite.internal.binary.BinarySchemaRegistry; -import org.apache.ignite.internal.binary.BinaryObjectOffheapImpl; import org.apache.ignite.internal.binary.BinaryUtils; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; +import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - /** * */ @@ -515,7 +515,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { Object val = val0 == null ? new BinaryValueWithType(BinaryUtils.typeByClass(Object.class), null) : val0; if (assignedVals == null) - assignedVals = new LinkedHashMap<>(); + assignedVals = new TreeMap<>(); Object oldVal = assignedVals.put(name, val); http://git-wip-us.apache.org/repos/asf/ignite/blob/3bb95531/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldOrderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldOrderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldOrderSelfTest.java new file mode 100644 index 0000000..5e2242c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldOrderSelfTest.java @@ -0,0 +1,93 @@ +package org.apache.ignite.internal.binary; + +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Test that field ordering doesn't change the schema. + */ +public class BinaryFieldOrderSelfTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + cfg.setMarshaller(new BinaryMarshaller()); + cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true))); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + startGrid(); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + } + + /** + * @throws Exception If failed. + */ + public void testEquals() throws Exception { + IgniteEx ignite = grid(); + + BinaryObject bo0 = ignite.binary().toBinary(new MyType(222, 333, 111)); + + BinaryObject bo1 = ignite.binary().builder(bo0.type().typeName()). + setField("b", 222). + setField("c", 333). + setField("a", 111). + hashCode(12345). + build(); + + BinaryObject bo2 = ignite.binary().builder(bo0.type().typeName()). + setField("a", 111). + setField("b", 222). + setField("c", 333). + hashCode(12345). + build(); + + assertEquals(12345, bo0.hashCode()); + assertEquals(12345, bo1.hashCode()); + assertEquals(12345, bo2.hashCode()); + + assertTrue(bo0.equals(bo1)); + assertTrue(bo0.equals(bo2)); + assertTrue(bo1.equals(bo2)); + } + + /** + */ + private static class MyType { + /** B. */ + private int b; + + /** C. */ + private int c; + + /** A. */ + private int a; + + /** + * @param b B. + * @param c C. + * @param a A. + */ + MyType(int b, int c, int a) { + this.b = b; + this.c = c; + this.a = a; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return 12345; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/3bb95531/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java index dc0540d..afab08b 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java @@ -22,6 +22,7 @@ import org.apache.ignite.internal.binary.BinaryBasicIdMapperSelfTest; import org.apache.ignite.internal.binary.BinaryBasicNameMapperSelfTest; import org.apache.ignite.internal.binary.BinaryConfigurationConsistencySelfTest; import org.apache.ignite.internal.binary.BinaryEnumsSelfTest; +import org.apache.ignite.internal.binary.BinaryFieldOrderSelfTest; import org.apache.ignite.internal.binary.BinaryFieldsHeapSelfTest; import org.apache.ignite.internal.binary.BinaryFieldsOffheapSelfTest; import org.apache.ignite.internal.binary.BinaryFooterOffsetsHeapSelfTest; @@ -102,6 +103,7 @@ public class IgniteBinaryObjectsTestSuite extends TestSuite { suite.addTestSuite(GridSimpleLowerCaseBinaryMappersBinaryMetaDataSelfTest.class); suite.addTestSuite(GridBinaryAffinityKeySelfTest.class); suite.addTestSuite(GridBinaryWildcardsSelfTest.class); + suite.addTestSuite(BinaryFieldOrderSelfTest.class); // Tests for objects with non-compact footers. suite.addTestSuite(BinaryMarshallerNonCompactSelfTest.class);