Skip to content

Commit 8e9d216

Browse files
committed
Use DefaultHasher
1 parent 4dd09d9 commit 8e9d216

File tree

4 files changed

+26
-89
lines changed

4 files changed

+26
-89
lines changed

opentelemetry-sdk/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ tokio = { workspace = true, features = ["rt", "time"], optional = true }
2929
tokio-stream = { workspace = true, optional = true }
3030
http = { workspace = true, optional = true }
3131
tracing = {workspace = true, optional = true}
32-
rustc-hash = "2.0.0"
3332

3433
[package.metadata.docs.rs]
3534
all-features = true

opentelemetry-sdk/src/metrics/internal/hashed.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
use std::{
22
borrow::{Borrow, Cow},
3-
hash::{BuildHasher, Hash, Hasher},
3+
hash::{BuildHasher, DefaultHasher, Hash, Hasher},
44
ops::Deref,
55
};
66

7-
use rustc_hash::*;
8-
97
/// Hash value only once, works with references and owned types.
108
pub(crate) struct Hashed<'a, T>
119
where
@@ -20,11 +18,10 @@ where
2018
T: ToOwned + Hash + ?Sized,
2119
{
2220
pub(crate) fn from_borrowed(value: &'a T) -> Self {
23-
let mut hasher = FxHasher::default();
24-
value.hash(&mut hasher);
21+
let hash = calc_hash(&value);
2522
Self {
2623
value: Cow::Borrowed(value),
27-
hash: hasher.finish(),
24+
hash,
2825
}
2926
}
3027

@@ -36,16 +33,6 @@ where
3633
}
3734
}
3835

39-
pub(crate) fn mutate(self, f: impl FnOnce(&mut <T as ToOwned>::Owned)) -> Hashed<'static, T> {
40-
let mut value = self.value.into_owned();
41-
f(&mut value);
42-
let hash = calc_hash(value.borrow());
43-
Hashed {
44-
value: Cow::Owned(value),
45-
hash,
46-
}
47-
}
48-
4936
pub(crate) fn into_owned(self) -> Hashed<'static, T> {
5037
let value = self.value.into_owned();
5138
Hashed {
@@ -63,7 +50,7 @@ fn calc_hash<T>(value: T) -> u64
6350
where
6451
T: Hash,
6552
{
66-
let mut hasher = FxHasher::default();
53+
let mut hasher = DefaultHasher::default();
6754
value.hash(&mut hasher);
6855
hasher.finish()
6956
}

opentelemetry-sdk/src/metrics/internal/mod.rs

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use hashed::{Hashed, HashedNoOpBuilder};
2020
use once_cell::sync::Lazy;
2121
use opentelemetry::{otel_warn, KeyValue};
2222

23+
use super::sort_and_dedup;
24+
2325
pub(crate) static STREAM_OVERFLOW_ATTRIBUTES: Lazy<Hashed<'static, [KeyValue]>> =
2426
Lazy::new(|| Hashed::from_owned(vec![KeyValue::new("otel.metric.overflow", "true")]));
2527

@@ -97,11 +99,7 @@ where
9799
}
98100

99101
// Try to retrieve and update the tracker with the attributes sorted.
100-
let sorted_attrs = attributes.clone().mutate(|list| {
101-
// use stable sort
102-
list.sort_by(|a, b| a.key.cmp(&b.key));
103-
dedup_remove_first(list, |a, b| a.key == b.key);
104-
});
102+
let sorted_attrs = Hashed::from_owned(sort_and_dedup(&attributes));
105103
if let Some(tracker) = trackers.get(&sorted_attrs) {
106104
tracker.update(value);
107105
return;
@@ -198,20 +196,6 @@ where
198196
}
199197
}
200198

