Return-Path: X-Original-To: apmail-ignite-commits-archive@minotaur.apache.org Delivered-To: apmail-ignite-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9B74B182B1 for ; Wed, 3 Feb 2016 12:40:13 +0000 (UTC) Received: (qmail 60242 invoked by uid 500); 3 Feb 2016 12:33:27 -0000 Delivered-To: apmail-ignite-commits-archive@ignite.apache.org Received: (qmail 60147 invoked by uid 500); 3 Feb 2016 12:33:27 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 59982 invoked by uid 99); 3 Feb 2016 12:33:26 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Feb 2016 12:33:26 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id AF85ADFC8F; Wed, 3 Feb 2016 12:33:26 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: agoncharuk@apache.org To: commits@ignite.apache.org Date: Wed, 03 Feb 2016 12:33:30 -0000 Message-Id: <1925b7e03452493bb3006da67ef15314@git.apache.org> In-Reply-To: <982b9dd1b3bf477ca219fd0f9d5447ef@git.apache.org> References: <982b9dd1b3bf477ca219fd0f9d5447ef@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [5/7] ignite git commit: IGNITE-2191 - Support classes with the same simple name for Binary marshaller - Fixes #398. IGNITE-2191 - Support classes with the same simple name for Binary marshaller - Fixes #398. Signed-off-by: Alexey Goncharuk Conflicts: modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8a52b365 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8a52b365 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8a52b365 Branch: refs/heads/ignite-1.5.7 Commit: 8a52b36549f0ac0942769041828b6da6887d7608 Parents: 1ce45a2 Author: ashutak Authored: Mon Feb 1 18:12:03 2016 +0300 Committer: Alexey Goncharuk Committed: Wed Feb 3 15:14:47 2016 +0300 ---------------------------------------------------------------------- .../ignite/binary/BinaryBasicIdMapper.java | 167 +++ .../ignite/binary/BinaryBasicNameMapper.java | 141 +++ .../apache/ignite/binary/BinaryIdMapper.java | 19 +- .../apache/ignite/binary/BinaryNameMapper.java | 47 + .../ignite/binary/BinaryTypeConfiguration.java | 23 +- .../configuration/BinaryConfiguration.java | 28 + .../configuration/IgniteConfiguration.java | 8 +- .../ignite/internal/IgniteNodeAttributes.java | 3 + .../internal/binary/BinaryClassDescriptor.java | 34 +- .../ignite/internal/binary/BinaryContext.java | 347 ++++-- .../internal/binary/BinaryEnumObjectImpl.java | 11 +- .../internal/binary/BinaryInternalIdMapper.java | 161 --- .../internal/binary/BinaryInternalMapper.java | 131 ++ .../binary/BinaryMetadataCollector.java | 22 +- .../internal/binary/BinaryReaderExImpl.java | 14 +- .../internal/binary/BinaryWriterExImpl.java | 30 +- .../binary/builder/BinaryBuilderSerializer.java | 16 +- .../binary/builder/BinaryObjectBuilderImpl.java | 2 +- .../binary/CacheObjectBinaryProcessorImpl.java | 123 +- .../cpp/PlatformCppConfigurationClosure.java | 32 + .../PlatformDotNetConfigurationClosure.java | 34 +- .../binary/BinaryBasicIdMapperSelfTest.java | 51 + .../binary/BinaryBasicNameMapperSelfTest.java | 50 + .../BinaryConfigurationConsistencySelfTest.java | 231 ++++ .../internal/binary/BinaryEnumsSelfTest.java | 12 +- .../binary/BinaryMarshallerSelfTest.java | 508 ++++++-- .../BinaryObjectBuilderAdditionalSelfTest.java | 4 +- ...naryObjectBuilderDefaultMappersSelfTest.java | 1149 ++++++++++++++++++ .../binary/BinaryObjectBuilderSelfTest.java | 1108 ----------------- ...ilderSimpleNameLowerCaseMappersSelfTest.java | 41 + .../BinarySimpleNameTestPropertySelfTest.java | 94 ++ .../binary/GridBinaryMetaDataSelfTest.java | 371 ------ .../binary/GridBinaryWildcardsSelfTest.java | 338 +++++- ...aultBinaryMappersBinaryMetaDataSelfTest.java | 389 ++++++ ...CaseBinaryMappersBinaryMetaDataSelfTest.java | 41 + .../internal/binary/TestMappedObject.java | 25 + ...BuilderNonCompactDefaultMappersSelfTest.java | 30 + .../BinaryObjectBuilderNonCompactSelfTest.java | 30 - ...mpactSimpleNameLowerCaseMappersSelfTest.java | 31 + .../GridCacheConditionalDeploymentSelfTest.java | 4 +- .../GridCacheBinaryObjectsAbstractSelfTest.java | 17 +- .../GridCacheBinaryStoreAbstractSelfTest.java | 10 + ...naryStoreBinariesDefaultMappersSelfTest.java | 81 ++ .../GridCacheBinaryStoreBinariesSelfTest.java | 66 - ...yStoreBinariesSimpleNameMappersSelfTest.java | 40 + .../config/GridTestProperties.java | 5 +- .../testframework/junits/GridAbstractTest.java | 23 +- .../ignite/testsuites/IgniteBasicTestSuite.java | 2 +- .../testsuites/IgniteBinaryBasicTestSuite.java | 95 ++ ...ctsSimpleNameMapperComputeGridTestSuite.java | 38 + .../IgniteBinaryObjectsTestSuite.java | 34 +- ...iteBinarySimpleNameMapperBasicTestSuite.java | 38 + ...rySimpleNameMapperCacheFullApiTestSuite.java | 39 + .../IgniteBinaryCacheQueryTestSuite.java | 186 +-- ...narySimpleNameMapperCacheQueryTestSuite.java | 38 + .../Config/Compute/compute-grid2.xml | 21 + .../Config/Compute/compute-grid3.xml | 31 +- .../org/apache/ignite/yardstick/IgniteNode.java | 3 + 58 files changed, 4393 insertions(+), 2274 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicIdMapper.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicIdMapper.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicIdMapper.java new file mode 100644 index 0000000..da31751 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicIdMapper.java @@ -0,0 +1,167 @@ +/* + * 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 + * + * http://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. + */ + +package org.apache.ignite.binary; + +import org.apache.ignite.internal.util.typedef.internal.A; + +/** + * Base binary ID mapper implementation. + */ +public class BinaryBasicIdMapper implements BinaryIdMapper { + /** Default lower case flag setting. */ + public static final boolean DFLT_LOWER_CASE = true; + + /** Maximum lower-case character. */ + private static final char MAX_LOWER_CASE_CHAR = 0x7e; + + /** Cached lower-case characters. */ + private static final char[] LOWER_CASE_CHARS; + + /** */ + private boolean isLowerCase = DFLT_LOWER_CASE; + + /** + * Static initializer. + */ + static { + LOWER_CASE_CHARS = new char[MAX_LOWER_CASE_CHAR + 1]; + + for (char c = 0; c <= MAX_LOWER_CASE_CHAR; c++) + LOWER_CASE_CHARS[c] = Character.toLowerCase(c); + } + + /** + * Default constructor. + */ + public BinaryBasicIdMapper() { + } + + /** + * @param isLowerCase Whether to use strings in lower case or not. + *

