Skip to content

Commit 8924def

Browse files
Update Trace.cs
1 parent 2170a32 commit 8924def

1 file changed

Lines changed: 40 additions & 13 deletions

File tree

  • Microsoft.Azure.Cosmos/src/Tracing

Microsoft.Azure.Cosmos/src/Tracing/Trace.cs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,15 @@
55
namespace Microsoft.Azure.Cosmos.Tracing
66
{
77
using System;
8-
using System.Collections.Concurrent;
98
using System.Collections.Generic;
10-
using System.Diagnostics;
11-
using System.Linq;
12-
using System.Runtime.CompilerServices;
13-
using Microsoft.Azure.Cosmos.Tracing.TraceData;
149
using Microsoft.Azure.Documents;
1510

1611
internal sealed class Trace : ITrace
1712
{
1813
private static readonly IReadOnlyDictionary<string, object> EmptyDictionary = new Dictionary<string, object>();
1914
private readonly List<ITrace> children;
20-
private readonly Lazy<ConcurrentDictionary<string, object>> data;
15+
private readonly Lazy<Dictionary<string, object>> data;
16+
private volatile IReadOnlyDictionary<string, object> materializedData = null;
2117
private ValueStopwatch stopwatch;
2218

2319
private Trace(
@@ -35,7 +31,7 @@ private Trace(
3531
this.Component = component;
3632
this.Parent = parent;
3733
this.children = new List<ITrace>();
38-
this.data = new Lazy<ConcurrentDictionary<string, object>>(() => new ConcurrentDictionary<string, object>());
34+
this.data = new Lazy<Dictionary<string, object>>();
3935
this.Summary = summary ?? throw new ArgumentNullException(nameof(summary));
4036
}
4137

@@ -57,7 +53,7 @@ private Trace(
5753

5854
public IReadOnlyList<ITrace> Children => this.children;
5955

60-
public IReadOnlyDictionary<string, object> Data => this.data.IsValueCreated ? this.data.Value : Trace.EmptyDictionary;
56+
public IReadOnlyDictionary<string, object> Data => this.EnsureMaterializedData();
6157

6258
public void Dispose()
6359
{
@@ -132,10 +128,12 @@ public static Trace GetRootTrace(
132128
/// <exception cref="ArgumentException">Thrown when the key already exists in the dictionary.</exception>
133129
public void AddDatum(string key, TraceDatum traceDatum)
134130
{
135-
if (!this.data.Value.TryAdd(key, traceDatum))
131+
lock (this.Name)
136132
{
137-
throw new ArgumentException($"An item with the same key has already been added: '{key}'");
133+
this.data.Value.Add(key, traceDatum);
134+
this.materializedData = null;
138135
}
136+
139137
this.Summary.UpdateRegionContacted(traceDatum);
140138
}
141139

@@ -148,9 +146,10 @@ public void AddDatum(string key, TraceDatum traceDatum)
148146
/// <exception cref="ArgumentException">Thrown when the key already exists in the dictionary.</exception>
149147
public void AddDatum(string key, object value)
150148
{
151-
if (!this.data.Value.TryAdd(key, value))
149+
lock (this.Name)
152150
{
153-
throw new ArgumentException($"An item with the same key has already been added: '{key}'");
151+
this.data.Value.Add(key, value);
152+
this.materializedData = null;
154153
}
155154
}
156155

@@ -162,7 +161,35 @@ public void AddDatum(string key, object value)
162161
/// <param name="value">The datum itself.</param>
163162
public void AddOrUpdateDatum(string key, object value)
164163
{
165-
this.data.Value.AddOrUpdate(key, value, (k, oldValue) => value);
164+
lock (this.Name)
165+
{
166+
this.data.Value[key] = value;
167+
this.materializedData = null;
168+
}
169+
}
170+
171+
private IReadOnlyDictionary<string, object> EnsureMaterializedData()
172+
{
173+
IReadOnlyDictionary<string, object> snapshot = this.materializedData;
174+
if (snapshot != null)
175+
{
176+
return snapshot;
177+
}
178+
179+
lock (this.Name)
180+
{
181+
if (snapshot != null)
182+
{
183+
return snapshot;
184+
}
185+
186+
if (!this.data.IsValueCreated)
187+
{
188+
return this.materializedData = EmptyDictionary;
189+
}
190+
191+
return this.materializedData = new Dictionary<string, object>(this.data.Value);
192+
}
166193
}
167194
}
168195
}

0 commit comments

Comments
 (0)