Skip to content

Commit 4174006

Browse files
committed
Don't populate a map to populate the tags map
1 parent 235d290 commit 4174006

File tree

12 files changed

+81
-63
lines changed

12 files changed

+81
-63
lines changed

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

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ public class CoreSpanBuilder implements AgentTracer.SpanBuilder {
455455
private final String operationName;
456456

457457
// Builder attributes
458-
private final Map<String, Object> tags = new LinkedHashMap<String, Object>(defaultSpanTags);
458+
private Map<String, Object> tags;
459459
private long timestampMicro;
460460
private Object parent;
461461
private String serviceName;
@@ -542,10 +542,14 @@ public CoreSpanBuilder asChildOf(final AgentSpan agentSpan) {
542542

543543
@Override
544544
public CoreSpanBuilder withTag(final String tag, final Object value) {
545+
Map<String, Object> tagMap = this.tags;
546+
if (tagMap == null) {
547+
tags = tagMap = new LinkedHashMap<>(); // Insertion order is important
548+
}
545549
if (value == null || (value instanceof String && ((String) value).isEmpty())) {
546-
tags.remove(tag);
550+
tagMap.remove(tag);
547551
} else {
548-
tags.put(tag, value);
552+
tagMap.put(tag, value);
549553
}
550554
return this;
551555
}
@@ -564,6 +568,8 @@ private DDSpanContext buildSpanContext() {
564568
final PendingTrace parentTrace;
565569
final int samplingPriority;
566570
final String origin;
571+
final Map<String, String> coreTags;
572+
final Map<String, String> rootSpanTags;
567573

568574
final DDSpanContext context;
569575

@@ -589,6 +595,8 @@ private DDSpanContext buildSpanContext() {
589595
parentTrace = ddsc.getTrace();
590596
samplingPriority = PrioritySampling.UNSET;
591597
origin = null;
598+
coreTags = null;
599+
rootSpanTags = null;
592600
if (serviceName == null) {
593601
serviceName = ddsc.getServiceName();
594602
}
@@ -611,13 +619,14 @@ private DDSpanContext buildSpanContext() {
611619

612620
// Get header tags and set origin whether propagating or not.
613621
if (parentContext instanceof TagContext) {
614-
tags.putAll(((TagContext) parentContext).getTags());
622+
coreTags = ((TagContext) parentContext).getTags();
615623
origin = ((TagContext) parentContext).getOrigin();
616624
} else {
625+
coreTags = null;
617626
origin = null;
618627
}
619628

620-
tags.putAll(localRootSpanTags);
629+
rootSpanTags = localRootSpanTags;
621630

622631
parentTrace = PendingTrace.create(CoreTracer.this, traceId);
623632
}
@@ -628,6 +637,11 @@ private DDSpanContext buildSpanContext() {
628637

629638
final String operationName = this.operationName != null ? this.operationName : resourceName;
630639

640+
int tagsSize =
641+
(null == tags ? 0 : tags.size())
642+
+ defaultSpanTags.size()
643+
+ (null == coreTags ? 0 : coreTags.size())
644+
+ (null == rootSpanTags ? 0 : rootSpanTags.size());
631645
// some attributes are inherited from the parent
632646
context =
633647
new DDSpanContext(
@@ -642,40 +656,18 @@ private DDSpanContext buildSpanContext() {
642656
baggage,
643657
errorFlag,
644658
spanType,
645-
tags,
659+
tagsSize,
646660
parentTrace,
647661
CoreTracer.this,
648662
serviceNameMappings);
649663

650-
// Apply Decorators to handle any tags that may have been set via the builder.
651-
for (final Map.Entry<String, Object> tag : tags.entrySet()) {
652-
if (tag.getValue() == null) {
653-
context.setTag(tag.getKey(), null);
654-
continue;
655-
}
656-
657-
boolean addTag = true;
658-
659-
// Call interceptors
660-
final List<AbstractTagInterceptor> interceptors = getSpanTagInterceptors(tag.getKey());
661-
if (interceptors != null) {
662-
for (final AbstractTagInterceptor interceptor : interceptors) {
663-
try {
664-
addTag &= interceptor.shouldSetTag(context, tag.getKey(), tag.getValue());
665-
} catch (final Throwable ex) {
666-
log.debug(
667-
"Could not intercept the span interceptor={}: {}",
668-
interceptor.getClass().getSimpleName(),
669-
ex.getMessage());
670-
}
671-
}
672-
}
673-
674-
if (!addTag) {
675-
context.setTag(tag.getKey(), null);
676-
}
677-
}
678-
664+
// By setting the tags on the context we apply decorators to any tags that have been set via
665+
// the builder. This is the order that the tags were added previously, but maybe the `tags`
666+
// set in the builder should come last, so that they override other tags.
667+
context.setAllTags(defaultSpanTags);
668+
context.setAllTags(tags);
669+
context.setAllTags(coreTags);
670+
context.setAllTags(rootSpanTags);
679671
return context;
680672
}
681673
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,12 @@ public AgentSpan removeTag(final String tag) {
233233
}
234234

235235
public Object getAndRemoveTag(final String tag) {
236-
return context.getTags().remove(tag);
236+
return context.getAndRemoveTag(tag);
237237
}
238238

239239
@Override
240240
public Object getTag(final String tag) {
241-
return context.getTags().get(tag);
241+
return context.getTag(tag);
242242
}
243243

244244
@Override

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

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public class DDSpanContext implements AgentSpan.Context {
4545
private final DDId parentId;
4646

4747
/** Tags are associated to the current span, they will not propagate to the children span */
48-
private final Map<String, Object> tags = new ConcurrentHashMap<>();
48+
private final Map<String, Object> tags;
4949

5050
/** The service name is required, otherwise the span are dropped by the agent */
5151
private volatile String serviceName;
@@ -69,10 +69,6 @@ public class DDSpanContext implements AgentSpan.Context {
6969
/** Metrics on the span */
7070
private final AtomicReference<Map<String, Number>> metrics = new AtomicReference<>();
7171

72-
// Additional Metadata
73-
private final String threadName = Thread.currentThread().getName();
74-
private final long threadId = Thread.currentThread().getId();
75-
7672
private final Map<String, String> serviceNameMappings;
7773

7874
public DDSpanContext(
@@ -87,7 +83,7 @@ public DDSpanContext(
8783
final Map<String, String> baggageItems,
8884
final boolean errorFlag,
8985
final String spanType,
90-
final Map<String, Object> tags,
86+
final int tagsSize,
9187
final PendingTrace trace,
9288
final CoreTracer tracer,
9389
final Map<String, String> serviceNameMappings) {
@@ -110,9 +106,10 @@ public DDSpanContext(
110106
this.baggageItems = new ConcurrentHashMap<>(baggageItems);
111107
}
112108

113-
if (tags != null) {
114-
this.tags.putAll(tags);
115-
}
109+
// Three is the magic number from the tags below that we set at the end,
110+
// and "* 4 / 3" is to make sure that we don't resize immediately
111+
int capacity = ((tagsSize <= 0 ? 3 : tagsSize + 3) * 4) / 3;
112+
this.tags = new ConcurrentHashMap<>(capacity);
116113

117114
this.serviceNameMappings = serviceNameMappings;
118115
setServiceName(serviceName);
@@ -129,8 +126,10 @@ public DDSpanContext(
129126
if (origin != null) {
130127
this.tags.put(ORIGIN_KEY, origin);
131128
}
132-
this.tags.put(DDTags.THREAD_NAME, threadName);
133-
this.tags.put(DDTags.THREAD_ID, threadId);
129+
// Additional Metadata
130+
Thread current = Thread.currentThread();
131+
this.tags.put(DDTags.THREAD_NAME, current.getName());
132+
this.tags.put(DDTags.THREAD_ID, current.getId());
134133
}
135134

136135
@Override
@@ -322,7 +321,25 @@ public void setMetric(final String key, final Number value) {
322321
* @param tag the tag-name
323322
* @param value the value of the tag. tags with null values are ignored.
324323
*/
325-
public synchronized void setTag(final String tag, final Object value) {
324+
public void setTag(final String tag, final Object value) {
325+
synchronized (tags) {
326+
internalSetTag(tag, value);
327+
}
328+
}
329+
330+
void setAllTags(final Map<String, ? extends Object> map) {
331+
if (map == null) {
332+
return;
333+
}
334+
335+
synchronized (tags) {
336+
for (final Map.Entry<String, ? extends Object> tag : map.entrySet()) {
337+
internalSetTag(tag.getKey(), tag.getValue());
338+
}
339+
}
340+
}
341+
342+
private void internalSetTag(final String tag, final Object value) {
326343
if (value == null || (value instanceof String && ((String) value).isEmpty())) {
327344
tags.remove(tag);
328345
return;
@@ -350,6 +367,14 @@ public synchronized void setTag(final String tag, final Object value) {
350367
}
351368
}
352369

370+
Object getTag(final String key) {
371+
return tags.get(key);
372+
}
373+
374+
Object getAndRemoveTag(final String tag) {
375+
return tags.remove(tag);
376+
}
377+
353378
public Map<String, Object> getTags() {
354379
return tags;
355380
}

dd-trace-core/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class DDAgentWriterTest extends DDSpecification {
203203
[:],
204204
false,
205205
"",
206-
[:],
206+
0,
207207
Mock(PendingTrace),
208208
Mock(CoreTracer),
209209
[:])
@@ -283,7 +283,7 @@ class DDAgentWriterTest extends DDSpecification {
283283
[:],
284284
false,
285285
"",
286-
[:],
286+
0,
287287
Mock(PendingTrace),
288288
Mock(CoreTracer),
289289
[:])

dd-trace-core/src/test/groovy/datadog/trace/core/DDSpanSerializationTest.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ class DDSpanSerializationTest extends DDSpecification {
6161
["a-baggage": "value"],
6262
false,
6363
spanType,
64-
["k1": "v1"],
64+
1,
6565
PendingTrace.create(tracer, DDId.ONE),
6666
tracer,
6767
[:])
68+
context.setAllTags(["k1": "v1"])
6869

6970
DDSpan span = DDSpan.create(100L, context)
7071

@@ -97,7 +98,7 @@ class DDSpanSerializationTest extends DDSpecification {
9798
Collections.emptyMap(),
9899
false,
99100
spanType,
100-
Collections.emptyMap(),
101+
0,
101102
PendingTrace.create(tracer, DDId.ONE),
102103
tracer,
103104
[:])

dd-trace-core/src/test/groovy/datadog/trace/core/DDSpanTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class DDSpanTest extends DDSpecification {
3434
Collections.<String, String> emptyMap(),
3535
false,
3636
"fakeType",
37-
null,
37+
0,
3838
PendingTrace.create(tracer, DDId.ONE),
3939
tracer,
4040
[:])

dd-trace-core/src/test/groovy/datadog/trace/core/SpanFactory.groovy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class SpanFactory {
2323
Collections.emptyMap(),
2424
false,
2525
"fakeType",
26-
Collections.emptyMap(),
26+
0,
2727
PendingTrace.create(tracer, DDId.ONE),
2828
tracer, [:])
2929
Thread.currentThread().setName(currentThreadName)
@@ -43,7 +43,7 @@ class SpanFactory {
4343
Collections.emptyMap(),
4444
false,
4545
"fakeType",
46-
Collections.emptyMap(),
46+
0,
4747
PendingTrace.create(tracer, DDId.ONE),
4848
tracer, [:])
4949
return DDSpan.create(1, context)
@@ -62,7 +62,7 @@ class SpanFactory {
6262
Collections.emptyMap(),
6363
false,
6464
"fakeType",
65-
Collections.emptyMap(),
65+
0,
6666
trace,
6767
trace.tracer, [:])
6868
return DDSpan.create(1, context)
@@ -83,7 +83,7 @@ class SpanFactory {
8383
Collections.emptyMap(),
8484
false,
8585
"fakeType",
86-
Collections.emptyMap(),
86+
0,
8787
PendingTrace.create(tracer, DDId.ONE),
8888
tracer,
8989
[:])

dd-trace-core/src/test/groovy/datadog/trace/core/propagation/B3HttpInjectorTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class B3HttpInjectorTest extends DDSpecification {
3939
},
4040
false,
4141
"fakeType",
42-
null,
42+
0,
4343
new PendingTrace(tracer, DDId.ONE),
4444
tracer,
4545
[:])

dd-trace-core/src/test/groovy/datadog/trace/core/propagation/DatadogHttpInjectorTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class DatadogHttpInjectorTest extends DDSpecification {
4141
},
4242
false,
4343
"fakeType",
44-
null,
44+
0,
4545
new PendingTrace(tracer, DDId.ONE),
4646
tracer,
4747
[:])

dd-trace-core/src/test/groovy/datadog/trace/core/propagation/HaystackHttpInjectorTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class HaystackHttpInjectorTest extends DDSpecification {
3939
},
4040
false,
4141
"fakeType",
42-
null,
42+
0,
4343
new PendingTrace(tracer, DDId.ONE),
4444
tracer,
4545
[:])

0 commit comments

Comments
 (0)