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 473c560b8..e4f3c635d 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,13 @@ 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 + if (labels.isEmpty()) { + labels = ImmutableList.of(); + } else { + labels = ImmutableList.copyOf(labels); + } + 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 96c78c2c3..f98e01e78 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,14 @@ 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.Arrays; import java.util.Comparator; import java.util.List; import org.junit.Test; @@ -98,4 +106,46 @@ 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"); + 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(); + } + } }