Skip to content

Commit

Permalink
fix: RowCells are not actually serializeable (#407)
Browse files Browse the repository at this point in the history
* fix: make RowCell serializable regardless given type of the labels parameter

* fix: make RowCell serializable regardless given type of the labels parameter

* optimization for an empty labels list
  • Loading branch information
dmitry-fa committed Sep 8, 2020
1 parent 0e0e802 commit 39e17cc
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
Expand Up @@ -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;
Expand Down Expand Up @@ -62,7 +63,13 @@ public static RowCell create(
long timestamp,
@Nonnull List<String> 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 */
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String> 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();
}
}
}

0 comments on commit 39e17cc

Please sign in to comment.