Skip to content

Commit 9c107d2

Browse files
committed
move keyvalue eq and hash to common
1 parent efd6ee4 commit 9c107d2

File tree

2 files changed

+109
-116
lines changed

2 files changed

+109
-116
lines changed

opentelemetry/src/common.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use std::borrow::{Borrow, Cow};
22
use std::sync::Arc;
33
use std::{fmt, hash};
44

5+
use std::hash::{Hash, Hasher};
6+
57
/// The key part of attribute [KeyValue] pairs.
68
///
79
/// See the [attribute naming] spec for guidelines.
@@ -399,6 +401,42 @@ impl KeyValue {
399401
}
400402
}
401403

404+
struct F64Hashable(f64);
405+
406+
impl PartialEq for F64Hashable {
407+
fn eq(&self, other: &Self) -> bool {
408+
self.0.to_bits() == other.0.to_bits()
409+
}
410+
}
411+
412+
impl Eq for F64Hashable {}
413+
414+
impl Hash for F64Hashable {
415+
fn hash<H: Hasher>(&self, state: &mut H) {
416+
self.0.to_bits().hash(state);
417+
}
418+
}
419+
420+
impl Hash for KeyValue {
421+
fn hash<H: Hasher>(&self, state: &mut H) {
422+
self.key.hash(state);
423+
match &self.value {
424+
Value::F64(f) => F64Hashable(*f).hash(state),
425+
Value::Array(a) => match a {
426+
Array::Bool(b) => b.hash(state),
427+
Array::I64(i) => i.hash(state),
428+
Array::F64(f) => f.iter().for_each(|f| F64Hashable(*f).hash(state)),
429+
Array::String(s) => s.hash(state),
430+
},
431+
Value::Bool(b) => b.hash(state),
432+
Value::I64(i) => i.hash(state),
433+
Value::String(s) => s.hash(state),
434+
};
435+
}
436+
}
437+
438+
impl Eq for KeyValue {}
439+
402440
/// Information about a library or crate providing instrumentation.
403441
///
404442
/// An instrumentation scope should be named to follow any naming conventions
@@ -579,6 +617,77 @@ mod tests {
579617

580618
use crate::{InstrumentationScope, KeyValue};
581619

620+
use rand::random;
621+
use std::collections::hash_map::DefaultHasher;
622+
use std::f64;
623+
624+
#[test]
625+
fn kv_float_equality() {
626+
let kv1 = KeyValue::new("key", 1.0);
627+
let kv2 = KeyValue::new("key", 1.0);
628+
assert_eq!(kv1, kv2);
629+
630+
let kv1 = KeyValue::new("key", 1.0);
631+
let kv2 = KeyValue::new("key", 1.01);
632+
assert_ne!(kv1, kv2);
633+
634+
let kv1 = KeyValue::new("key", f64::NAN);
635+
let kv2 = KeyValue::new("key", f64::NAN);
636+
assert_ne!(kv1, kv2, "NAN is not equal to itself");
637+
638+
for float_val in [
639+
f64::INFINITY,
640+
f64::NEG_INFINITY,
641+
f64::MAX,
642+
f64::MIN,
643+
f64::MIN_POSITIVE,
644+
]
645+
.iter()
646+
{
647+
let kv1 = KeyValue::new("key", *float_val);
648+
let kv2 = KeyValue::new("key", *float_val);
649+
assert_eq!(kv1, kv2);
650+
}
651+
652+
for _ in 0..100 {
653+
let random_value = random::<f64>();
654+
let kv1 = KeyValue::new("key", random_value);
655+
let kv2 = KeyValue::new("key", random_value);
656+
assert_eq!(kv1, kv2);
657+
}
658+
}
659+
660+
#[test]
661+
fn kv_float_hash() {
662+
for float_val in [
663+
f64::NAN,
664+
f64::INFINITY,
665+
f64::NEG_INFINITY,
666+
f64::MAX,
667+
f64::MIN,
668+
f64::MIN_POSITIVE,
669+
]
670+
.iter()
671+
{
672+
let kv1 = KeyValue::new("key", *float_val);
673+
let kv2 = KeyValue::new("key", *float_val);
674+
assert_eq!(hash_helper(&kv1), hash_helper(&kv2));
675+
}
676+
677+
for _ in 0..100 {
678+
let random_value = random::<f64>();
679+
let kv1 = KeyValue::new("key", random_value);
680+
let kv2 = KeyValue::new("key", random_value);
681+
assert_eq!(hash_helper(&kv1), hash_helper(&kv2));
682+
}
683+
}
684+
685+
fn hash_helper<T: Hash>(item: &T) -> u64 {
686+
let mut hasher = DefaultHasher::new();
687+
item.hash(&mut hasher);
688+
hasher.finish()
689+
}
690+
582691
#[test]
583692
fn instrumentation_scope_equality() {
584693
let scope1 = InstrumentationScope::builder("my-crate")

opentelemetry/src/metrics/mod.rs

Lines changed: 0 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
//! # OpenTelemetry Metrics API
22
3-
use std::hash::{Hash, Hasher};
43
use std::sync::Arc;
54

65
mod instruments;
76
mod meter;
87
pub(crate) mod noop;
9-
10-
use crate::{Array, KeyValue, Value};
118
pub use instruments::{
129
counter::{Counter, ObservableCounter},
1310
gauge::{Gauge, ObservableGauge},
@@ -18,42 +15,6 @@ pub use instruments::{
1815
};
1916
pub use meter::{Meter, MeterProvider};
2017

21-
struct F64Hashable(f64);
22-
23-
impl PartialEq for F64Hashable {
24-
fn eq(&self, other: &Self) -> bool {
25-
self.0.to_bits() == other.0.to_bits()
26-
}
27-
}
28-
29-
impl Eq for F64Hashable {}
30-
31-
impl Hash for F64Hashable {
32-
fn hash<H: Hasher>(&self, state: &mut H) {
33-
self.0.to_bits().hash(state);
34-
}
35-
}
36-
37-
impl Hash for KeyValue {
38-
fn hash<H: Hasher>(&self, state: &mut H) {
39-
self.key.hash(state);
40-
match &self.value {
41-
Value::F64(f) => F64Hashable(*f).hash(state),
42-
Value::Array(a) => match a {
43-
Array::Bool(b) => b.hash(state),
44-
Array::I64(i) => i.hash(state),
45-
Array::F64(f) => f.iter().for_each(|f| F64Hashable(*f).hash(state)),
46-
Array::String(s) => s.hash(state),
47-
},
48-
Value::Bool(b) => b.hash(state),
49-
Value::I64(i) => i.hash(state),
50-
Value::String(s) => s.hash(state),
51-
};
52-
}
53-
}
54-
55-
impl Eq for KeyValue {}
56-
5718
/// SDK implemented trait for creating instruments
5819
pub trait InstrumentProvider {
5920
/// creates an instrument for recording increasing values.
@@ -163,80 +124,3 @@ pub trait InstrumentProvider {
163124
Histogram::new(Arc::new(noop::NoopSyncInstrument::new()))
164125
}
165126
}
166-
167-
#[cfg(test)]
168-
mod tests {
169-
use rand::random;
170-
171-
use crate::KeyValue;
172-
use std::collections::hash_map::DefaultHasher;
173-
use std::f64;
174-
use std::hash::{Hash, Hasher};
175-
176-
#[test]
177-
fn kv_float_equality() {
178-
let kv1 = KeyValue::new("key", 1.0);
179-
let kv2 = KeyValue::new("key", 1.0);
180-
assert_eq!(kv1, kv2);
181-
182-
let kv1 = KeyValue::new("key", 1.0);
183-
let kv2 = KeyValue::new("key", 1.01);
184-
assert_ne!(kv1, kv2);
185-
186-
let kv1 = KeyValue::new("key", f64::NAN);
187-
let kv2 = KeyValue::new("key", f64::NAN);
188-
assert_ne!(kv1, kv2, "NAN is not equal to itself");
189-
190-
for float_val in [
191-
f64::INFINITY,
192-
f64::NEG_INFINITY,
193-
f64::MAX,
194-
f64::MIN,
195-
f64::MIN_POSITIVE,
196-
]
197-
.iter()
198-
{
199-
let kv1 = KeyValue::new("key", *float_val);
200-
let kv2 = KeyValue::new("key", *float_val);
201-
assert_eq!(kv1, kv2);
202-
}
203-
204-
for _ in 0..100 {
205-
let random_value = random::<f64>();
206-
let kv1 = KeyValue::new("key", random_value);
207-
let kv2 = KeyValue::new("key", random_value);
208-
assert_eq!(kv1, kv2);
209-
}
210-
}
211-
212-
#[test]
213-
fn kv_float_hash() {
214-
for float_val in [
215-
f64::NAN,
216-
f64::INFINITY,
217-
f64::NEG_INFINITY,
218-
f64::MAX,
219-
f64::MIN,
220-
f64::MIN_POSITIVE,
221-
]
222-
.iter()
223-
{
224-
let kv1 = KeyValue::new("key", *float_val);
225-
let kv2 = KeyValue::new("key", *float_val);
226-
assert_eq!(hash_helper(&kv1), hash_helper(&kv2));
227-
}
228-
229-
for _ in 0..100 {
230-
let random_value = random::<f64>();
231-
let kv1 = KeyValue::new("key", random_value);
232-
let kv2 = KeyValue::new("key", random_value);
233-
assert_eq!(hash_helper(&kv1), hash_helper(&kv2));
234-
}
235-
}
236-
237-
fn hash_helper<T: Hash>(item: &T) -> u64 {
238-
let mut hasher = DefaultHasher::new();
239-
item.hash(&mut hasher);
240-
hasher.finish()
241-
}
242-
}

0 commit comments

Comments
 (0)