Skip to content

Commit 9c71657

Browse files
author
Mindaugas Vinkelis
committed
Baggage improvements
1 parent ebf1bb6 commit 9c71657

File tree

1 file changed

+44
-61
lines changed

1 file changed

+44
-61
lines changed

opentelemetry/src/baggage.rs

+44-61
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
//! [W3C Baggage]: https://w3c.github.io/baggage
1717
use crate::{Context, Key, KeyValue, Value};
1818
use once_cell::sync::Lazy;
19+
use std::collections::hash_map::Entry;
1920
use std::collections::{hash_map, HashMap};
2021
use std::fmt;
2122

@@ -124,6 +125,8 @@ impl Baggage {
124125
/// Same with `insert`, if the name was not present, [`None`] will be returned.
125126
/// If the name is present, the old value and metadata will be returned.
126127
///
128+
/// Also checks for [limits](https://w3c.github.io/baggage/#limits).
129+
///
127130
/// # Examples
128131
///
129132
/// ```
@@ -146,10 +149,41 @@ impl Baggage {
146149
S: Into<BaggageMetadata>,
147150
{
148151
let (key, value, metadata) = (key.into(), value.into(), metadata.into());
149-
if self.insertable(&key, &value, &metadata) {
150-
self.inner.insert(key, (value, metadata))
151-
} else {
152-
None
152+
if !key.as_str().is_ascii() {
153+
return None;
154+
}
155+
let entry_content_len =
156+
key_value_metadata_bytes_size(key.as_str(), value.as_str().as_ref(), metadata.as_str());
157+
if entry_content_len >= MAX_BYTES_FOR_ONE_PAIR {
158+
return None;
159+
}
160+
let entries_count = self.inner.len();
161+
match self.inner.entry(key) {
162+
Entry::Occupied(mut occupied_entry) => {
163+
let prev_content_len = key_value_metadata_bytes_size(
164+
occupied_entry.key().as_str(),
165+
&occupied_entry.get().0.as_str().as_ref(),
166+
occupied_entry.get().1.as_str(),
167+
);
168+
let new_content_len = self.kv_content_len + entry_content_len - prev_content_len;
169+
if new_content_len > MAX_LEN_OF_ALL_PAIRS {
170+
return None;
171+
}
172+
self.kv_content_len = new_content_len;
173+
Some(occupied_entry.insert((value, metadata)))
174+
}
175+
Entry::Vacant(vacant_entry) => {
176+
if entries_count == MAX_KEY_VALUE_PAIRS {
177+
return None;
178+
}
179+
let new_content_len = self.kv_content_len + entry_content_len;
180+
if new_content_len > MAX_LEN_OF_ALL_PAIRS {
181+
return None;
182+
}
183+
self.kv_content_len = new_content_len;
184+
vacant_entry.insert((value, metadata));
185+
None
186+
}
153187
}
154188
}
155189

@@ -169,59 +203,10 @@ impl Baggage {
169203
self.inner.is_empty()
170204
}
171205

172-
/// Gets an iterator over the baggage items, sorted by name.
206+
/// Gets an iterator over the baggage items, in any order.
173207
pub fn iter(&self) -> Iter<'_> {
174208
self.into_iter()
175209
}
176-
177-
/// Determine whether the key value pair exceed one of the [limits](https://w3c.github.io/baggage/#limits).
178-
/// If not, update the total length of key values
179-
fn insertable(&mut self, key: &Key, value: &Value, metadata: &BaggageMetadata) -> bool {
180-
if !key.as_str().is_ascii() {
181-
return false;
182-
}
183-
let value = value.as_str();
184-
if key_value_metadata_bytes_size(key.as_str(), value.as_ref(), metadata.as_str())
185-
< MAX_BYTES_FOR_ONE_PAIR
186-
{
187-
match self.inner.get(key) {
188-
None => {
189-
// check total length
190-
if self.kv_content_len
191-
+ metadata.as_str().len()
192-
+ value.len()
193-
+ key.as_str().len()
194-
> MAX_LEN_OF_ALL_PAIRS
195-
{
196-
return false;
197-
}
198-
// check number of pairs
199-
if self.inner.len() + 1 > MAX_KEY_VALUE_PAIRS {
200-
return false;
201-
}
202-
self.kv_content_len +=
203-
metadata.as_str().len() + value.len() + key.as_str().len()
204-
}
205-
Some((old_value, old_metadata)) => {
206-
let old_value = old_value.as_str();
207-
if self.kv_content_len - old_metadata.as_str().len() - old_value.len()
208-
+ metadata.as_str().len()
209-
+ value.len()
210-
> MAX_LEN_OF_ALL_PAIRS
211-
{
212-
return false;
213-
}
214-
self.kv_content_len =
215-
self.kv_content_len - old_metadata.as_str().len() - old_value.len()
216-
+ metadata.as_str().len()
217-
+ value.len()
218-
}
219-
}
220-
true
221-
} else {
222-
false
223-
}
224-
}
225210
}
226211

227212
/// Get the number of bytes for one key-value pair
@@ -376,13 +361,11 @@ impl BaggageExt for Context {
376361
&self,
377362
baggage: T,
378363
) -> Self {
379-
let mut merged: Baggage = self
380-
.baggage()
381-
.iter()
382-
.map(|(key, (value, metadata))| {
383-
KeyValueMetadata::new(key.clone(), value.clone(), metadata.clone())
384-
})
385-
.collect();
364+
let old = self.baggage();
365+
let mut merged = Baggage {
366+
inner: old.inner.clone(),
367+
kv_content_len: old.kv_content_len,
368+
};
386369
for kvm in baggage.into_iter().map(|kv| kv.into()) {
387370
merged.insert_with_metadata(kvm.key, kvm.value, kvm.metadata);
388371
}

0 commit comments

Comments
 (0)