You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by tl...@apache.org on 2021/04/29 11:51:41 UTC
[ignite] branch master updated: IGNITE-14610 fix
BinaryBuilderReader doesn't supports reference (HANDLE) to collection
(#9057)
This is an automated email from the ASF dual-hosted git repository.
tledkov 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 dc168e9 IGNITE-14610 fix BinaryBuilderReader doesn't supports reference (HANDLE) to collection (#9057)
dc168e9 is described below
commit dc168e914362d448e02c3f7d2083d2dbcc20ba65
Author: tledkov <tl...@gridgain.com>
AuthorDate: Thu Apr 29 14:51:21 2021 +0300
IGNITE-14610 fix BinaryBuilderReader doesn't supports reference (HANDLE) to collection (#9057)
---
.../binary/builder/BinaryBuilderReader.java | 89 +++++++++++++++-----
.../internal/binary/BinaryMarshallerSelfTest.java | 97 ++++++++++++++++++++++
2 files changed, 165 insertions(+), 21 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
index c46be5d..dc12b09 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
@@ -51,7 +51,7 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
private final BinaryReaderExImpl reader;
/** */
- private final Map<Integer, BinaryObjectBuilderImpl> objMap;
+ private final Map<Integer, Object> objMap;
/** */
private int pos;
@@ -382,19 +382,21 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
case GridBinaryMarshaller.HANDLE: {
int objStart = pos - readIntPositioned(pos + 1);
- BinaryObjectBuilderImpl res = objMap.get(objStart);
+ Object res = objMap.get(objStart);
- if (res == null) {
- res = new BinaryObjectBuilderImpl(new BinaryBuilderReader(this, objStart), objStart);
+ if (res != null)
+ return res;
- objMap.put(objStart, res);
- }
+ // Read handle by position
+ res = getValueQuickly(objStart, len - (objStart - pos));
+
+ objMap.put(objStart, res);
return res;
}
case GridBinaryMarshaller.OBJ: {
- BinaryObjectBuilderImpl res = objMap.get(pos);
+ Object res = objMap.get(pos);
if (res == null) {
res = new BinaryObjectBuilderImpl(new BinaryBuilderReader(this, pos), pos);
@@ -454,8 +456,18 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
case GridBinaryMarshaller.ENUM_ARR:
case GridBinaryMarshaller.OBJ_ARR:
case GridBinaryMarshaller.COL:
- case GridBinaryMarshaller.MAP:
- return new LazyCollection(pos);
+ case GridBinaryMarshaller.MAP: {
+ Object res = objMap.get(pos);
+
+ if (res != null)
+ return res;
+
+ res = new LazyCollection(pos);
+
+ objMap.put(pos, res);
+
+ return res;
+ }
case GridBinaryMarshaller.ENUM: {
if (len == 1) {
@@ -516,13 +528,20 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
case GridBinaryMarshaller.HANDLE: {
int objStart = pos - 1 - readInt();
- BinaryObjectBuilderImpl res = objMap.get(objStart);
+ Object res = objMap.get(objStart);
- if (res == null) {
- res = new BinaryObjectBuilderImpl(new BinaryBuilderReader(this, objStart), objStart);
+ if (res != null)
+ return res;
- objMap.put(objStart, res);
- }
+ // Read handle by position
+ int savedPos = pos;
+ pos = objStart;
+
+ res = parseValue();
+
+ pos = savedPos;
+
+ objMap.put(objStart, res);
return res;
}
@@ -530,7 +549,7 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
case GridBinaryMarshaller.OBJ: {
pos--;
- BinaryObjectBuilderImpl res = objMap.get(pos);
+ Object res = objMap.get(pos);
if (res == null) {
res = new BinaryObjectBuilderImpl(new BinaryBuilderReader(this, pos), pos);
@@ -764,24 +783,52 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
int size = readInt();
byte colType = arr[pos++];
+ Object res = objMap.get(pos);
+ Object parseRes;
+
switch (colType) {
case GridBinaryMarshaller.USER_COL:
case GridBinaryMarshaller.ARR_LIST:
- return new BinaryLazyArrayList(this, size);
+ parseRes = new BinaryLazyArrayList(this, size);
+
+ break;
case GridBinaryMarshaller.LINKED_LIST:
- return new BinaryLazyLinkedList(this, size);
+ parseRes = new BinaryLazyLinkedList(this, size);
+
+ break;
case GridBinaryMarshaller.HASH_SET:
case GridBinaryMarshaller.LINKED_HASH_SET:
- return new BinaryLazySet(this, size);
+ parseRes = new BinaryLazySet(this, size);
+
+ break;
+
+ default:
+ throw new BinaryObjectException("Unknown collection type: " + colType);
+ }
+
+ if (res == null) {
+ objMap.put(pos, parseRes);
+
+ res = parseRes;
}
- throw new BinaryObjectException("Unknown collection type: " + colType);
+ return res;
}
- case GridBinaryMarshaller.MAP:
- return BinaryLazyMap.parseMap(this);
+ case GridBinaryMarshaller.MAP: {
+ Object res = objMap.get(pos);
+ Object parseRes = BinaryLazyMap.parseMap(this);
+
+ if (res == null) {
+ objMap.put(pos, parseRes);
+
+ res = parseRes;
+ }
+
+ return res;
+ }
case GridBinaryMarshaller.ENUM:
return new BinaryBuilderEnum(this);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
index f48bf9a..60f287a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
@@ -43,6 +43,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -52,6 +53,7 @@ import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import com.google.common.collect.ImmutableList;
@@ -89,6 +91,7 @@ import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.internal.util.lang.GridMapEntry;
+import org.apache.ignite.internal.util.lang.IgnitePair;
import org.apache.ignite.internal.util.lang.IgniteThrowableConsumer;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.T2;
@@ -1032,6 +1035,56 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
}
/**
+ * Checks {@link BinaryBuilderReader#parseValue()} for object that contains handles to collection.
+ *
+ * @throws Exception If failed.
+ */
+ @Test
+ public void handleToCollection() throws Exception {
+ final IgnitePair<String>[] fieldsColAndHandle = new IgnitePair[] {
+ new IgnitePair<>("lst", "hndLst"),
+ new IgnitePair<>("linkedLst", "hndLinkedLst"),
+ new IgnitePair<>("map", "hndMap"),
+ new IgnitePair<>("linkedMap", "hndLinkedMap")
+ };
+ BinaryMarshaller m = binaryMarshaller();
+
+ HandleToCollections obj = new HandleToCollections();
+
+ BinaryObject bo = marshal(obj, m);
+
+ for (int i = 0; i < 10; ++i) {
+ BinaryObjectBuilder bob = bo.toBuilder();
+
+ if (i > 0)
+ assertEquals(i - 1, (int)bo.field("a"));
+
+ bob.setField("a", i);
+
+ for (IgnitePair<String> flds : fieldsColAndHandle) {
+ // Different orders to read collection and handle to collection.
+ Object col;
+ Object colHnd;
+
+ if (i % 2 == 0) {
+ col = bob.getField(flds.get1());
+ colHnd = bob.getField(flds.get2());
+ }
+ else {
+ colHnd = bob.getField(flds.get2());
+ col = bob.getField(flds.get1());
+ }
+
+ // Must be assertSame but now BinaryObjectBuilder doesn't support handle to collection.
+ // Now we check only that BinaryObjectBuilder#getField doesn't crash and returns valid collection.
+ assertEquals("Check: " + flds, col, colHnd);
+ }
+
+ bo = bob.build();
+ }
+ }
+
+ /**
*
*/
private static class EnclosingObj implements Serializable {
@@ -5826,4 +5879,48 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
}
}
}
+
+ /** */
+ public static class HandleToCollections {
+ /** */
+ List<Value> lst;
+
+ /** */
+ List<Value> hndLst;
+
+ /** */
+ List<Value> linkedLst;
+
+ /** */
+ List<Value> hndLinkedLst;
+
+ /** */
+ Map<Integer, Value> map;
+
+ /** */
+ Map<Integer, Value> hndMap;
+
+ /** */
+ Map<Integer, Value> linkedMap;
+
+ /** */
+ Map<Integer, Value> hndLinkedMap;
+
+ /** */
+ public HandleToCollections() {
+ lst = new ArrayList<>(Arrays.asList(new Value(0), new Value(1)));
+ hndLst = lst;
+
+ linkedLst = new LinkedList<>(Arrays.asList(new Value(0), new Value(1)));
+ hndLinkedLst = linkedLst;
+
+ map = IntStream.range(0, 1).boxed()
+ .collect(Collectors.toMap(Function.identity(), Value::new));
+ hndMap = map;
+
+ linkedMap = IntStream.range(0, 1).boxed()
+ .collect(Collectors.toMap(Function.identity(), Value::new, (a, b) -> a, LinkedHashMap::new));
+ hndLinkedMap = linkedMap;
+ }
+ }
}