Skip to content

Commit bc109ba

Browse files
committed
wip: add poolable map of tag
1 parent 17c7fcf commit bc109ba

File tree

18 files changed

+452
-92
lines changed

18 files changed

+452
-92
lines changed

dd-trace-core/src/main/java/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import datadog.communication.serialization.msgpack.MsgPackWriter;
1010
import datadog.trace.api.DDTags;
1111
import datadog.trace.api.DDTraceId;
12-
import datadog.trace.api.TagMap;
1312
import datadog.trace.api.civisibility.CiVisibilityWellKnownTags;
1413
import datadog.trace.api.civisibility.InstrumentationBridge;
1514
import datadog.trace.api.civisibility.telemetry.CiVisibilityDistributionMetric;
@@ -317,7 +316,7 @@ MetaWriter withWritable(Writable writable) {
317316

318317
@Override
319318
public void accept(Metadata metadata) {
320-
TagMap tags = metadata.getTags().copy();
319+
Map<String, Object> tags = new HashMap<>(metadata.getTags());
321320

322321
for (String ignoredTag : DEFAULT_TOP_LEVEL_TAGS) {
323322
tags.remove(ignoredTag);

dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,9 @@ void write(final List<DDSpan> trace) {
12561256
if (null != rootSpan) {
12571257
onRootSpanFinished(rootSpan, rootSpan.getEndpointTracker());
12581258
}
1259+
for (DDSpan span : writtenTrace) {
1260+
span.context().releaseTags();
1261+
}
12591262
}
12601263

12611264
private List<DDSpan> interceptCompleteTrace(List<DDSpan> trace) {

dd-trace-core/src/main/java/datadog/trace/core/DDSpanContext.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import datadog.trace.api.DDTraceId;
1212
import datadog.trace.api.Functions;
1313
import datadog.trace.api.ProcessTags;
14+
import datadog.trace.api.SimplePooledMap;
1415
import datadog.trace.api.TagMap;
1516
import datadog.trace.api.cache.DDCache;
1617
import datadog.trace.api.cache.DDCaches;
@@ -93,6 +94,7 @@ public class DDSpanContext
9394

9495
private volatile short httpStatusCode;
9596
private CharSequence integrationName;
97+
private final String poolKey;
9698

9799
/**
98100
* Tags are associated to the current span, they will not propagate to the children span.
@@ -103,7 +105,7 @@ public class DDSpanContext
103105
* rather read and accessed in a serial fashion on thread after thread. The synchronization can
104106
* then be wrapped around bulk operations to minimize the costly atomic operations.
105107
*/
106-
private final TagMap unsafeTags;
108+
private final SimplePooledMap unsafeTags;
107109

108110
/** The service name is required, otherwise the span are dropped by the agent */
109111
private volatile String serviceName;
@@ -112,10 +114,13 @@ public class DDSpanContext
112114
private volatile CharSequence resourceName;
113115

114116
private volatile byte resourceNamePriority = ResourceNamePriorities.DEFAULT;
117+
115118
/** Each span have an operation name describing the current span */
116119
private volatile CharSequence operationName;
120+
117121
/** The type of the span. If null, the Datadog Agent will report as a custom */
118122
private volatile CharSequence spanType;
123+
119124
/** True indicates that the span reports an error */
120125
private volatile boolean errorFlag;
121126

@@ -351,7 +356,8 @@ public DDSpanContext(
351356
// The +1 is the magic number from the tags below that we set at the end,
352357
// and "* 4 / 3" is to make sure that we don't resize immediately
353358
final int capacity = Math.max((tagsSize <= 0 ? 3 : (tagsSize + 1)) * 4 / 3, 8);
354-
this.unsafeTags = TagMap.create(capacity);
359+
this.poolKey = operationName != null ? operationName.toString() : "";
360+
this.unsafeTags = SimplePooledMap.acquire(poolKey, capacity);
355361

356362
// must set this before setting the service and resource names below
357363
this.profilingContextIntegration = profilingContextIntegration;
@@ -790,7 +796,7 @@ void setAllTags(final TagMap map, boolean needsIntercept) {
790796
Object value = tagEntry.objectValue();
791797

792798
if (!tagInterceptor.interceptTag(ctx, tag, value)) {
793-
ctx.unsafeTags.set(tagEntry);
799+
ctx.unsafeTags.put(tag, value);
794800
}
795801
});
796802
} else {
@@ -816,7 +822,7 @@ void setAllTags(final TagMap.Ledger ledger) {
816822
Object value = entry.objectValue();
817823

818824
if (!tagInterceptor.interceptTag(this, tag, value)) {
819-
unsafeTags.set(entry);
825+
unsafeTags.put(tag, value);
820826
}
821827
}
822828
}
@@ -863,6 +869,10 @@ Object getTag(final String key) {
863869
}
864870
}
865871

872+
void releaseTags() {
873+
SimplePooledMap.release(poolKey, unsafeTags);
874+
}
875+
866876
/**
867877
* This is not thread-safe and must only be used when it can be guaranteed that the context will
868878
* not be mutated. This is internal API and must not be exposed to users.
@@ -871,13 +881,13 @@ Object getTag(final String key) {
871881
* @return the value associated with the tag
872882
*/
873883
public Object unsafeGetTag(final String tag) {
874-
return unsafeTags.getObject(tag);
884+
return unsafeTags.get(tag);
875885
}
876886

877887
@Deprecated
878888
public TagMap getTags() {
879889
synchronized (unsafeTags) {
880-
TagMap tags = unsafeTags.copy();
890+
TagMap tags = TagMap.fromMap(unsafeTags);
881891

882892
tags.put(DDTags.THREAD_ID, threadId);
883893
// maintain previously observable type of the thread name :|

dd-trace-core/src/main/java/datadog/trace/core/Metadata.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22

33
import static datadog.trace.api.sampling.PrioritySampling.UNSET;
44

5-
import datadog.trace.api.TagMap;
65
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
76
import java.util.Map;
87

98
public final class Metadata {
109
private final long threadId;
1110
private final UTF8BytesString threadName;
1211
private final UTF8BytesString httpStatusCode;
13-
private final TagMap tags;
12+
private final Map<String, Object> tags;
1413
private final Map<String, String> baggage;
1514

1615
private final int samplingPriority;
@@ -23,7 +22,7 @@ public final class Metadata {
2322
public Metadata(
2423
long threadId,
2524
UTF8BytesString threadName,
26-
TagMap tags,
25+
Map<String, Object> tags,
2726
Map<String, String> baggage,
2827
int samplingPriority,
2928
boolean measured,
@@ -61,7 +60,7 @@ public UTF8BytesString getThreadName() {
6160
return threadName;
6261
}
6362

64-
public TagMap getTags() {
63+
public Map<String, Object> getTags() {
6564
return this.tags;
6665
}
6766

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
package datadog.trace.core.tagprocessor;
22

33
import datadog.trace.api.DDTags;
4-
import datadog.trace.api.TagMap;
54
import datadog.trace.bootstrap.instrumentation.api.AgentSpanLink;
65
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
76
import datadog.trace.core.DDSpanContext;
87
import java.util.List;
8+
import java.util.Map;
99
import javax.annotation.Nullable;
1010

11-
public final class BaseServiceAdder extends TagsPostProcessor {
11+
public final class BaseServiceAdder implements TagsPostProcessor {
1212
private final UTF8BytesString ddService;
1313

1414
public BaseServiceAdder(@Nullable final String ddService) {
1515
this.ddService = ddService != null ? UTF8BytesString.create(ddService) : null;
1616
}
1717

1818
@Override
19-
public void processTags(
20-
TagMap unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
19+
public Map<String, Object> processTags(
20+
Map<String, Object> unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
2121
if (ddService != null
2222
&& spanContext != null
2323
&& !ddService.toString().equalsIgnoreCase(spanContext.getServiceName())) {
2424
unsafeTags.put(DDTags.BASE_SERVICE, ddService);
2525
unsafeTags.remove("version");
2626
}
27+
return unsafeTags;
2728
}
2829
}

dd-trace-core/src/main/java/datadog/trace/core/tagprocessor/IntegrationAdder.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22

33
import static datadog.trace.api.DDTags.DD_INTEGRATION;
44

5-
import datadog.trace.api.TagMap;
65
import datadog.trace.bootstrap.instrumentation.api.AgentSpanLink;
76
import datadog.trace.core.DDSpanContext;
87
import java.util.List;
8+
import java.util.Map;
99

10-
public class IntegrationAdder extends TagsPostProcessor {
10+
public class IntegrationAdder implements TagsPostProcessor {
1111
@Override
12-
public void processTags(
13-
TagMap unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
12+
public Map<String, Object> processTags(
13+
Map<String, Object> unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
1414
final CharSequence instrumentationName = spanContext.getIntegrationName();
1515
if (instrumentationName != null) {
16-
unsafeTags.set(DD_INTEGRATION, instrumentationName);
16+
unsafeTags.put(DD_INTEGRATION, instrumentationName);
1717
} else {
1818
unsafeTags.remove(DD_INTEGRATION);
1919
}
20+
return unsafeTags;
2021
}
2122
}

dd-trace-core/src/main/java/datadog/trace/core/tagprocessor/PayloadTagsProcessor.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import datadog.trace.api.Config;
66
import datadog.trace.api.ConfigDefaults;
7-
import datadog.trace.api.TagMap;
87
import datadog.trace.api.telemetry.LogCollector;
98
import datadog.trace.bootstrap.instrumentation.api.AgentSpanLink;
109
import datadog.trace.core.DDSpanContext;
@@ -22,7 +21,7 @@
2221
import org.slf4j.LoggerFactory;
2322

2423
/** Post-processor that extracts tags from payload data injected as tags by instrumentations. */
25-
public final class PayloadTagsProcessor extends TagsPostProcessor {
24+
public final class PayloadTagsProcessor implements TagsPostProcessor {
2625
private static final Logger log = LoggerFactory.getLogger(PayloadTagsProcessor.class);
2726

2827
private static final String REDACTED = "redacted";
@@ -70,19 +69,17 @@ public static PayloadTagsProcessor create(Config config) {
7069
}
7170

7271
@Override
73-
public void processTags(
74-
TagMap unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
72+
public Map<String, Object> processTags(
73+
Map<String, Object> unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
7574
int spanMaxTags = maxTags + unsafeTags.size();
7675
for (Map.Entry<String, RedactionRules> tagPrefixRedactionRules :
7776
redactionRulesByTagPrefix.entrySet()) {
7877
String tagPrefix = tagPrefixRedactionRules.getKey();
7978
RedactionRules redactionRules = tagPrefixRedactionRules.getValue();
80-
Object tagValue = unsafeTags.getObject(tagPrefix);
79+
Object tagValue = unsafeTags.get(tagPrefix);
8180
if (tagValue instanceof PayloadTagsData) {
82-
if (unsafeTags.remove(tagPrefix)) {
83-
spanMaxTags -= 1;
84-
}
85-
81+
unsafeTags.remove(tagPrefix);
82+
spanMaxTags -= 1;
8683
PayloadTagsData payloadTagsData = (PayloadTagsData) tagValue;
8784
PayloadTagsCollector payloadTagsCollector =
8885
new PayloadTagsCollector(maxDepth, spanMaxTags, redactionRules, tagPrefix, unsafeTags);
@@ -95,6 +92,7 @@ public void processTags(
9592
tagValue);
9693
}
9794
}
95+
return unsafeTags;
9896
}
9997

10098
private void collectPayloadTags(
@@ -181,14 +179,14 @@ private static final class PayloadTagsCollector implements JsonStreamParser.Visi
181179
private final RedactionRules redactionRules;
182180
private final String tagPrefix;
183181

184-
private final TagMap collectedTags;
182+
private final Map<String, Object> collectedTags;
185183

186184
public PayloadTagsCollector(
187185
int maxDepth,
188186
int maxTags,
189187
RedactionRules redactionRules,
190188
String tagPrefix,
191-
TagMap collectedTags) {
189+
Map<String, Object> collectedTags) {
192190
this.maxDepth = maxDepth;
193191
this.maxTags = maxTags;
194192
this.redactionRules = redactionRules;

dd-trace-core/src/main/java/datadog/trace/core/tagprocessor/PeerServiceCalculator.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import datadog.trace.api.Config;
44
import datadog.trace.api.DDTags;
5-
import datadog.trace.api.TagMap;
65
import datadog.trace.api.naming.NamingSchema;
76
import datadog.trace.api.naming.SpanNaming;
87
import datadog.trace.bootstrap.instrumentation.api.AgentSpanLink;
@@ -12,7 +11,7 @@
1211
import java.util.Map;
1312
import javax.annotation.Nonnull;
1413

15-
public final class PeerServiceCalculator extends TagsPostProcessor {
14+
public final class PeerServiceCalculator implements TagsPostProcessor {
1615
private final NamingSchema.ForPeerService peerServiceNaming;
1716

1817
private final Map<String, String> peerServiceMapping;
@@ -33,26 +32,27 @@ public PeerServiceCalculator() {
3332
}
3433

3534
@Override
36-
public void processTags(
37-
TagMap unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
38-
Object peerService = unsafeTags.getObject(Tags.PEER_SERVICE);
35+
public Map<String, Object> processTags(
36+
Map<String, Object> unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
37+
Object peerService = unsafeTags.get(Tags.PEER_SERVICE);
3938
// the user set it
4039
if (peerService != null) {
4140
if (canRemap) {
4241
remapPeerService(unsafeTags, peerService);
43-
return;
42+
return unsafeTags;
4443
}
4544
} else if (peerServiceNaming.supports()) {
4645
// calculate the defaults (if any)
4746
peerServiceNaming.tags(unsafeTags);
4847
// only remap if the mapping is not empty (saves one get)
49-
remapPeerService(unsafeTags, canRemap ? unsafeTags.getObject(Tags.PEER_SERVICE) : null);
50-
return;
48+
remapPeerService(unsafeTags, canRemap ? unsafeTags.get(Tags.PEER_SERVICE) : null);
49+
return unsafeTags;
5150
}
5251
// we have no peer.service and we do not compute defaults. Leave the map untouched
52+
return unsafeTags;
5353
}
5454

55-
private void remapPeerService(TagMap unsafeTags, Object value) {
55+
private void remapPeerService(Map<String, Object> unsafeTags, Object value) {
5656
if (value != null) {
5757
String mapped = peerServiceMapping.get(value);
5858
if (mapped != null) {
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
package datadog.trace.core.tagprocessor;
22

3-
import datadog.trace.api.TagMap;
43
import datadog.trace.bootstrap.instrumentation.api.AgentSpanLink;
54
import datadog.trace.core.DDSpanContext;
65
import java.util.List;
6+
import java.util.Map;
77
import java.util.Objects;
88
import javax.annotation.Nonnull;
99

10-
public final class PostProcessorChain extends TagsPostProcessor {
10+
public final class PostProcessorChain implements TagsPostProcessor {
1111
private final TagsPostProcessor[] chain;
1212

1313
public PostProcessorChain(@Nonnull final TagsPostProcessor... processors) {
1414
chain = Objects.requireNonNull(processors);
1515
}
1616

1717
@Override
18-
public void processTags(
19-
TagMap unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
18+
public Map<String, Object> processTags(
19+
Map<String, Object> unsafeTags, DDSpanContext spanContext, List<AgentSpanLink> spanLinks) {
2020
for (final TagsPostProcessor tagsPostProcessor : chain) {
2121
tagsPostProcessor.processTags(unsafeTags, spanContext, spanLinks);
2222
}
23+
return unsafeTags;
2324
}
2425
}

0 commit comments

Comments
 (0)