Fix repeated string serialization for JSON. (#6888)
Co-authored-by: Jack Berg <jberg@newrelic.com>
This commit is contained in:
parent
6487ac2976
commit
8a3329be4d
|
|
@ -122,6 +122,22 @@ final class JsonSerializer extends Serializer {
|
|||
generator.writeString(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) throws IOException {
|
||||
generator.writeArrayFieldStart(field.getJsonName());
|
||||
for (byte[] value : utf8Bytes) {
|
||||
// Marshalers encoded String into UTF-8 bytes to optimize for binary serialization where
|
||||
// we are able to avoid the encoding process happening twice, one for size computation and one
|
||||
// for actual writing. JsonGenerator actually has a writeUTF8String that would be able to
|
||||
// accept
|
||||
// this, but it only works when writing to an OutputStream, but not to a String like we do for
|
||||
// writing to logs. It's wasteful to take a String, convert it to bytes, and convert back to
|
||||
// the same String but we can see if this can be improved in the future.
|
||||
generator.writeString(new String(value, StandardCharsets.UTF_8));
|
||||
}
|
||||
generator.writeEndArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException {
|
||||
generator.writeBinaryField(field.getJsonName(), value);
|
||||
|
|
|
|||
|
|
@ -110,6 +110,16 @@ public final class MarshalerUtil {
|
|||
return size;
|
||||
}
|
||||
|
||||
/** Returns the size of a repeated string field. */
|
||||
@SuppressWarnings("AvoidObjectArrays")
|
||||
public static int sizeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) {
|
||||
int size = 0;
|
||||
for (byte[] i : utf8Bytes) {
|
||||
size += MarshalerUtil.sizeBytes(field, i);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a repeated uint64 field.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -163,6 +163,13 @@ final class ProtoSerializer extends Serializer implements AutoCloseable {
|
|||
StatelessMarshalerUtil.writeUtf8(output, string, utf8Length, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) throws IOException {
|
||||
for (byte[] value : utf8Bytes) {
|
||||
writeString(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException {
|
||||
output.writeUInt32NoTag(field.getTag());
|
||||
|
|
|
|||
|
|
@ -220,6 +220,18 @@ public abstract class Serializer implements AutoCloseable {
|
|||
writeString(field, utf8Bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a protobuf {@code repeated string} field. {@code utf8Bytes} is the UTF8 encoded
|
||||
* bytes of the strings to serialize.
|
||||
*/
|
||||
@SuppressWarnings("AvoidObjectArrays")
|
||||
public void serializeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) throws IOException {
|
||||
if (utf8Bytes.length == 0) {
|
||||
return;
|
||||
}
|
||||
writeRepeatedString(field, utf8Bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a protobuf {@code string} field. {@code string} is the value to be serialized and
|
||||
* {@code utf8Length} is the length of the string after it is encoded in UTF8. This method reads
|
||||
|
|
@ -246,6 +258,11 @@ public abstract class Serializer implements AutoCloseable {
|
|||
ProtoFieldInfo field, String string, int utf8Length, MarshalerContext context)
|
||||
throws IOException;
|
||||
|
||||
/** Writes a protobuf {@code repeated string} field, even if it matches the default value. */
|
||||
@SuppressWarnings("AvoidObjectArrays")
|
||||
public abstract void writeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes)
|
||||
throws IOException;
|
||||
|
||||
/** Serializes a protobuf {@code bytes} field. */
|
||||
public void serializeBytes(ProtoFieldInfo field, byte[] value) throws IOException {
|
||||
if (value.length == 0) {
|
||||
|
|
|
|||
|
|
@ -149,9 +149,7 @@ final class ProfileMarshaler extends MarshalerWithSize {
|
|||
output.serializeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers);
|
||||
for (byte[] i : stringTable) {
|
||||
output.serializeString(Profile.STRING_TABLE, i);
|
||||
}
|
||||
output.serializeRepeatedString(Profile.STRING_TABLE, stringTable);
|
||||
output.serializeInt64(Profile.DROP_FRAMES, dropFrames);
|
||||
output.serializeInt64(Profile.KEEP_FRAMES, keepFrames);
|
||||
output.serializeInt64(Profile.TIME_NANOS, timeNanos);
|
||||
|
|
@ -192,9 +190,7 @@ final class ProfileMarshaler extends MarshalerWithSize {
|
|||
size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers);
|
||||
for (byte[] i : stringTable) {
|
||||
size += MarshalerUtil.sizeBytes(Profile.STRING_TABLE, i);
|
||||
}
|
||||
size += MarshalerUtil.sizeRepeatedString(Profile.STRING_TABLE, stringTable);
|
||||
size += MarshalerUtil.sizeInt64(Profile.DROP_FRAMES, dropFrames);
|
||||
size += MarshalerUtil.sizeInt64(Profile.KEEP_FRAMES, keepFrames);
|
||||
size += MarshalerUtil.sizeInt64(Profile.TIME_NANOS, timeNanos);
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ public class ProfilesRequestMarshalerTest {
|
|||
Attributes.empty(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
listOf("foo", "bar"),
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
|
|
@ -304,6 +304,8 @@ public class ProfilesRequestMarshalerTest {
|
|||
.AGGREGATION_TEMPORALITY_CUMULATIVE)
|
||||
.build())
|
||||
.addAllComment(listOf(8L, 9L))
|
||||
.addStringTable("foo")
|
||||
.addStringTable("bar")
|
||||
.setDefaultSampleType(10);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue