11package datadog .trace .core ;
22
3+ import com .google .common .collect .ImmutableMap ;
34import datadog .trace .api .DDId ;
45import datadog .trace .api .DDTags ;
56import datadog .trace .api .sampling .PrioritySampling ;
67import datadog .trace .bootstrap .instrumentation .api .AgentSpan ;
78import datadog .trace .core .taginterceptor .AbstractTagInterceptor ;
89import java .util .Collections ;
10+ import java .util .HashMap ;
911import java .util .List ;
1012import java .util .Map ;
1113import java .util .TreeMap ;
@@ -45,7 +47,7 @@ public class DDSpanContext implements AgentSpan.Context {
4547 private final DDId parentId ;
4648
4749 /** Tags are associated to the current span, they will not propagate to the children span */
48- private final Map <String , Object > tags ;
50+ private final Map <String , Object > unsafe_tags ;
4951
5052 /** The service name is required, otherwise the span are dropped by the agent */
5153 private volatile String serviceName ;
@@ -109,7 +111,7 @@ public DDSpanContext(
109111 // Three is the magic number from the tags below that we set at the end,
110112 // and "* 4 / 3" is to make sure that we don't resize immediately
111113 int capacity = ((tagsSize <= 0 ? 3 : tagsSize + 3 ) * 4 ) / 3 ;
112- this .tags = new ConcurrentHashMap <>(capacity );
114+ this .unsafe_tags = new HashMap <>(capacity );
113115
114116 this .serviceNameMappings = serviceNameMappings ;
115117 setServiceName (serviceName );
@@ -124,12 +126,12 @@ public DDSpanContext(
124126 }
125127
126128 if (origin != null ) {
127- this .tags .put (ORIGIN_KEY , origin );
129+ this .unsafe_tags .put (ORIGIN_KEY , origin );
128130 }
129131 // Additional Metadata
130132 Thread current = Thread .currentThread ();
131- this .tags .put (DDTags .THREAD_NAME , current .getName ());
132- this .tags .put (DDTags .THREAD_ID , current .getId ());
133+ this .unsafe_tags .put (DDTags .THREAD_NAME , current .getName ());
134+ this .unsafe_tags .put (DDTags .THREAD_ID , current .getId ());
133135 }
134136
135137 @ Override
@@ -164,7 +166,7 @@ public boolean isResourceNameSet() {
164166 }
165167
166168 public boolean hasResourceName () {
167- return isResourceNameSet () || tags . containsKey (DDTags .RESOURCE_NAME );
169+ return isResourceNameSet () || getTag (DDTags .RESOURCE_NAME ) != null ;
168170 }
169171
170172 public void setResourceName (final CharSequence resourceName ) {
@@ -322,17 +324,17 @@ public void setMetric(final String key, final Number value) {
322324 * @param value the value of the tag. tags with null values are ignored.
323325 */
324326 public void setTag (final String tag , final Object value ) {
325- synchronized (tags ) {
327+ synchronized (unsafe_tags ) {
326328 internalSetTag (tag , value );
327329 }
328330 }
329331
330332 void setAllTags (final Map <String , ? extends Object > map ) {
331- if (map == null ) {
333+ if (map == null || map . isEmpty () ) {
332334 return ;
333335 }
334336
335- synchronized (tags ) {
337+ synchronized (unsafe_tags ) {
336338 for (final Map .Entry <String , ? extends Object > tag : map .entrySet ()) {
337339 internalSetTag (tag .getKey (), tag .getValue ());
338340 }
@@ -341,7 +343,7 @@ void setAllTags(final Map<String, ? extends Object> map) {
341343
342344 private void internalSetTag (final String tag , final Object value ) {
343345 if (value == null || (value instanceof String && ((String ) value ).isEmpty ())) {
344- tags .remove (tag );
346+ unsafe_tags .remove (tag );
345347 return ;
346348 }
347349
@@ -363,20 +365,37 @@ private void internalSetTag(final String tag, final Object value) {
363365 }
364366
365367 if (addTag ) {
366- tags .put (tag , value );
368+ unsafe_tags .put (tag , value );
367369 }
368370 }
369371
370372 Object getTag (final String key ) {
371- return tags .get (key );
373+ synchronized (unsafe_tags ) {
374+ return unsafe_tags .get (key );
375+ }
372376 }
373377
374378 Object getAndRemoveTag (final String tag ) {
375- return tags .remove (tag );
379+ synchronized (unsafe_tags ) {
380+ return unsafe_tags .remove (tag );
381+ }
376382 }
377383
378384 public Map <String , Object > getTags () {
379- return tags ;
385+ synchronized (unsafe_tags ) {
386+ return ImmutableMap .copyOf (unsafe_tags );
387+ }
388+ }
389+
390+ public abstract static class TagsAndBaggageConsumer <E extends Exception > {
391+ public abstract void accept (Map <String , Object > tags , Map <String , String > baggage ) throws E ;
392+ }
393+
394+ public <E extends Exception > void processTagsAndBaggage (TagsAndBaggageConsumer <E > consumer )
395+ throws E {
396+ synchronized (unsafe_tags ) {
397+ consumer .accept (unsafe_tags , baggageItems );
398+ }
380399 }
381400
382401 @ Override
@@ -401,7 +420,9 @@ public String toString() {
401420 s .append (" *errored*" );
402421 }
403422
404- s .append (" tags=" ).append (new TreeMap <>(tags ));
423+ synchronized (unsafe_tags ) {
424+ s .append (" tags=" ).append (new TreeMap <>(unsafe_tags ));
425+ }
405426 return s .toString ();
406427 }
407428}
0 commit comments