@@ -34,8 +34,10 @@ public final class Breadcrumb implements JsonUnknown, JsonSerializable, Comparab
3434 /** The type of breadcrumb. */
3535 private @ Nullable String type ;
3636
37+ private static final @ NotNull Map <String , @ NotNull Object > EMPTY_DATA = Collections .emptyMap ();
38+
3739 /** Data associated with this breadcrumb. */
38- private @ NotNull Map <String , @ NotNull Object > data = new ConcurrentHashMap <>() ;
40+ private volatile @ NotNull Map <String , @ NotNull Object > data = EMPTY_DATA ;
3941
4042 /** Dotted strings that indicate what the crumb is or where it comes from. */
4143 private @ Nullable String category ;
@@ -78,9 +80,11 @@ public Breadcrumb(final long timestamp) {
7880 this .type = breadcrumb .type ;
7981 this .category = breadcrumb .category ;
8082 this .origin = breadcrumb .origin ;
81- final Map <String , Object > dataClone = CollectionUtils .newConcurrentHashMap (breadcrumb .data );
82- if (dataClone != null ) {
83- this .data = dataClone ;
83+ if (!breadcrumb .data .isEmpty ()) {
84+ final Map <String , Object > dataClone = CollectionUtils .newConcurrentHashMap (breadcrumb .data );
85+ if (dataClone != null ) {
86+ this .data = dataClone ;
87+ }
8488 }
8589 this .unknown = CollectionUtils .newConcurrentHashMap (breadcrumb .unknown );
8690 this .level = breadcrumb .level ;
@@ -100,7 +104,7 @@ public static Breadcrumb fromMap(
100104 @ NotNull Date timestamp = DateUtils .getCurrentDateTime ();
101105 String message = null ;
102106 String type = null ;
103- @ NotNull Map <String , Object > data = new ConcurrentHashMap <>() ;
107+ Map <String , Object > data = null ;
104108 String category = null ;
105109 String origin = null ;
106110 SentryLevel level = null ;
@@ -129,6 +133,9 @@ public static Breadcrumb fromMap(
129133 if (untypedData != null ) {
130134 for (Map .Entry <Object , Object > dataEntry : untypedData .entrySet ()) {
131135 if (dataEntry .getKey () instanceof String && dataEntry .getValue () != null ) {
136+ if (data == null ) {
137+ data = new ConcurrentHashMap <>();
138+ }
132139 data .put ((String ) dataEntry .getKey (), dataEntry .getValue ());
133140 } else {
134141 options
@@ -166,7 +173,9 @@ public static Breadcrumb fromMap(
166173 final Breadcrumb breadcrumb = new Breadcrumb (timestamp );
167174 breadcrumb .message = message ;
168175 breadcrumb .type = type ;
169- breadcrumb .data = data ;
176+ if (data != null ) {
177+ breadcrumb .data = data ;
178+ }
170179 breadcrumb .category = category ;
171180 breadcrumb .origin = origin ;
172181 breadcrumb .level = level ;
@@ -494,7 +503,7 @@ public static Breadcrumb fromMap(
494503 breadcrumb .setData ("view.tag" , viewTag );
495504 }
496505 for (final Map .Entry <String , Object > entry : additionalData .entrySet ()) {
497- breadcrumb .getData (). put (entry .getKey (), entry .getValue ());
506+ breadcrumb .setData (entry .getKey (), entry .getValue ());
498507 }
499508 breadcrumb .setLevel (SentryLevel .INFO );
500509 return breadcrumb ;
@@ -598,6 +607,20 @@ public void setType(@Nullable String type) {
598607 this .type = type ;
599608 }
600609
610+ private @ NotNull Map <String , @ NotNull Object > getOrCreateData () {
611+ Map <String , @ NotNull Object > currentData = data ;
612+ if (currentData == EMPTY_DATA ) {
613+ synchronized (this ) {
614+ currentData = data ;
615+ if (currentData == EMPTY_DATA ) {
616+ currentData = new ConcurrentHashMap <>();
617+ data = currentData ;
618+ }
619+ }
620+ }
621+ return currentData ;
622+ }
623+
601624 /**
602625 * Returns the data map
603626 *
@@ -606,7 +629,7 @@ public void setType(@Nullable String type) {
606629 @ ApiStatus .Internal
607630 @ NotNull
608631 public Map <String , Object > getData () {
609- return data ;
632+ return getOrCreateData () ;
610633 }
611634
612635 /**
@@ -636,7 +659,7 @@ public void setData(@Nullable String key, @Nullable Object value) {
636659 if (value == null ) {
637660 removeData (key );
638661 } else {
639- data .put (key , value );
662+ getOrCreateData () .put (key , value );
640663 }
641664 }
642665
@@ -649,7 +672,10 @@ public void removeData(@Nullable String key) {
649672 if (key == null ) {
650673 return ;
651674 }
652- data .remove (key );
675+ final Map <String , @ NotNull Object > currentData = data ;
676+ if (currentData != EMPTY_DATA ) {
677+ currentData .remove (key );
678+ }
653679 }
654680
655681 /**
@@ -859,7 +885,7 @@ public static final class Deserializer implements JsonDeserializer<Breadcrumb> {
859885 @ NotNull Date timestamp = DateUtils .getCurrentDateTime ();
860886 String message = null ;
861887 String type = null ;
862- @ NotNull Map <String , Object > data = new ConcurrentHashMap <>() ;
888+ Map <String , Object > data = null ;
863889 String category = null ;
864890 String origin = null ;
865891 SentryLevel level = null ;
@@ -884,7 +910,7 @@ public static final class Deserializer implements JsonDeserializer<Breadcrumb> {
884910 Map <String , Object > deserializedData =
885911 CollectionUtils .newConcurrentHashMap (
886912 (Map <String , Object >) reader .nextObjectOrNull ());
887- if (deserializedData != null ) {
913+ if (deserializedData != null && ! deserializedData . isEmpty () ) {
888914 data = deserializedData ;
889915 }
890916 break ;
@@ -913,7 +939,9 @@ public static final class Deserializer implements JsonDeserializer<Breadcrumb> {
913939 Breadcrumb breadcrumb = new Breadcrumb (timestamp );
914940 breadcrumb .message = message ;
915941 breadcrumb .type = type ;
916- breadcrumb .data = data ;
942+ if (data != null ) {
943+ breadcrumb .data = data ;
944+ }
917945 breadcrumb .category = category ;
918946 breadcrumb .origin = origin ;
919947 breadcrumb .level = level ;
0 commit comments