Skip to content

Commit bae76f8

Browse files
Optimization of traceId serialization: do not allocate temporary buffer.
1 parent c9a31a6 commit bae76f8

6 files changed

Lines changed: 46 additions & 18 deletions

File tree

communication/src/main/java/datadog/communication/serialization/Writable.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public interface Writable {
2727

2828
void writeBinary(byte[] binary, int offset, int length);
2929

30+
void writeBinary(long hi, long lo);
31+
3032
/**
3133
* Start a part of the message containing key-value pairs
3234
*

communication/src/main/java/datadog/communication/serialization/msgpack/MsgPackWriter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,13 @@ public void writeBinary(byte[] binary, int offset, int length) {
213213
buffer.put(binary, offset, length);
214214
}
215215

216+
@Override
217+
public void writeBinary(long hi, long lo) {
218+
writeBinaryHeader(16);
219+
buffer.putLong(hi);
220+
buffer.putLong(lo);
221+
}
222+
216223
@Override
217224
public void writeBinary(ByteBuffer binary) {
218225
ByteBuffer slice = binary.slice();

communication/src/test/java/datadog/communication/serialization/msgpack/MsgPackWriterTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,28 @@ public void testWriteBinaryNoArgVariant() {
154154
writer.writeBinary("foobar".getBytes(UTF_8));
155155
}
156156

157+
@Test
158+
public void testWriteBinaryLongPair() {
159+
final long hi = 0x1122334455667788L;
160+
final long lo = 0x99AABBCCDDEEFF00L;
161+
final byte[] data = ByteBuffer.allocate(16).putLong(hi).putLong(lo).array();
162+
MessageFormatter messageFormatter =
163+
new MsgPackWriter(
164+
newBuffer(
165+
25,
166+
(messageCount, buffy) -> {
167+
try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(buffy)) {
168+
int length = unpacker.unpackBinaryHeader();
169+
assertEquals(16, length);
170+
assertArrayEquals(data, unpacker.readPayload(length));
171+
} catch (IOException e) {
172+
fail(e.getMessage());
173+
}
174+
}));
175+
messageFormatter.format(data, (ignored, writable) -> writable.writeBinary(hi, lo));
176+
messageFormatter.flush();
177+
}
178+
157179
@Test
158180
public void testWriteBinaryAsObject() {
159181
final byte[] data = new byte[] {1, 2, 3, 4};

dd-trace-api/src/main/java/datadog/trace/api/DDTraceId.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package datadog.trace.api;
22

33
import datadog.trace.api.internal.util.LongStringUtils;
4-
import java.nio.ByteBuffer;
54

65
/**
76
* Class encapsulating the id used for TraceIds.
@@ -103,14 +102,4 @@ public static DDTraceId fromHex(String s) throws NumberFormatException {
103102
* <code>0</code> for 64-bit {@link DDTraceId} only.
104103
*/
105104
public abstract long toHighOrderLong();
106-
107-
/**
108-
* @return High-order and low-order bits as bytes array.
109-
*/
110-
public byte[] to128BitBytes() {
111-
ByteBuffer buffer = ByteBuffer.allocate(16);
112-
buffer.putLong(toHighOrderLong());
113-
buffer.putLong(toLong());
114-
return buffer.array();
115-
}
116105
}

