Skip to content

Commit 2bfe267

Browse files
committed
Optimize cloning of Context since entries are immutable
1 parent 3af1060 commit 2bfe267

File tree

1 file changed

+22
-17
lines changed

1 file changed

+22
-17
lines changed

opentelemetry/src/context.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ thread_local! {
7878
pub struct Context {
7979
#[cfg(feature = "trace")]
8080
pub(super) span: Option<Arc<SynchronizedSpan>>,
81-
entries: HashMap<TypeId, Arc<dyn Any + Sync + Send>, BuildHasherDefault<IdHasher>>,
81+
entries: Option<Arc<HashMap<TypeId, Arc<dyn Any + Sync + Send>, BuildHasherDefault<IdHasher>>>>,
8282
}
8383

8484
impl Context {
@@ -152,12 +152,7 @@ impl Context {
152152
/// assert_eq!(all_current_and_b.get::<ValueB>(), Some(&ValueB(42)));
153153
/// ```
154154
pub fn current_with_value<T: 'static + Send + Sync>(value: T) -> Self {
155-
let mut new_context = Context::current();
156-
new_context
157-
.entries
158-
.insert(TypeId::of::<T>(), Arc::new(value));
159-
160-
new_context
155+
Context::map_current(|cx| cx.with_value(value))
161156
}
162157

163158
/// Returns a reference to the entry for the corresponding value type.
@@ -182,9 +177,13 @@ impl Context {
182177
/// assert_eq!(cx.get::<MyUser>(), None);
183178
/// ```
184179
pub fn get<T: 'static>(&self) -> Option<&T> {
185-
self.entries
186-
.get(&TypeId::of::<T>())
187-
.and_then(|rc| rc.downcast_ref())
180+
if let Some(entries) = &self.entries {
181+
entries
182+
.get(&TypeId::of::<T>())
183+
.and_then(|rc| rc.downcast_ref())
184+
} else {
185+
None
186+
}
188187
}
189188

190189
/// Returns a copy of the context with the new value included.
@@ -215,12 +214,18 @@ impl Context {
215214
/// assert_eq!(cx_with_a_and_b.get::<ValueB>(), Some(&ValueB(42)));
216215
/// ```
217216
pub fn with_value<T: 'static + Send + Sync>(&self, value: T) -> Self {
218-
let mut new_context = self.clone();
219-
new_context
220-
.entries
221-
.insert(TypeId::of::<T>(), Arc::new(value));
222-
223-
new_context
217+
let entries = if let Some(current_entries) = &self.entries {
218+
let mut inner_entries = (**current_entries).clone();
219+
inner_entries.insert(TypeId::of::<T>(), Arc::new(value));
220+
Some(Arc::new(inner_entries))
221+
} else {
222+
None
223+
};
224+
Context {
225+
entries: entries,
226+
#[cfg(feature = "trace")]
227+
span: self.span.clone(),
228+
}
224229
}
225230

226231
/// Replaces the current context on this thread with this context.
@@ -326,7 +331,7 @@ impl Context {
326331
impl fmt::Debug for Context {
327332
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328333
let mut dbg = f.debug_struct("Context");
329-
let mut entries = self.entries.len();
334+
let mut entries = self.entries.as_ref().map_or(0, |e| e.len());
330335
#[cfg(feature = "trace")]
331336
{
332337
if let Some(span) = &self.span {

0 commit comments

Comments
 (0)