+ * Defaults to {@link #DFLT_LOWER_CASE}. + */ + public BinaryBasicIdMapper(boolean isLowerCase) { + this.isLowerCase = isLowerCase; + } + + /** + * Get type ID. + * + * @param typeName Type name. + * @return Type ID. + */ + public int typeId(String typeName) { + A.notNull(typeName, "typeName"); + + int id = isLowerCase ? lowerCaseHashCode(typeName) : typeName.hashCode(); + + if (id != 0) + return id; + else { + throw new BinaryObjectException("Binary ID mapper resolved type ID to zero " + + "(either change type's name or use custom ID mapper) " + + "[name=" + typeName + ", isLowerCase=" + isLowerCase + "]"); + } + } + + /** + * Get field ID. + * + * @param typeId Type ID. + * @param fieldName Field name. + * @return Field ID. + */ + public int fieldId(int typeId, String fieldName) { + A.notNull(fieldName, "fieldName"); + + int id = isLowerCase ? lowerCaseHashCode(fieldName) : fieldName.hashCode(); + + if (id != 0) + return id; + else { + throw new BinaryObjectException("Binary ID mapper resolved field ID to zero " + + "(either change filed's name or use custom ID mapper) " + + "[name=" + fieldName + ", isLowerCase=" + isLowerCase + "]"); + } + } + + /** + * Gets whether to use strings in lower case or not. + * + * @return Whether to use strings in lower case or not. + */ + public boolean isLowerCase() { + return isLowerCase; + } + + /** + * Sets whether to use strings in lower case or not. + * + * @param isLowerCase Whether to use strings in lower case or not. + */ + public void setLowerCase(boolean isLowerCase) { + this.isLowerCase = isLowerCase; + } + + /** + * Routine to calculate string hash code an + * + * @param str String. + * @return Hash code for given string converted to lower case. + */ + private static int lowerCaseHashCode(String str) { + int len = str.length(); + + int h = 0; + + for (int i = 0; i < len; i++) { + int c = str.charAt(i); + + c = c <= MAX_LOWER_CASE_CHAR ? LOWER_CASE_CHARS[c] : Character.toLowerCase(c); + + h = 31 * h + c; + } + + return h; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof BinaryBasicIdMapper)) + return false; + + BinaryBasicIdMapper mapper = (BinaryBasicIdMapper)o; + + return isLowerCase == mapper.isLowerCase; + + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return (isLowerCase ? 1 : 0); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "BinaryBaseIdMapper [isLowerCase=" + isLowerCase + ']'; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicNameMapper.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicNameMapper.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicNameMapper.java new file mode 100644 index 0000000..62420f7 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryBasicNameMapper.java @@ -0,0 +1,141 @@ +/* + * 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 + * + * http://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. + */ + +package org.apache.ignite.binary; + +import org.apache.ignite.internal.util.typedef.internal.A; + +/** + * Base binary name mapper implementation. + */ +public class BinaryBasicNameMapper implements BinaryNameMapper { + /** Default use simple name flag setting. */ + public static final boolean DFLT_SIMPLE_NAME = false; + + /** */ + private boolean isSimpleName = DFLT_SIMPLE_NAME; + + /** + * Default constructor. + */ + public BinaryBasicNameMapper() { + // No-op. + } + + /** + * @param isSimpleName Whether to use simple name of class or not. + *

+ * Defaults to {@link #DFLT_SIMPLE_NAME}. + */ + public BinaryBasicNameMapper(boolean isSimpleName) { + this.isSimpleName = isSimpleName; + } + + /** + * Gets whether to use simple name of class or not. + * + * @return Whether to use simple name of class or not. + */ + public boolean isSimpleName() { + return isSimpleName; + } + + /** + * Sets whether to use simple name of class or not. + * + * @param isSimpleName Whether to use simple name of class or not. + */ + public void setLowerCase(boolean isSimpleName) { + this.isSimpleName = isSimpleName; + } + + /** {@inheritDoc} */ + @Override public String typeName(String clsName) { + A.notNull(clsName, "clsName"); + + return isSimpleName ? simpleName(clsName) : clsName; + } + + /** {@inheritDoc} */ + @Override public String fieldName(String fieldName) { + A.notNull(fieldName, "fieldName"); + + return fieldName; + } + + /** + * @param clsName Class name. + * @return Type name. + */ + private static String simpleName(String clsName) { + assert clsName != null; + + int idx = clsName.lastIndexOf('$'); + + if (idx == clsName.length() - 1) + // This is a regular (not inner) class name that ends with '$'. Common use case for Scala classes. + idx = -1; + else if (idx >= 0) { + String typeName = clsName.substring(idx + 1); + + try { + Integer.parseInt(typeName); + + // This is an anonymous class. Don't cut off enclosing class name for it. + idx = -1; + } + catch (NumberFormatException ignore) { + // This is a lambda class. + if (clsName.indexOf("$$Lambda$") > 0) + idx = -1; + else + return typeName; + } + } + + if (idx < 0) + idx = clsName.lastIndexOf('.'); + + return idx >= 0 ? clsName.substring(idx + 1) : clsName; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof BinaryBasicNameMapper)) + return false; + + BinaryBasicNameMapper mapper = (BinaryBasicNameMapper)o; + + if (isSimpleName != mapper.isSimpleName) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return (isSimpleName ? 1 : 0); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "BinaryBaseNameMapper [isSimpleName=" + isSimpleName + ']'; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/binary/BinaryIdMapper.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryIdMapper.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryIdMapper.java index 4c31140..dac5c44 100644 --- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryIdMapper.java +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryIdMapper.java @@ -30,26 +30,29 @@ package org.apache.ignite.binary; * Binary ID mapper can be configured for all binary objects via * {@link org.apache.ignite.configuration.BinaryConfiguration#getIdMapper()} method, * or for a specific binary type via {@link BinaryTypeConfiguration#getIdMapper()} method. + * @see BinaryNameMapper */ public interface BinaryIdMapper { /** - * Gets type ID for provided class name. + * Gets type ID for provided type name. *

* If {@code 0} is returned, hash code of class simple name will be used. * - * @param clsName Class name. + * @param typeName Type name. Type name is a result of {@link BinaryNameMapper#typeName(String)} call for an + * initial class or type name. * @return Type ID. + * @see BinaryNameMapper#typeName(String) */ - public int typeId(String clsName); + public int typeId(String typeName); /** - * Gets ID for provided field. - *

- * If {@code 0} is returned, hash code of field name will be used. + * Gets ID for provided field name.

If {@code 0} is returned, hash code of field name will be used. * * @param typeId Type ID. - * @param fieldName Field name. + * @param fieldName Field name. Filed anme is a result of {@link BinaryNameMapper#fieldName(String)} call for an + * initial filed name. * @return Field ID. + * @see BinaryNameMapper#fieldName(String) */ public int fieldId(int typeId, String fieldName); -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/binary/BinaryNameMapper.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryNameMapper.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryNameMapper.java new file mode 100644 index 0000000..2db0aeb --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryNameMapper.java @@ -0,0 +1,47 @@ +/* + * 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 + * + * http://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. + */ + +package org.apache.ignite.binary; + +import org.apache.ignite.configuration.BinaryConfiguration; + +/** + * Maps type and field names to different names. Prepares class/type names + * and field names before pass them to {@link BinaryIdMapper}. + *

+ * Binary name mapper can be configured for all binary objects via + * {@link BinaryConfiguration#getNameMapper()} method, + * or for a specific binary type via {@link BinaryTypeConfiguration#getNameMapper()} method. + * @see BinaryIdMapper + */ +public interface BinaryNameMapper { + /** + * Gets type clsName. + * + * @param clsName Class came + * @return Type name. + */ + String typeName(String clsName); + + /** + * Gets field name. + * + * @param fieldName Field name. + * @return Field name. + */ + String fieldName(String fieldName); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java index a00c061..fea0af7 100644 --- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java +++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java @@ -36,6 +36,9 @@ public class BinaryTypeConfiguration { /** ID mapper. */ private BinaryIdMapper idMapper; + /** Name mapper. */ + private BinaryNameMapper nameMapper; + /** Serializer. */ private BinarySerializer serializer; @@ -107,6 +110,24 @@ public class BinaryTypeConfiguration { } /** + * Gets name mapper. + * + * @return Name mapper. + */ + public BinaryNameMapper getNameMapper() { + return nameMapper; + } + + /** + * Sets name mapper. + * + * @param nameMapper Name mapper. + */ + public void setNameMapper(BinaryNameMapper nameMapper) { + this.nameMapper = nameMapper; + } + + /** * Gets serializer. * * @return Serializer. @@ -146,4 +167,4 @@ public class BinaryTypeConfiguration { @Override public String toString() { return S.toString(BinaryTypeConfiguration.class, this, super.toString()); } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java index 1151245..30d77de 100644 --- a/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java +++ b/modules/core/src/main/java/org/apache/ignite/configuration/BinaryConfiguration.java @@ -20,8 +20,10 @@ package org.apache.ignite.configuration; import java.util.ArrayList; import java.util.Collection; import org.apache.ignite.binary.BinaryIdMapper; +import org.apache.ignite.binary.BinaryNameMapper; import org.apache.ignite.binary.BinarySerializer; import org.apache.ignite.binary.BinaryTypeConfiguration; +import org.apache.ignite.internal.util.typedef.internal.S; /** * Configuration object for Ignite Binary Objects. @@ -34,6 +36,9 @@ public class BinaryConfiguration { /** ID mapper. */ private BinaryIdMapper idMapper; + /** Name mapper. */ + private BinaryNameMapper nameMapper; + /** Serializer. */ private BinarySerializer serializer; @@ -75,6 +80,24 @@ public class BinaryConfiguration { } /** + * Gets name mapper. + * + * @return Name mapper. + */ + public BinaryNameMapper getNameMapper() { + return nameMapper; + } + + /** + * Sets name mapper. + * + * @param nameMapper Name mapper. + */ + public void setNameMapper(BinaryNameMapper nameMapper) { + this.nameMapper = nameMapper; + } + + /** * Gets serializer. * * @return Serializer. @@ -136,4 +159,9 @@ public class BinaryConfiguration { public void setCompactFooter(boolean compactFooter) { this.compactFooter = compactFooter; } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(BinaryConfiguration.class, this); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java index 6598dc0..f705638 100644 --- a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java +++ b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java @@ -2002,8 +2002,10 @@ public class IgniteConfiguration { * * @param cacheKeyCfg Cache key configuration. */ - public void setCacheKeyConfiguration(CacheKeyConfiguration... cacheKeyCfg) { + public IgniteConfiguration setCacheKeyConfiguration(CacheKeyConfiguration... cacheKeyCfg) { this.cacheKeyCfg = cacheKeyCfg; + + return this; } /** @@ -2020,8 +2022,10 @@ public class IgniteConfiguration { * * @param binaryCfg Binary configuration object. */ - public void setBinaryConfiguration(BinaryConfiguration binaryCfg) { + public IgniteConfiguration setBinaryConfiguration(BinaryConfiguration binaryCfg) { this.binaryCfg = binaryCfg; + + return this; } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java index 3c5f960..da6f40d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java @@ -147,6 +147,9 @@ public final class IgniteNodeAttributes { /** Update notifier enabled. */ public static final String ATTR_UPDATE_NOTIFIER_ENABLED = ATTR_PREFIX + ".update.notifier.enabled"; + /** Binary configuration. */ + public static final String ATTR_BINARY_CONFIGURATION = ATTR_PREFIX + ".binary.config"; + /** * Enforces singleton. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/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 1ffa9e5..701425a 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 @@ -47,6 +47,20 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.binary.BinaryReflectiveSerializer; +import org.apache.ignite.binary.BinarySerializer; +import org.apache.ignite.binary.Binarylizable; +import org.apache.ignite.internal.processors.cache.CacheObjectImpl; +import org.apache.ignite.internal.util.GridUnsafe; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.MarshallerExclusions; +import org.apache.ignite.marshaller.optimized.OptimizedMarshaller; +import org.jetbrains.annotations.Nullable; +import sun.misc.Unsafe; /** * Binary class descriptor. @@ -59,6 +73,7 @@ public class BinaryClassDescriptor { private static final String OAI_PKG = "org.apache.ignite"; /** */ + @GridToStringExclude private final BinaryContext ctx; /** */ @@ -68,7 +83,7 @@ public class BinaryClassDescriptor { private final BinarySerializer serializer; /** ID mapper. */ - private final BinaryIdMapper idMapper; + private final BinaryInternalMapper mapper; /** */ private final BinaryWriteMode mode; @@ -122,7 +137,7 @@ public class BinaryClassDescriptor { * @param typeId Type ID. * @param typeName Type name. * @param affKeyFieldName Affinity key field name. - * @param idMapper ID mapper. + * @param mapper Mapper. * @param serializer Serializer. * @param metaDataEnabled Metadata enabled flag. * @param registered Whether typeId has been successfully registered by MarshallerContext or not. @@ -135,14 +150,14 @@ public class BinaryClassDescriptor { int typeId, String typeName, @Nullable String affKeyFieldName, - @Nullable BinaryIdMapper idMapper, + @Nullable BinaryInternalMapper mapper, @Nullable BinarySerializer serializer, boolean metaDataEnabled, boolean registered ) throws BinaryObjectException { assert ctx != null; assert cls != null; - assert idMapper != null; + assert mapper != null; // If serializer is not defined at this point, then we have to user OptimizedMarshaller. useOptMarshaller = serializer == null; @@ -158,7 +173,7 @@ public class BinaryClassDescriptor { this.typeName = typeName; this.affKeyFieldName = affKeyFieldName; this.serializer = serializer; - this.idMapper = idMapper; + this.mapper = mapper; this.registered = registered; schemaReg = ctx.schemaRegistry(typeId); @@ -273,7 +288,7 @@ public class BinaryClassDescriptor { assert added : name; - int fieldId = idMapper.fieldId(typeId, name); + int fieldId = this.mapper.fieldId(typeId, name); if (!ids.add(fieldId)) throw new BinaryObjectException("Duplicate field ID: " + name); @@ -639,7 +654,7 @@ public class BinaryClassDescriptor { if (schemaReg.schema(schemaId) == null) { // This is new schema, let's update metadata. BinaryMetadataCollector collector = - new BinaryMetadataCollector(typeId, typeName, idMapper); + new BinaryMetadataCollector(typeId, typeName, mapper); if (serializer != null) serializer.writeBinary(obj, collector); @@ -808,4 +823,9 @@ public class BinaryClassDescriptor { throw new BinaryObjectException("Failed to get constructor for class: " + cls.getName(), e); } } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(BinaryClassDescriptor.class, this); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java index 163532d..cf19bdf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java @@ -17,10 +17,39 @@ package org.apache.ignite.internal.binary; +import java.io.Externalizable; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentMap; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; +import org.apache.ignite.binary.BinaryBasicIdMapper; +import org.apache.ignite.binary.BinaryBasicNameMapper; import org.apache.ignite.binary.BinaryIdMapper; import org.apache.ignite.binary.BinaryInvalidTypeException; +import org.apache.ignite.binary.BinaryNameMapper; import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.binary.BinaryReflectiveSerializer; import org.apache.ignite.binary.BinarySerializer; @@ -31,7 +60,6 @@ import org.apache.ignite.cache.affinity.AffinityKey; import org.apache.ignite.cache.affinity.AffinityKeyMapped; import org.apache.ignite.configuration.BinaryConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.internal.IgnitionEx; import org.apache.ignite.internal.processors.cache.binary.BinaryMetadataKey; import org.apache.ignite.internal.processors.datastructures.CollocatedQueueItemKey; import org.apache.ignite.internal.processors.datastructures.CollocatedSetItemKey; @@ -46,32 +74,6 @@ import org.apache.ignite.marshaller.optimized.OptimizedMarshaller; import org.jetbrains.annotations.Nullable; import org.jsr166.ConcurrentHashMap8; -import java.io.Externalizable; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentMap; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - /** * Binary context. */ @@ -80,6 +82,14 @@ public class BinaryContext { private static final ClassLoader dfltLdr = U.gridClassLoader(); /** */ + private static final BinaryInternalMapper DFLT_MAPPER = + new BinaryInternalMapper(new BinaryBasicNameMapper(false), new BinaryBasicIdMapper(true), false); + + /** */ + static final BinaryInternalMapper SIMPLE_NAME_LOWER_CASE_MAPPER = + new BinaryInternalMapper(new BinaryBasicNameMapper(true), new BinaryBasicIdMapper(true), false); + + /** */ private final ConcurrentMap, BinaryClassDescriptor> descByCls = new ConcurrentHashMap8<>(); /** Holds classes loaded by default class loader only. */ @@ -97,14 +107,14 @@ public class BinaryContext { /** */ private final Map, Byte> mapTypes = new HashMap<>(); - /** */ - private final ConcurrentMap mappers = new ConcurrentHashMap8<>(0); + /** Maps typeId to mappers. */ + private final ConcurrentMap typeId2Mapper = new ConcurrentHashMap8<>(0); /** Affinity key field names. */ private final ConcurrentMap affKeyFieldNames = new ConcurrentHashMap8<>(0); - /** */ - private final Map typeMappers = new ConcurrentHashMap8<>(0); + /** Maps className to mapper */ + private final ConcurrentMap cls2Mappers = new ConcurrentHashMap8<>(0); /** */ private BinaryMetadataHandler metaHnd; @@ -271,6 +281,7 @@ public class BinaryContext { optmMarsh.setContext(marshCtx); configure( + binaryCfg.getNameMapper(), binaryCfg.getIdMapper(), binaryCfg.getSerializer(), binaryCfg.getTypeConfigurations() @@ -286,6 +297,7 @@ public class BinaryContext { * @throws BinaryObjectException In case of error. */ private void configure( + BinaryNameMapper globalNameMapper, BinaryIdMapper globalIdMapper, BinarySerializer globalSerializer, Collection typeCfgs @@ -306,13 +318,20 @@ public class BinaryContext { if (clsName == null) throw new BinaryObjectException("Class name is required for binary type configuration."); + // Resolve mapper. BinaryIdMapper idMapper = globalIdMapper; if (typeCfg.getIdMapper() != null) idMapper = typeCfg.getIdMapper(); - idMapper = BinaryInternalIdMapper.create(idMapper); + BinaryNameMapper nameMapper = globalNameMapper; + + if (typeCfg.getNameMapper() != null) + nameMapper = typeCfg.getNameMapper(); + + BinaryInternalMapper mapper = resolveMapper(nameMapper, idMapper); + // Resolve serializer. BinarySerializer serializer = globalSerializer; if (typeCfg.getSerializer() != null) @@ -322,25 +341,25 @@ public class BinaryContext { String pkgName = clsName.substring(0, clsName.length() - 2); for (String clsName0 : classesInPackage(pkgName)) - descs.add(clsName0, idMapper, serializer, affFields.get(clsName0), + descs.add(clsName0, mapper, serializer, affFields.get(clsName0), typeCfg.isEnum(), true); } else - descs.add(clsName, idMapper, serializer, affFields.get(clsName), + descs.add(clsName, mapper, serializer, affFields.get(clsName), typeCfg.isEnum(), false); } } for (TypeDescriptor desc : descs.descriptors()) - registerUserType(desc.clsName, desc.idMapper, desc.serializer, desc.affKeyFieldName, desc.isEnum); + registerUserType(desc.clsName, desc.mapper, desc.serializer, desc.affKeyFieldName, desc.isEnum); - BinaryInternalIdMapper dfltMapper = BinaryInternalIdMapper.create(globalIdMapper); + BinaryInternalMapper globalMapper = resolveMapper(globalNameMapper, globalIdMapper); // Put affinity field names for unconfigured types. for (Map.Entry entry : affFields.entrySet()) { String typeName = entry.getKey(); - int typeId = dfltMapper.typeId(typeName); + int typeId = globalMapper.typeId(typeName); affKeyFieldNames.putIfAbsent(typeId, entry.getValue()); } @@ -350,6 +369,52 @@ public class BinaryContext { } /** + * @param nameMapper Name mapper. + * @param idMapper ID mapper. + * @return Mapper. + */ + private static BinaryInternalMapper resolveMapper(BinaryNameMapper nameMapper, BinaryIdMapper idMapper) { + if ((nameMapper == null || (DFLT_MAPPER.nameMapper().equals(nameMapper))) + && (idMapper == null || DFLT_MAPPER.idMapper().equals(idMapper))) + return DFLT_MAPPER; + + if (nameMapper != null && nameMapper instanceof BinaryBasicNameMapper + && ((BinaryBasicNameMapper)nameMapper).isSimpleName() + && idMapper != null && idMapper instanceof BinaryBasicIdMapper + && ((BinaryBasicIdMapper)idMapper).isLowerCase()) + return SIMPLE_NAME_LOWER_CASE_MAPPER; + + if (nameMapper == null) + nameMapper = DFLT_MAPPER.nameMapper(); + + if (idMapper == null) + idMapper = DFLT_MAPPER.idMapper(); + + return new BinaryInternalMapper(nameMapper, idMapper, true); + } + + /** + * @return Intenal mpper used as default. + */ + public static BinaryInternalMapper defaultMapper() { + return DFLT_MAPPER; + } + + /** + * @return ID mapper used as default. + */ + public static BinaryIdMapper defaultIdMapper() { + return DFLT_MAPPER.idMapper(); + } + + /** + * @return Name mapper used as default. + */ + public static BinaryNameMapper defaultNameMapper() { + return DFLT_MAPPER.nameMapper(); + } + + /** * @param cls Class. */ private void addSystemClassAffinityKey(Class cls) { @@ -502,7 +567,8 @@ public class BinaryContext { if (desc == null) { desc = registerClassDescriptor(cls, deserialize); - assert desc.typeId() == typeId; + assert desc.typeId() == typeId : "Duplicate typeId [typeId=" + typeId + ", cls=" + cls + + ", desc=" + desc + "]"; } return desc; @@ -526,7 +592,7 @@ public class BinaryContext { clsName.hashCode(), clsName, null, - BinaryInternalIdMapper.defaultInstance(), + SIMPLE_NAME_LOWER_CASE_MAPPER, null, false, true /* registered */ @@ -552,11 +618,13 @@ public class BinaryContext { private BinaryClassDescriptor registerUserClassDescriptor(Class cls, boolean deserialize) { boolean registered; - String typeName = typeName(cls.getName()); + final String clsName = cls.getName(); + + BinaryInternalMapper mapper = userTypeMapper(clsName); - BinaryIdMapper idMapper = userTypeIdMapper(typeName); + final String typeName = mapper.typeName(clsName); - int typeId = idMapper.typeId(typeName); + final int typeId = mapper.typeId(clsName); try { registered = marshCtx.registerClass(typeId, cls); @@ -575,7 +643,7 @@ public class BinaryContext { typeId, typeName, affFieldName, - idMapper, + mapper, serializer, true, registered @@ -595,7 +663,7 @@ public class BinaryContext { descByCls.put(cls, desc); - mappers.putIfAbsent(typeId, idMapper); + typeId2Mapper.putIfAbsent(typeId, mapper); return desc; } @@ -656,9 +724,7 @@ public class BinaryContext { * @return Type ID. */ public int typeId(String typeName) { - String typeName0 = typeName(typeName); - - Integer id = predefinedTypeNames.get(typeName0); + Integer id = predefinedTypeNames.get(SIMPLE_NAME_LOWER_CASE_MAPPER.typeName(typeName)); if (id != null) return id; @@ -666,7 +732,9 @@ public class BinaryContext { if (marshCtx.isSystemType(typeName)) return typeName.hashCode(); - return userTypeIdMapper(typeName0).typeId(typeName0); + BinaryInternalMapper mapper = userTypeMapper(typeName); + + return mapper.typeId(typeName); } /** @@ -675,27 +743,107 @@ public class BinaryContext { * @return Field ID. */ public int fieldId(int typeId, String fieldName) { - return userTypeIdMapper(typeId).fieldId(typeId, fieldName); + BinaryInternalMapper mapper = userTypeMapper(typeId); + + return mapper.fieldId(typeId, fieldName); } /** * @param typeId Type ID. * @return Instance of ID mapper. */ - public BinaryIdMapper userTypeIdMapper(int typeId) { - BinaryIdMapper idMapper = mappers.get(typeId); + public BinaryInternalMapper userTypeMapper(int typeId) { + BinaryInternalMapper mapper = typeId2Mapper.get(typeId); - return idMapper != null ? idMapper : BinaryInternalIdMapper.defaultInstance(); + return mapper != null ? mapper : SIMPLE_NAME_LOWER_CASE_MAPPER; } /** - * @param typeName Type name. + * @param clsName Type name. * @return Instance of ID mapper. */ - private BinaryIdMapper userTypeIdMapper(String typeName) { - BinaryIdMapper idMapper = typeMappers.get(typeName); + private BinaryInternalMapper userTypeMapper(String clsName) { + BinaryInternalMapper mapper = cls2Mappers.get(clsName); + + if (mapper != null) + return mapper; + + mapper = resolveMapper(clsName, igniteCfg.getBinaryConfiguration()); + + BinaryInternalMapper prevMap = cls2Mappers.putIfAbsent(clsName, mapper); + + if (prevMap != null && !mapper.equals(prevMap)) + throw new IgniteException("Different mappers [clsName=" + clsName + ", newMapper=" + mapper + + ", prevMap=" + prevMap + "]"); + + prevMap = typeId2Mapper.putIfAbsent(mapper.typeId(clsName), mapper); - return idMapper != null ? idMapper : BinaryInternalIdMapper.defaultInstance(); + if (prevMap != null && !mapper.equals(prevMap)) + throw new IgniteException("Different mappers [clsName=" + clsName + ", newMapper=" + mapper + + ", prevMap=" + prevMap + "]"); + + return mapper; + } + + /** + * @param clsName Type name. + * @param cfg Binary configuration. + * @return Mapper according to configuration. + */ + private static BinaryInternalMapper resolveMapper(String clsName, BinaryConfiguration cfg) { + assert clsName != null; + + if (cfg == null) + return DFLT_MAPPER; + + BinaryIdMapper globalIdMapper = cfg.getIdMapper(); + BinaryNameMapper globalNameMapper = cfg.getNameMapper(); + + Collection typeCfgs = cfg.getTypeConfigurations(); + + if (typeCfgs != null) { + for (BinaryTypeConfiguration typeCfg : typeCfgs) { + String typeCfgName = typeCfg.getTypeName(); + + // Pattern. + if (typeCfgName != null && typeCfgName.endsWith(".*")) { + String pkgName = typeCfgName.substring(0, typeCfgName.length() - 2); + + int dotIndex = clsName.lastIndexOf('.'); + + if (dotIndex > 0) { + String typePkgName = clsName.substring(0, dotIndex); + + if (pkgName.equals(typePkgName)) { + // Resolve mapper. + BinaryIdMapper idMapper = globalIdMapper; + + if (typeCfg.getIdMapper() != null) + idMapper = typeCfg.getIdMapper(); + + BinaryNameMapper nameMapper = globalNameMapper; + + if (typeCfg.getNameMapper() != null) + nameMapper = typeCfg.getNameMapper(); + + return resolveMapper(nameMapper, idMapper); + } + } + } + } + } + + return resolveMapper(globalNameMapper, globalIdMapper); + } + + /** + * @param clsName Class name. + * @return Type name. + */ + public String userTypeName(String clsName) { + BinaryInternalMapper mapper = userTypeMapper(clsName); + + return mapper.typeName(clsName); } /** @@ -728,25 +876,25 @@ public class BinaryContext { * @return GridBinaryClassDescriptor. */ public BinaryClassDescriptor registerPredefinedType(Class cls, int id, String affFieldName) { - String typeName = typeName(cls.getName()); + String simpleClsName = SIMPLE_NAME_LOWER_CASE_MAPPER.typeName(cls.getName()); if (id == 0) - id = BinaryInternalIdMapper.defaultInstance().typeId(typeName); + id = SIMPLE_NAME_LOWER_CASE_MAPPER.typeId(simpleClsName); BinaryClassDescriptor desc = new BinaryClassDescriptor( this, cls, false, id, - typeName, + simpleClsName, affFieldName, - BinaryInternalIdMapper.defaultInstance(), + SIMPLE_NAME_LOWER_CASE_MAPPER, new BinaryReflectiveSerializer(), false, true /* registered */ ); - predefinedTypeNames.put(typeName, id); + predefinedTypeNames.put(simpleClsName, id); predefinedTypes.put(id, desc); descByCls.put(cls, desc); @@ -759,7 +907,7 @@ public class BinaryContext { /** * @param clsName Class name. - * @param idMapper ID mapper. + * @param mapper ID mapper. * @param serializer Serializer. * @param affKeyFieldName Affinity key field name. * @param isEnum If enum. @@ -767,12 +915,12 @@ public class BinaryContext { */ @SuppressWarnings("ErrorNotRethrown") public void registerUserType(String clsName, - BinaryIdMapper idMapper, + BinaryInternalMapper mapper, @Nullable BinarySerializer serializer, @Nullable String affKeyFieldName, boolean isEnum) throws BinaryObjectException { - assert idMapper != null; + assert mapper != null; Class cls = null; @@ -783,15 +931,15 @@ public class BinaryContext { // No-op. } - String typeName = typeName(clsName); + String typeName = mapper.typeName(clsName); - int id = idMapper.typeId(typeName); + int id = mapper.typeId(clsName); //Workaround for IGNITE-1358 if (predefinedTypes.get(id) != null) throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']'); - if (mappers.put(id, idMapper) != null) + if (typeId2Mapper.put(id, mapper) != null) throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']'); if (affKeyFieldName != null) { @@ -799,7 +947,7 @@ public class BinaryContext { throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']'); } - typeMappers.put(typeName, idMapper); + cls2Mappers.put(clsName, mapper); Map fieldsMeta = null; Collection schemas = null; @@ -820,7 +968,7 @@ public class BinaryContext { id, typeName, affKeyFieldName, - idMapper, + mapper, serializer, true, true /* registered */ @@ -858,7 +1006,9 @@ public class BinaryContext { public BinaryFieldImpl createField(int typeId, String fieldName) { BinarySchemaRegistry schemaReg = schemaRegistry(typeId); - int fieldId = userTypeIdMapper(typeId).fieldId(typeId, fieldName); + BinaryInternalMapper mapper = userTypeMapper(typeId); + + int fieldId = mapper.fieldId(typeId, fieldName); return new BinaryFieldImpl(typeId, schemaReg, fieldName, fieldId); } @@ -954,43 +1104,6 @@ public class BinaryContext { } /** - * @param clsName Class name. - * @return Type name. - */ - @SuppressWarnings("ResultOfMethodCallIgnored") - public static String typeName(String clsName) { - assert clsName != null; - - int idx = clsName.lastIndexOf('$'); - - if (idx == clsName.length() - 1) - // This is a regular (not inner) class name that ends with '$'. Common use case for Scala classes. - idx = -1; - else if (idx >= 0) { - String typeName = clsName.substring(idx + 1); - - try { - Integer.parseInt(typeName); - - // This is an anonymous class. Don't cut off enclosing class name for it. - idx = -1; - } - catch (NumberFormatException ignore) { - // This is a lambda class. - if (clsName.indexOf("$$Lambda$") > 0) - idx = -1; - else - return typeName; - } - } - - if (idx < 0) - idx = clsName.lastIndexOf('.'); - - return idx >= 0 ? clsName.substring(idx + 1) : clsName; - } - - /** * Undeployment callback invoked when class loader is being undeployed. * * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow. @@ -1017,7 +1130,7 @@ public class BinaryContext { * Add type descriptor. * * @param clsName Class name. - * @param idMapper ID mapper. + * @param mapper Mapper. * @param serializer Serializer. * @param affKeyFieldName Affinity key field name. * @param isEnum Enum flag. @@ -1025,14 +1138,14 @@ public class BinaryContext { * @throws BinaryObjectException If failed. */ private void add(String clsName, - BinaryIdMapper idMapper, + BinaryInternalMapper mapper, BinarySerializer serializer, String affKeyFieldName, boolean isEnum, boolean canOverride) throws BinaryObjectException { TypeDescriptor desc = new TypeDescriptor(clsName, - idMapper, + mapper, serializer, affKeyFieldName, isEnum, @@ -1063,8 +1176,8 @@ public class BinaryContext { /** Class name. */ private final String clsName; - /** ID mapper. */ - private BinaryIdMapper idMapper; + /** Mapper. */ + private BinaryInternalMapper mapper; /** Serializer. */ private BinarySerializer serializer; @@ -1082,16 +1195,16 @@ public class BinaryContext { * Constructor. * * @param clsName Class name. - * @param idMapper ID mapper. + * @param mapper ID mapper. * @param serializer Serializer. * @param affKeyFieldName Affinity key field name. * @param isEnum Enum type. * @param canOverride Whether this descriptor can be override. */ - private TypeDescriptor(String clsName, BinaryIdMapper idMapper, BinarySerializer serializer, - String affKeyFieldName, boolean isEnum, boolean canOverride) { + private TypeDescriptor(String clsName, BinaryInternalMapper mapper, + BinarySerializer serializer, String affKeyFieldName, boolean isEnum, boolean canOverride) { this.clsName = clsName; - this.idMapper = idMapper; + this.mapper = mapper; this.serializer = serializer; this.affKeyFieldName = affKeyFieldName; this.isEnum = isEnum; @@ -1108,7 +1221,7 @@ public class BinaryContext { assert clsName.equals(other.clsName); if (canOverride) { - idMapper = other.idMapper; + mapper = other.mapper; serializer = other.serializer; affKeyFieldName = other.affKeyFieldName; isEnum = other.isEnum; http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java index 99c5d48..7390aeb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java @@ -17,6 +17,11 @@ package org.apache.ignite.internal.binary; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.nio.ByteBuffer; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryObjectBuilder; @@ -32,12 +37,6 @@ import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.jetbrains.annotations.Nullable; -import java.io.Externalizable; -import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.nio.ByteBuffer; - /** * Binary enum object. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalIdMapper.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalIdMapper.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalIdMapper.java deleted file mode 100644 index 14d7d6f..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalIdMapper.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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 - * - * http://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. - */ - -package org.apache.ignite.internal.binary; - -import org.apache.ignite.binary.BinaryIdMapper; -import org.apache.ignite.binary.BinaryObjectException; -import org.jetbrains.annotations.Nullable; - -/** - * Internal ID mapper. Mimics ID mapper interface, but provides default implementation and offers slightly better - * performance on micro-level in default case because it doesn't need virtual calls. - */ -public class BinaryInternalIdMapper implements BinaryIdMapper { - /** Maximum lower-case character. */ - private static final char MAX_LOWER_CASE_CHAR = 0x7e; - - /** Cached lower-case characters. */ - private static final char[] LOWER_CASE_CHARS; - - /** Default implementation. */ - private static final BinaryInternalIdMapper DFLT = new BinaryInternalIdMapper(); - - /** - * Static initializer. - */ - static { - LOWER_CASE_CHARS = new char[MAX_LOWER_CASE_CHAR + 1]; - - for (char c = 0; c <= MAX_LOWER_CASE_CHAR; c++) - LOWER_CASE_CHARS[c] = Character.toLowerCase(c); - } - - /** - * Get default instance. - * - * @return Default instance. - */ - public static BinaryInternalIdMapper defaultInstance() { - return DFLT; - } - - /** - * Create internal mapper. - * - * @param mapper Public mapper. - * @return Internal mapper. - */ - public static BinaryInternalIdMapper create(@Nullable BinaryIdMapper mapper) { - return mapper == null ? DFLT : new Wrapper(mapper); - } - - /** - * Private constructor. - */ - protected BinaryInternalIdMapper() { - // No-op. - } - - /** - * Get type ID. - * - * @param typeName Type name. - * @return Type ID. - */ - public int typeId(String typeName) { - assert typeName != null; - - return lowerCaseHashCode(typeName, true); - } - - /** - * Get field ID. - * - * @param typeId Type ID. - * @param fieldName Field name. - * @return Field ID. - */ - public int fieldId(int typeId, String fieldName) { - assert fieldName != null; - - return lowerCaseHashCode(fieldName, false); - } - - /** - * Routine to calculate string hash code an - * - * @param str String. - * @param type {@code True} if this is type name, false otherwise. - * @return Hash code for given string converted to lower case. - */ - private static int lowerCaseHashCode(String str, boolean type) { - int len = str.length(); - - int h = 0; - - for (int i = 0; i < len; i++) { - int c = str.charAt(i); - - c = c <= MAX_LOWER_CASE_CHAR ? LOWER_CASE_CHARS[c] : Character.toLowerCase(c); - - h = 31 * h + c; - } - - if (h != 0) - return h; - else { - String what = type ? "type" : "field"; - - throw new BinaryObjectException("Default binary ID mapper resolved " + what + " ID to zero " + - "(either change " + what + "'s name or use custom ID mapper) [name=" + str + ']'); - } - } - - /** - * Wrapping ID mapper. - */ - private static class Wrapper extends BinaryInternalIdMapper { - /** Delegate. */ - private final BinaryIdMapper mapper; - - /** - * Constructor. - * - * @param mapper Delegate. - */ - private Wrapper(BinaryIdMapper mapper) { - assert mapper != null; - - this.mapper = mapper; - } - - /** {@inheritDoc} */ - @Override public int typeId(String typeName) { - int id = mapper.typeId(typeName); - - return id != 0 ? id : super.typeId(typeName); - } - - /** {@inheritDoc} */ - @Override public int fieldId(int typeId, String fieldName) { - int id = mapper.fieldId(typeId, fieldName); - - return id != 0 ? id : super.fieldId(typeId, fieldName); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalMapper.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalMapper.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalMapper.java new file mode 100644 index 0000000..1adc8c7 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryInternalMapper.java @@ -0,0 +1,131 @@ +/* + * 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 + * + * http://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. + */ + +package org.apache.ignite.internal.binary; + +import org.apache.ignite.binary.BinaryIdMapper; +import org.apache.ignite.binary.BinaryNameMapper; +import org.apache.ignite.internal.util.typedef.internal.S; + +/** + * Internal binary mapper. + */ +public class BinaryInternalMapper { + /** */ + private final BinaryNameMapper nameMapper; + + /** */ + private final BinaryIdMapper idMapper; + + /** */ + private boolean checkOnZeroId; + + /** + * @param nameMapper Name mapper. + * @param idMapper Id mapper. + * @param checkOnZeroId Whether checks on zero id or not. + */ + public BinaryInternalMapper(BinaryNameMapper nameMapper, BinaryIdMapper idMapper, boolean checkOnZeroId) { + assert nameMapper != null; + assert idMapper != null; + + this.nameMapper = nameMapper; + this.idMapper = idMapper; + this.checkOnZeroId = checkOnZeroId; + } + + /** + * @return Name mapper. + */ + public BinaryNameMapper nameMapper() { + return nameMapper; + } + + /** + * @return ID mapper. + */ + public BinaryIdMapper idMapper() { + return idMapper; + } + + /** + * @param clsName Class name. + * @return Type ID. + */ + public int typeId(String clsName) { + int id = idMapper.typeId(nameMapper.typeName(clsName)); + + if (!checkOnZeroId) + return id; + + return id != 0 ? id : BinaryContext.SIMPLE_NAME_LOWER_CASE_MAPPER.typeId(clsName); + } + + /** + * @param typeId Type ID. + * @param fieldName Field name. + * @return Field ID. + */ + public int fieldId(int typeId, String fieldName) { + int id = idMapper.fieldId(typeId, nameMapper.fieldName(fieldName)); + + if (!checkOnZeroId) + return id; + + return id != 0 ? id : BinaryContext.SIMPLE_NAME_LOWER_CASE_MAPPER.fieldId(typeId, fieldName); + } + + /** + * @param clsName Class name. + * @return Type name. + */ + public String typeName(String clsName) { + return nameMapper.typeName(clsName); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof BinaryInternalMapper)) + return false; + + BinaryInternalMapper mapper = (BinaryInternalMapper)o; + + return checkOnZeroId == mapper.checkOnZeroId + && idMapper.equals(mapper.idMapper) + && nameMapper.equals(mapper.nameMapper); + + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = nameMapper.hashCode(); + + res = 31 * res + idMapper.hashCode(); + + res = 31 * res + (checkOnZeroId ? 1 : 0); + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(BinaryInternalMapper.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java index 54f2b13..e8574ef 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataCollector.java @@ -17,12 +17,6 @@ package org.apache.ignite.internal.binary; -import org.apache.ignite.binary.BinaryIdMapper; -import org.apache.ignite.binary.BinaryObjectException; -import org.apache.ignite.binary.BinaryRawWriter; -import org.apache.ignite.binary.BinaryWriter; -import org.jetbrains.annotations.Nullable; - import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; @@ -33,6 +27,10 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.binary.BinaryRawWriter; +import org.apache.ignite.binary.BinaryWriter; +import org.jetbrains.annotations.Nullable; /** * Writer for meta data collection. @@ -44,8 +42,8 @@ class BinaryMetadataCollector implements BinaryWriter { /** Type name. */ private final String typeName; - /** ID mapper. */ - private final BinaryIdMapper idMapper; + /** Name mapper. */ + private final BinaryInternalMapper mapper; /** Collected metadata. */ private final Map meta = new HashMap<>(); @@ -58,12 +56,12 @@ class BinaryMetadataCollector implements BinaryWriter { * * @param typeId Type ID. * @param typeName Type name. - * @param idMapper ID mapper. + * @param mapper Name mapper. */ - BinaryMetadataCollector(int typeId, String typeName, BinaryIdMapper idMapper) { + BinaryMetadataCollector(int typeId, String typeName, BinaryInternalMapper mapper) { this.typeId = typeId; this.typeName = typeName; - this.idMapper = idMapper; + this.mapper = mapper; } /** @@ -272,6 +270,6 @@ class BinaryMetadataCollector implements BinaryWriter { ); } - schemaBuilder.addField(idMapper.fieldId(typeId, name)); + schemaBuilder.addField(mapper.fieldId(typeId, name)); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java index 8f9cc92..607dabc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java @@ -26,9 +26,7 @@ import java.util.Collection; import java.util.Date; import java.util.Map; import java.util.UUID; - import org.apache.ignite.binary.BinaryCollectionFactory; -import org.apache.ignite.binary.BinaryIdMapper; import org.apache.ignite.binary.BinaryInvalidTypeException; import org.apache.ignite.binary.BinaryMapFactory; import org.apache.ignite.binary.BinaryObject; @@ -40,6 +38,7 @@ import org.apache.ignite.internal.util.typedef.internal.SB; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BINARY_OBJ; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BOOLEAN; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BOOLEAN_ARR; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BYTE; @@ -69,7 +68,6 @@ import static org.apache.ignite.internal.binary.GridBinaryMarshaller.NULL; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.OBJ; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.OBJ_ARR; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.OPTM_MARSH; -import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BINARY_OBJ; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.SHORT; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.SHORT_ARR; import static org.apache.ignite.internal.binary.GridBinaryMarshaller.STRING; @@ -115,8 +113,8 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina /** Footer end. */ private final int footerLen; - /** ID mapper. */ - private final BinaryIdMapper idMapper; + /** Mapper. */ + private final BinaryInternalMapper mapper; /** Schema Id. */ private final int schemaId; @@ -247,7 +245,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina dataStart = start + DFLT_HDR_LEN; } - idMapper = userType ? ctx.userTypeIdMapper(typeId) : BinaryInternalIdMapper.defaultInstance(); + mapper = userType ? ctx.userTypeMapper(typeId) : BinaryContext.defaultMapper(); schema = BinaryUtils.hasSchema(flags) ? getOrCreateSchema() : null; } else { @@ -256,7 +254,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina rawOff = 0; footerStart = 0; footerLen = 0; - idMapper = null; + mapper = null; schemaId = 0; userType = false; fieldIdLen = 0; @@ -1653,7 +1651,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina private int fieldId(String name) { assert name != null; - return idMapper.fieldId(typeId, name); + return mapper.fieldId(typeId, name); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java index 6e05b40..877a2db 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java @@ -17,16 +17,6 @@ package org.apache.ignite.internal.binary; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.binary.BinaryIdMapper; -import org.apache.ignite.binary.BinaryObjectException; -import org.apache.ignite.binary.BinaryRawWriter; -import org.apache.ignite.binary.BinaryWriter; -import org.apache.ignite.internal.binary.streams.BinaryOutputStream; -import org.apache.ignite.internal.binary.streams.BinaryHeapOutputStream; -import org.apache.ignite.internal.util.typedef.internal.A; -import org.jetbrains.annotations.Nullable; - import java.io.IOException; import java.io.ObjectOutput; import java.lang.reflect.InvocationTargetException; @@ -37,6 +27,14 @@ import java.util.Collection; import java.util.Date; import java.util.Map; import java.util.UUID; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.binary.BinaryRawWriter; +import org.apache.ignite.binary.BinaryWriter; +import org.apache.ignite.internal.binary.streams.BinaryHeapOutputStream; +import org.apache.ignite.internal.binary.streams.BinaryOutputStream; +import org.apache.ignite.internal.util.typedef.internal.A; +import org.jetbrains.annotations.Nullable; import static java.nio.charset.StandardCharsets.UTF_8; @@ -77,8 +75,8 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje /** Amount of written fields. */ private int fieldCnt; - /** ID mapper. */ - private BinaryIdMapper idMapper; + /** */ + private BinaryInternalMapper mapper; /** * @param ctx Context. @@ -1642,10 +1640,12 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje if (rawOffPos != 0) throw new BinaryObjectException("Individual field can't be written after raw writer is acquired."); - if (idMapper == null) - idMapper = ctx.userTypeIdMapper(typeId); + if (mapper == null) + mapper = ctx.userTypeMapper(typeId); + + assert mapper != null; - int id = idMapper.fieldId(typeId, fieldName); + int id = mapper.fieldId(typeId, fieldName); writeFieldId(id); } http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java index a095242..6e5a621 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java @@ -17,17 +17,15 @@ package org.apache.ignite.internal.binary.builder; +import java.util.Collection; +import java.util.IdentityHashMap; +import java.util.Map; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.internal.binary.BinaryMetadata; import org.apache.ignite.internal.binary.BinaryObjectExImpl; +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.binary.BinaryContext; -import org.apache.ignite.internal.binary.BinaryUtils; - -import java.util.Collection; -import java.util.IdentityHashMap; -import java.util.Map; /** * @@ -100,8 +98,10 @@ class BinaryBuilderSerializer { } if (val.getClass().isEnum()) { - String typeName = BinaryContext.typeName(val.getClass().getName()); - int typeId = writer.context().typeId(typeName); + String clsName = val.getClass().getName(); + + int typeId = writer.context().typeId(clsName); + String typeName = writer.context().userTypeName(clsName); BinaryMetadata meta = new BinaryMetadata(typeId, typeName, null, null, null, true); writer.context().updateMetadata(typeId, meta); http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/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 8353cdb..e2290d6 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 @@ -90,7 +90,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { * @param ctx Binary context. */ public BinaryObjectBuilderImpl(BinaryContext ctx, String clsName) { - this(ctx, ctx.typeId(clsName), BinaryContext.typeName(clsName)); + this(ctx, ctx.typeId(clsName), ctx.userTypeName(clsName)); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/8a52b365/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java index c9d6dad..a21331e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java @@ -22,9 +22,10 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.Map; -import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; @@ -39,16 +40,20 @@ import javax.cache.processor.MutableEntry; import org.apache.ignite.IgniteBinary; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; +import org.apache.ignite.binary.BinaryBasicNameMapper; 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.binary.BinaryTypeConfiguration; import org.apache.ignite.cache.CacheEntryEventSerializableFilter; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.cluster.ClusterTopologyException; +import org.apache.ignite.configuration.BinaryConfiguration; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException; +import org.apache.ignite.internal.IgniteNodeAttributes; +import org.apache.ignite.internal.binary.BinaryContext; import org.apache.ignite.internal.binary.BinaryEnumObjectImpl; import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.binary.BinaryMetadata; @@ -57,12 +62,12 @@ import org.apache.ignite.internal.binary.BinaryObjectEx; import org.apache.ignite.internal.binary.BinaryObjectImpl; import org.apache.ignite.internal.binary.BinaryObjectOffheapImpl; import org.apache.ignite.internal.binary.BinaryTypeImpl; -import org.apache.ignite.internal.binary.GridBinaryMarshaller; -import org.apache.ignite.internal.binary.BinaryContext; import org.apache.ignite.internal.binary.BinaryUtils; +import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl; import org.apache.ignite.internal.binary.streams.BinaryInputStream; import org.apache.ignite.internal.binary.streams.BinaryOffheapInputStream; +import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CacheEntryPredicateAdapter; @@ -92,11 +97,16 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiPredicate; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgniteClosure; +import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.spi.IgniteNodeValidationResult; import org.jetbrains.annotations.Nullable; import org.jsr166.ConcurrentHashMap8; import sun.misc.Unsafe; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK; +import static org.apache.ignite.IgniteSystemProperties.getBoolean; + /** * Binary processor implementation. */ @@ -106,6 +116,9 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm private static final Unsafe UNSAFE = GridUnsafe.unsafe(); /** */ + public static final IgniteProductVersion BINARY_CFG_CHECK_SINCE = IgniteProductVersion.fromString("1.5.6"); + + /** */ private final CountDownLatch startLatch = new CountDownLatch(1); /** */ @@ -204,16 +217,46 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm } }; - BinaryMarshaller pMarh0 = (BinaryMarshaller)marsh; + BinaryMarshaller bMarsh0 = (BinaryMarshaller)marsh; binaryCtx = new BinaryContext(metaHnd, ctx.config(), ctx.log(BinaryContext.class)); - IgniteUtils.invoke(BinaryMarshaller.class, pMarh0, "setBinaryContext", binaryCtx, - ctx.config()); + IgniteUtils.invoke(BinaryMarshaller.class, bMarsh0, "setBinaryContext", binaryCtx, ctx.config()); binaryMarsh = new GridBinaryMarshaller(binaryCtx); binaries = new IgniteBinaryImpl(ctx, this); + + if (!getBoolean(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK)) { + BinaryConfiguration bCfg = ctx.config().getBinaryConfiguration(); + + if (bCfg != null) { + Map map = new HashMap<>(); + + map.put("globIdMapper", bCfg.getIdMapper() != null ? bCfg.getIdMapper().getClass().getName() : null); + map.put("globSerializer", bCfg.getSerializer() != null ? bCfg.getSerializer().getClass() : null); + map.put("compactFooter", bCfg.isCompactFooter()); + + if (bCfg.getTypeConfigurations() != null) { + Map typeCfgsMap = new HashMap<>(); + + for (BinaryTypeConfiguration c : bCfg.getTypeConfigurations()) { + typeCfgsMap.put( + c.getTypeName() != null, + Arrays.asList( + c.getIdMapper() != null ? c.getIdMapper().getClass() : null, + c.getSerializer() != null ? c.getSerializer().getClass() : null, + c.isEnum() + ) + ); + } + + map.put("typeCfgs", typeCfgsMap); + } + + ctx.addNodeAttribute(IgniteNodeAttributes.ATTR_BINARY_CONFIGURATION, map); + } + } } } @@ -294,6 +337,37 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm } /** {@inheritDoc} */ + @Override public void onKernalStart() throws IgniteCheckedException { + super.onKernalStart(); + + if (!getBoolean(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK) && marsh instanceof BinaryMarshaller) { + BinaryConfiguration bcfg = ctx.config().getBinaryConfiguration(); + + for (ClusterNode rmtNode : ctx.discovery().remoteNodes()) { + if (rmtNode.version().compareTo(BINARY_CFG_CHECK_SINCE) < 0) { + if (bcfg == null || bcfg.getNameMapper() == null) { + throw new IgniteCheckedException("When BinaryMarshaller is used and topology contains old " + + "nodes, then " + BinaryBasicNameMapper.class.getName() + " mapper have to be set " + + "explicitely into binary configuration and 'simpleName' property of the mapper " + + "have to be set to 'true'."); + } + + if (!(bcfg.getNameMapper() instanceof BinaryBasicNameMapper) + || !((BinaryBasicNameMapper)bcfg.getNameMapper()).isSimpleName()) { + U.quietAndWarn(log, "When BinaryMarshaller is used and topology contains old" + + " nodes, it's strongly recommended, to set " + BinaryBasicNameMapper.class.getName() + + " mapper into binary configuration explicitely " + + " and 'simpleName' property of the mapper set to 'true' (fix configuration or set " + + "-D" + IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK + "=true system property)."); + } + + break; + } + } + } + } + + /** {@inheritDoc} */ @Override public void onKernalStop(boolean cancel) { super.onKernalStop(cancel); @@ -578,10 +652,10 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm /** {@inheritDoc} */ @Override public BinaryObject buildEnum(String typeName, int ord) throws IgniteException { - typeName = BinaryContext.typeName(typeName); - int typeId = binaryCtx.typeId(typeName); + typeName = binaryCtx.userTypeName(typeName); + updateMetadata(typeId, typeName, null, null, true); return new BinaryEnumObjectImpl(binaryCtx, typeId, null, ord); @@ -784,6 +858,37 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm return marshalToBinary(obj); } + /** {@inheritDoc} */ + @Nullable @Override public IgniteNodeValidationResult validateNode(ClusterNode rmtNode) { + IgniteNodeValidationResult res = super.validateNode(rmtNode); + + if (res != null) + return res; + + if (getBoolean(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK) || !(marsh instanceof BinaryMarshaller)) + return null; + + Object rmtBinaryCfg = rmtNode.attribute(IgniteNodeAttributes.ATTR_BINARY_CONFIGURATION); + + if (rmtNode.version().compareTo(BINARY_CFG_CHECK_SINCE) < 0) + return null; + + ClusterNode locNode = ctx.discovery().localNode(); + + Object locBinaryCfg = locNode.attribute(IgniteNodeAttributes.ATTR_BINARY_CONFIGURATION); + + if (!F.eq(locBinaryCfg, rmtBinaryCfg)) { + String msg = "Local node's binary configuration is not equal to remote node's binary configuration " + + "[locNodeId=%s, rmtNodeId=%s, locBinaryCfg=%s, rmtBinaryCfg=%s]"; + + return new IgniteNodeValidationResult(rmtNode.id(), + String.format(msg, locNode.id(), rmtNode.id(), locBinaryCfg, rmtBinaryCfg), + String.format(msg, rmtNode.id(), locNode.id(), rmtBinaryCfg, locBinaryCfg)); + } + + return null; + } + /** * Processor responsible for metadata update. */