dd-trace-core/src/main/java/datadog/trace/common/writer/ddagent/TraceMapperV1.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import datadog.environment.JavaVirtualMachine;
1414
import datadog.trace.api.Config;
1515
import datadog.trace.api.DDTags;
16+
import datadog.trace.api.DDTraceId;
1617
import datadog.trace.api.ProcessTags;
1718
import datadog.trace.api.TagMap;
1819
import datadog.trace.api.sampling.SamplingMechanism;
@@ -97,7 +98,7 @@ public void map(List<? extends CoreSpan<?>> trace, Writable writable) {
9798
// spans = 4, a list of spans in this chunk
9899
encodeSpans(writable, 4, trace);
99100
// traceID = 6, the ID of the trace to which all spans in this chunk belong
100-
encodeBytes(writable, 6, firstSpan.getTraceId().to128BitBytes());
101+
encodeTraceId(writable, 6, firstSpan.getTraceId());
101102
// samplingMechanism = 7, uint32
102103
encodeInt(writable, 7, parseSamplingMechanism(firstSpanMeta.getTags()));
103104
}
@@ -184,7 +185,7 @@ private void encodeSpanLinks(
184185
for (AgentSpanLink link : links) {
185186
writable.startMap(5);
186187
// 1: the ID of the trace that this link targets
187-
encodeBytes(writable, 1, link.traceId().to128BitBytes());
188+
encodeTraceId(writable, 1, link.traceId());
188189
// 2: the ID of the span that this link targets, fixed64
189190
encodeLongUnsigned(writable, 2, link.spanId());
190191
// 3: a collection of attribute string key to value pairs on the link, map<uint32, AnyValue>
@@ -522,9 +523,9 @@ private void encodeString(Writable writable, int fieldId, CharSequence value) {
522523
writeStreamingString(writable, value);
523524
}
524525

525-
private void encodeBytes(Writable writable, int fieldId, byte[] value) {
526+
private void encodeTraceId(Writable writable, int fieldId, DDTraceId traceId) {
526527
writable.writeInt(fieldId);
527-
writable.writeBinary(value);
528+
writable.writeBinary(traceId.toHighOrderLong(), traceId.toLong());
528529
}
529530

530531
/** Writes a string using the streaming string table encoding. */

dd-trace-core/src/test/groovy/datadog/trace/common/writer/ddagent/TraceMapperV1PayloadTest.groovy

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,13 +349,13 @@ class TraceMapperV1PayloadTest extends DDSpecification {
349349

350350
then:
351351
assertEquals(2, links.size())
352-
assertArrayEquals(DDTraceId.fromHex("11223344556677889900aabbccddeeff").to128BitBytes(), links[0].traceId as byte[])
352+
assertArrayEquals(traceIdBytes(DDTraceId.fromHex("11223344556677889900aabbccddeeff")), links[0].traceId as byte[])
353353
assertEquals(DDSpanId.fromHex("000000000000002a"), links[0].spanId)
354354
assertEquals("dd=s:1", links[0].tracestate)
355355
assertEquals(1L, links[0].flags)
356356
assertEquals(["link.kind": "follows_from", "context_headers": "tracecontext"], links[0].attributes)
357357

358-
assertArrayEquals(DDTraceId.fromHex("00000000000000000000000000000001").to128BitBytes(), links[1].traceId as byte[])
358+
assertArrayEquals(traceIdBytes(DDTraceId.fromHex("00000000000000000000000000000001")), links[1].traceId as byte[])
359359
assertEquals(DDSpanId.fromHex("0000000000000002"), links[1].spanId)
360360
assertEquals("", links[1].tracestate)
361361
assertEquals(0L, links[1].flags)
@@ -846,10 +846,17 @@ class TraceMapperV1PayloadTest extends DDSpecification {
846846
assertEqualsWithNullAsEmpty(firstSpan.getOrigin(), origin)
847847
assertEquals(1, chunkAttributes.size())
848848
assertEqualsWithNullAsEmpty(firstSpan.getLocalRootSpan().getServiceName(), chunkAttributes.get("service"))
849-
assertArrayEquals(firstSpan.getTraceId().to128BitBytes(), traceId)
849+
assertArrayEquals(traceIdBytes(firstSpan.getTraceId()), traceId)
850850
assertEquals(expectedSamplingMechanism(firstSpan.getTags()), samplingMechanism)
851851
}
852852

853+
private static byte[] traceIdBytes(DDTraceId traceId) {
854+
ByteBuffer.allocate(16)
855+
.putLong(traceId.toHighOrderLong())
856+
.putLong(traceId.toLong())
857+
.array()
858+
}
859+
853860
private static List<TraceGenerator.PojoSpan> verifySpans(
854861
MessageUnpacker unpacker,
855862
List<TraceGenerator.PojoSpan> expectedTrace,

0 commit comments

Comments
 (0)