From 9758245e3dca75ce909badf8ce3d654ff1a81c3c Mon Sep 17 00:00:00 2001 From: dmitry-fa Date: Thu, 3 Sep 2020 14:04:44 +0300 Subject: [PATCH 1/3] fix: make RowCell serializable regardless given type of the labels parameter --- .../bigtable/data/v2/models/RowCell.java | 4 +- .../bigtable/data/v2/models/RowCellTest.java | 52 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java index 473c560b83..6300691667 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java @@ -20,6 +20,7 @@ import com.google.auto.value.AutoValue; import com.google.cloud.bigtable.data.v2.internal.ByteStringComparator; import com.google.common.collect.ComparisonChain; +import com.google.common.collect.ImmutableList; import com.google.protobuf.ByteString; import java.io.Serializable; import java.util.Comparator; @@ -62,7 +63,8 @@ public static RowCell create( long timestamp, @Nonnull List labels, @Nonnull ByteString value) { - return new AutoValue_RowCell(family, qualifier, timestamp, value, labels); + // Ensure that the list is serializable and optimize for the common case + return new AutoValue_RowCell(family, qualifier, timestamp, value, ImmutableList.copyOf(labels)); } /** The cell's family */ diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java index 96c78c2c33..78def8c608 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java @@ -19,6 +19,15 @@ import com.google.common.collect.ImmutableList; import com.google.protobuf.ByteString; +import com.google.protobuf.LazyStringArrayList; +import com.google.protobuf.UnmodifiableLazyStringList; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.List; import org.junit.Test; @@ -98,4 +107,47 @@ public void compareTest() { RowCell.create("family1", col1, timestamp2, labels1, value1))) .isEqualTo(1); } + + @Test + public void testSerialization() throws IOException, ClassNotFoundException { + LazyStringArrayList lazyList = new LazyStringArrayList(); + lazyList.add("lazy"); + lazyList.add("very lazy"); + UnmodifiableLazyStringList lst; + List[] labelLists = { + Arrays.asList("str1", "str2", "str3"), + ImmutableList.of("string1", "string2"), + new UnmodifiableLazyStringList(lazyList), + new UnmodifiableLazyStringList(LazyStringArrayList.EMPTY) + }; + + for (int i = 0; i < labelLists.length; i++) { + String family = "family_" + i; + ByteString col = ByteString.copyFromUtf8("col_" + i); + long timestamp = 1000L * (i + 1); + List labels = labelLists[i]; + ByteString value = ByteString.copyFromUtf8("value_" + i); + RowCell cell = RowCell.create(family, col, timestamp, labels, value); + RowCell deserialized = (RowCell) serializeDeserialize(cell); + + assertThat(cell.getFamily()).isEqualTo(deserialized.getFamily()); + assertThat(cell.getQualifier()).isEqualTo(deserialized.getQualifier()); + assertThat(cell.getTimestamp()).isEqualTo(deserialized.getTimestamp()); + assertThat(cell.getLabels()).isEqualTo(deserialized.getLabels()); + assertThat(cell.getValue()).isEqualTo(deserialized.getValue()); + } + } + + private static Object serializeDeserialize(Object obj) + throws IOException, ClassNotFoundException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ObjectOutputStream outStream = new ObjectOutputStream(bos)) { + outStream.writeObject(obj); + } + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + try (ObjectInputStream inStream = new ObjectInputStream(bis)) { + return inStream.readObject(); + } + } } From b33307bdf977aed2f6e7f11ad3bbbaa588958454 Mon Sep 17 00:00:00 2001 From: dmitry-fa Date: Thu, 3 Sep 2020 14:36:55 +0300 Subject: [PATCH 2/3] fix: make RowCell serializable regardless given type of the labels parameter --- .../com/google/cloud/bigtable/data/v2/models/RowCellTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java index 78def8c608..f98e01e785 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/RowCellTest.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; @@ -113,7 +112,6 @@ public void testSerialization() throws IOException, ClassNotFoundException { LazyStringArrayList lazyList = new LazyStringArrayList(); lazyList.add("lazy"); lazyList.add("very lazy"); - UnmodifiableLazyStringList lst; List[] labelLists = { Arrays.asList("str1", "str2", "str3"), ImmutableList.of("string1", "string2"), From 020c4374de90bfe63f1689d80bd9f570e1aeac89 Mon Sep 17 00:00:00 2001 From: dmitry-fa Date: Thu, 3 Sep 2020 20:48:53 +0300 Subject: [PATCH 3/3] optimization for an empty labels list --- .../com/google/cloud/bigtable/data/v2/models/RowCell.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java index 6300691667..e4f3c635d3 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowCell.java @@ -64,6 +64,11 @@ public static RowCell create( @Nonnull List labels, @Nonnull ByteString value) { // Ensure that the list is serializable and optimize for the common case + if (labels.isEmpty()) { + labels = ImmutableList.of(); + } else { + labels = ImmutableList.copyOf(labels); + } return new AutoValue_RowCell(family, qualifier, timestamp, value, ImmutableList.copyOf(labels)); }