This is an automated email from the ASF dual-hosted git repository. sergeychugunov pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new 73eee77 IGNITE-12911 CacheObjectAdapter#put incorrect offset handling fixed - Fixes #7742. 73eee77 is described below commit 73eee77744e4ee9bf34717947f290bd95caa2ab5 Author: Anton Kalashnikov <kaa....@yandex.ru> AuthorDate: Mon Jun 28 10:42:58 2021 +0300 IGNITE-12911 CacheObjectAdapter#put incorrect offset handling fixed - Fixes #7742. Signed-off-by: Ilya Kasnacheev <ilya.kasnach...@gmail.com> --- .../internal/binary/BinaryEnumObjectImpl.java | 2 +- .../ignite/internal/binary/BinaryObjectImpl.java | 2 +- .../processors/cache/CacheObjectAdapter.java | 23 ++- .../processors/cache/CacheObjectByteArrayImpl.java | 2 +- .../IgniteCachePutKeyAttachedBinaryObjectTest.java | 177 +++++++++++++++++++++ .../ignite/testsuites/IgniteCacheTestSuite8.java | 3 + 6 files changed, 200 insertions(+), 9 deletions(-) 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 c09cda1..d4e3d07 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 @@ -349,7 +349,7 @@ public class BinaryEnumObjectImpl implements BinaryObjectEx, Externalizable, Cac @Override public int putValue(long addr) throws IgniteCheckedException { assert valBytes != null : "Value bytes must be initialized before object is stored"; - return CacheObjectAdapter.putValue(addr, cacheObjectType(), valBytes, 0); + return CacheObjectAdapter.putValue(addr, cacheObjectType(), valBytes); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java index ef654cc..e3873ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java @@ -174,7 +174,7 @@ public final class BinaryObjectImpl extends BinaryObjectExImpl implements Extern /** {@inheritDoc} */ @Override public int putValue(long addr) throws IgniteCheckedException { - return CacheObjectAdapter.putValue(addr, cacheObjectType(), arr, start); + return CacheObjectAdapter.putValue(addr, cacheObjectType(), arr, start, length()); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectAdapter.java index fa51ce5..eb1f3b3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectAdapter.java @@ -82,27 +82,38 @@ public abstract class CacheObjectAdapter implements CacheObject, Externalizable @Override public int putValue(long addr) throws IgniteCheckedException { assert valBytes != null : "Value bytes must be initialized before object is stored"; - return putValue(addr, cacheObjectType(), valBytes, 0); + return putValue(addr, cacheObjectType(), valBytes); } /** * @param addr Write address. * @param type Object type. * @param valBytes Value bytes array. - * @param valOff Value bytes array offset. * @return Offset shift compared to initial address. */ - public static int putValue(long addr, byte type, byte[] valBytes, int valOff) { + public static int putValue(long addr, byte type, byte[] valBytes) { + return putValue(addr, type, valBytes, 0, valBytes.length); + } + + /** + * @param addr Write address. + * @param type Object type. + * @param srcBytes Source value bytes array. + * @param srcOff Start position in sourceBytes. + * @param len Number of bytes for write. + * @return Offset shift compared to initial address. + */ + public static int putValue(long addr, byte type, byte[] srcBytes, int srcOff, int len) { int off = 0; - PageUtils.putInt(addr, off, valBytes.length); + PageUtils.putInt(addr, off, len); off += 4; PageUtils.putByte(addr, off, type); off++; - PageUtils.putBytes(addr, off, valBytes, valOff); - off += valBytes.length - valOff; + PageUtils.putBytes(addr, off, srcBytes, srcOff, len); + off += len; return off; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java index 5c033b6..6eac6a5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java @@ -88,7 +88,7 @@ public class CacheObjectByteArrayImpl implements CacheObject, Externalizable { /** {@inheritDoc} */ @Override public int putValue(long addr) throws IgniteCheckedException { - return CacheObjectAdapter.putValue(addr, cacheObjectType(), val, 0); + return CacheObjectAdapter.putValue(addr, cacheObjectType(), val); } /** {@inheritDoc} */ diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCachePutKeyAttachedBinaryObjectTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCachePutKeyAttachedBinaryObjectTest.java new file mode 100644 index 0000000..91277f8 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCachePutKeyAttachedBinaryObjectTest.java @@ -0,0 +1,177 @@ +/* + * 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.processors.cache; + +import org.apache.ignite.IgniteCache; +import org.apache.ignite.binary.BinaryBasicNameMapper; +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryObjectBuilder; +import org.apache.ignite.configuration.BinaryConfiguration; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.failure.StopNodeFailureHandler; +import org.apache.ignite.internal.binary.BinaryObjectImpl; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Ignore; +import org.junit.Test; + +/** + * + */ +public class IgniteCachePutKeyAttachedBinaryObjectTest extends GridCommonAbstractTest { + /** */ + public static final String CACHE_NAME = "test"; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + return super.getConfiguration(gridName) + .setFailureHandler(new StopNodeFailureHandler()) + .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME)) + // For brevity, not needed to reproduce the issue. + .setBinaryConfiguration(new BinaryConfiguration().setNameMapper(new BinaryBasicNameMapper(true))); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + super.afterTest(); + + stopAllGrids(); + } + + /** + * @throws Exception If failed. + */ + @Test + public void testAttachedBinaryKeyStoredSuccessfullyToNotEmptyCache() throws Exception { + startGrid(0); + + IgniteCache<Object, Object> binCache = grid(0).cache(CACHE_NAME); + + //Ensure that cache not empty. + AttachedKey ordinaryKey = new AttachedKey(0); + + binCache.put(ordinaryKey, 1); + + BinaryObjectBuilder holdBuilder = grid(0).binary().builder(HolderKey.class.getName()); + + //Creating attached key which stores as byte array. + BinaryObjectImpl attachedKey = holdBuilder.setField("id", new AttachedKey(1)) + .build() + .field("id"); + + //Put data with attached key. + binCache.put(attachedKey, 2); + + assertEquals(1, binCache.get(ordinaryKey)); + assertEquals(2, binCache.get(attachedKey)); + } + + /** + * @throws Exception If failed. + */ + @Test + @Ignore("https://issues.apache.org/jira/browse/IGNITE-13080") + public void testKeyRefersToSubkeyInValue() throws Exception { + startGrid(0); + + IgniteCache<CompositeKey, CompositeValue> cache = grid(0).cache(CACHE_NAME); + + SubKey subKey = new SubKey(10); + CompositeKey compositeKey = new CompositeKey(20, subKey); + CompositeValue compositeVal = new CompositeValue("foo", subKey, compositeKey); + + cache.put(compositeKey, compositeVal); + + IgniteCache<Object, Object> binCache = cache.withKeepBinary(); + + BinaryObject binObj = (BinaryObject)binCache.get(compositeKey); + + binCache.put(binObj.field("key"), binObj.toBuilder().setField("val", "bar").build()); + + assertEquals("bar", cache.get(compositeKey).val()); + + assertEquals(1, cache.size()); + } + + /** */ + public static class AttachedKey { + /** */ + public int id; + + /** */ + public AttachedKey(int id) { + this.id = id; + } + } + + /** */ + public static class HolderKey { + /** */ + public AttachedKey key; + } + + /** */ + public static class SubKey { + /** */ + private int subId; + + /** */ + public SubKey(int subId) { + this.subId = subId; + } + } + + /** */ + public static class CompositeKey { + /** */ + private int id; + + /** */ + private SubKey subKey; + + /** */ + public CompositeKey(int id, SubKey subKey) { + this.id = id; + this.subKey = subKey; + } + } + + /** */ + public static class CompositeValue { + /** */ + private String val; + + /** */ + private SubKey subKey; + + /** */ + private CompositeKey key; + + /** */ + public CompositeValue(String val, SubKey subKey, CompositeKey key) { + this.val = val; + this.subKey = subKey; + this.key = key; + } + + /** */ + public String val() { + return val; + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite8.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite8.java index 43784b3..065fff5 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite8.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite8.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.ignite.cache.ClientCreateCacheGroupOnJoinNodeMapsTest; import org.apache.ignite.internal.processors.cache.CacheStoreTxPutAllMultiNodeTest; import org.apache.ignite.internal.processors.cache.GridCacheOrderedPreloadingSelfTest; +import org.apache.ignite.internal.processors.cache.IgniteCachePutKeyAttachedBinaryObjectTest; import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRabalancingDelayedPartitionMapExchangeSelfTest; import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalanceOrderTest; import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingAsyncSelfTest; @@ -80,6 +81,8 @@ public class IgniteCacheTestSuite8 { GridTestUtils.addTestIfNeeded(suite, CleanupRestoredCachesSlowTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, ClientCreateCacheGroupOnJoinNodeMapsTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, IgniteCachePutKeyAttachedBinaryObjectTest.class, ignoredTests); + return suite; } }