201-
fn dedup_remove_first<T>(values: &mut Vec<T>, is_eq: impl Fn(&T, &T) -> bool) {
202-
// we cannot use vec.dedup_by because it will remove last duplicate not first
203-
if values.len() > 1 {
204-
let mut i = values.len() - 1;
205-
while i != 0 {
206-
let is_same = unsafe { is_eq(values.get_unchecked(i - 1), values.get_unchecked(i)) };
207-
if is_same {
208-
values.remove(i - 1);
209-
}
210-
i -= 1;
211-
}
212-
}
213-
}
214-
215199
/// Clear and allocate exactly required amount of space for all attribute-sets
216200
fn prepare_data<T>(data: &mut Vec<T>, list_len: usize) {
217201
data.clear();
@@ -415,45 +399,9 @@ impl AtomicallyUpdate<f64> for f64 {
415399

416400
#[cfg(test)]
417401
mod tests {
418-
use std::usize;
419402

420403
use super::*;
421404

422-
fn assert_deduped<const N: usize, const M: usize>(
423-
input: [(i32, bool); N],
424-
expect: [(i32, bool); M],
425-
) {
426-
let mut list: Vec<(i32, bool)> = Vec::from(input);
427-
dedup_remove_first(&mut list, |a, b| a.0 == b.0);
428-
assert_eq!(list, expect);
429-
}
430-
431-
#[test]
432-
fn deduplicate_by_removing_first_element_from_sorted_array() {
433-
assert_deduped([], []);
434-
assert_deduped([(1, true)], [(1, true)]);
435-
assert_deduped([(1, false), (1, false), (1, true)], [(1, true)]);
436-
assert_deduped(
437-
[(1, true), (2, false), (2, false), (2, true)],
438-
[(1, true), (2, true)],
439-
);
440-
assert_deduped(
441-
[(1, true), (1, false), (1, true), (2, true)],
442-
[(1, true), (2, true)],
443-
);
444-
assert_deduped(
445-
[
446-
(1, false),
447-
(1, true),
448-
(2, false),
449-
(2, true),
450-
(3, false),
451-
(3, true),
452-
],
453-
[(1, true), (2, true), (3, true)],
454-
);
455-
}
456-
457405
#[test]
458406
fn can_store_u64_atomic_value() {
459407
let atomic = u64::new_atomic_tracker(0);

opentelemetry-sdk/src/metrics/mod.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,27 @@ pub(crate) struct AttributeSet(Vec<KeyValue>, u64);
115115

116116
impl From<&[KeyValue]> for AttributeSet {
117117
fn from(values: &[KeyValue]) -> Self {
118-
let mut seen_keys = HashSet::with_capacity(values.len());
119-
let vec = values
120-
.iter()
121-
.rev()
122-
.filter_map(|kv| {
123-
if seen_keys.insert(kv.key.clone()) {
124-
Some(kv.clone())
125-
} else {
126-
None
127-
}
128-
})
129-
.collect::<Vec<_>>();
130-
131-
AttributeSet::new(vec)
118+
AttributeSet::new(sort_and_dedup(values))
132119
}
133120
}
134121

122+
pub(crate) fn sort_and_dedup(values: &[KeyValue]) -> Vec<KeyValue> {
123+
let mut seen_keys = HashSet::with_capacity(values.len());
124+
let mut vec = values
125+
.iter()
126+
.rev()
127+
.filter_map(|kv| {
128+
if seen_keys.insert(kv.key.clone()) {
129+
Some(kv.clone())
130+
} else {
131+
None
132+
}
133+
})
134+
.collect::<Vec<_>>();
135+
vec.sort_unstable_by(|a, b| a.key.cmp(&b.key));
136+
vec
137+
}
138+
135139
fn calculate_hash(values: &[KeyValue]) -> u64 {
136140
let mut hasher = DefaultHasher::new();
137141
values.iter().fold(&mut hasher, |mut hasher, item| {
@@ -142,8 +146,7 @@ fn calculate_hash(values: &[KeyValue]) -> u64 {
142146
}
143147

144148
impl AttributeSet {
145-
fn new(mut values: Vec<KeyValue>) -> Self {
146-
values.sort_unstable_by(|a, b| a.key.cmp(&b.key));
149+
fn new(values: Vec<KeyValue>) -> Self {
147150
let hash = calculate_hash(&values);
148151
AttributeSet(values, hash)
149152
}

0 commit comments

Comments
 (0)