Skip to content

Commit 4407d84

Browse files
committed
style: fix clippy lints
1 parent 1458aad commit 4407d84

File tree

5 files changed

+94
-90
lines changed

5 files changed

+94
-90
lines changed

profiling/src/bitset.rs

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
33

4-
use std::cell::Cell;
54
use std::hash::{Hash, Hasher};
65

76
/// Very simple bitset which doesn't allocate, and doesn't change after it has
87
/// been created.
9-
#[derive(Clone, Debug, Eq, PartialEq)]
8+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
109
#[repr(transparent)]
1110
pub struct BitSet {
12-
bits: Cell<u32>,
11+
bits: u32,
1312
}
1413

1514
impl Hash for BitSet {
1615
fn hash<H: Hasher>(&self, state: &mut H) {
17-
let bits = self.bits.get();
16+
let bits = self.bits;
1817
bits.count_ones().hash(state);
1918
bits.hash(state);
2019
}
@@ -24,47 +23,25 @@ impl BitSet {
2423
pub const MAX: usize = u32::BITS as usize;
2524

2625
/// Creates a new bitset from the provided number.
27-
pub const fn new(bitset: u32) -> Self {
28-
Self {
29-
bits: Cell::new(bitset),
30-
}
31-
}
32-
33-
/// Creates a new bitset from the iterator.
34-
///
35-
/// # Panics
36-
///
37-
/// Panics if an item is out of the range of the bitset e.g. [`u32::MAX`].
38-
pub fn from_iter<I: Iterator<Item = usize>>(iter: I) -> BitSet {
39-
let mut bits = 0;
40-
let mut insert = |bit| {
41-
// todo: add non-panic API
42-
assert!(bit < BitSet::MAX);
43-
bits |= 1u32 << bit;
44-
};
45-
for bit in iter {
46-
insert(bit);
47-
}
48-
BitSet {
49-
bits: Cell::new(bits),
50-
}
26+
pub const fn new(bits: u32) -> Self {
27+
Self { bits }
5128
}
5229

5330
#[inline]
5431
pub fn len(&self) -> usize {
55-
self.bits.get().count_ones() as usize
32+
self.bits.count_ones() as usize
5633
}
5734

5835
#[inline]
5936
pub fn is_empty(&self) -> bool {
60-
self.bits.get() == 0
37+
self.bits == 0
6138
}
6239

6340
#[inline]
6441
pub fn contains(&self, bit: usize) -> bool {
6542
if bit < 32 {
6643
let mask = 1u32 << bit;
67-
let masked = self.bits.get() & mask;
44+
let masked = self.bits & mask;
6845
masked != 0
6946
} else {
7047
false
@@ -76,6 +53,26 @@ impl BitSet {
7653
}
7754
}
7855

56+
impl FromIterator<usize> for BitSet {
57+
/// Creates a new bitset from the iterator.
58+
///
59+
/// # Panics
60+
///
61+
/// Panics if an item is out of the range of the bitset e.g. [`u32::MAX`].
62+
fn from_iter<I: IntoIterator<Item = usize>>(iter: I) -> BitSet {
63+
let mut bits = 0;
64+
let mut insert = |bit| {
65+
// todo: add non-panic API
66+
assert!(bit < BitSet::MAX);
67+
bits |= 1u32 << bit;
68+
};
69+
for bit in iter {
70+
insert(bit);
71+
}
72+
BitSet { bits }
73+
}
74+
}
75+
7976
pub struct BitSetIter {
8077
bitset: u32,
8178
offset: u32,
@@ -84,7 +81,7 @@ pub struct BitSetIter {
8481

8582
impl BitSetIter {
8683
pub fn new(bitset: &BitSet) -> BitSetIter {
87-
let bitset = bitset.bits.get();
84+
let bitset = bitset.bits;
8885
let offset = 0;
8986
let end = {
9087
let num_bits = u32::BITS;

profiling/src/inlinevec.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ const fn assert_capacity(n: usize) {
1818
panic!("InlineVec only supports up to u8::MAX capacities");
1919
}
2020
}
21+
22+
impl<T, const N: usize> Default for InlineVec<T, N> {
23+
fn default() -> Self {
24+
InlineVec::new()
25+
}
26+
}
27+
2128
impl<T, const N: usize> InlineVec<T, N> {
2229
pub const fn new() -> Self {
2330
assert_capacity(N);
@@ -146,7 +153,7 @@ impl<T, const N: usize> InlineVecIter<T, N> {
146153
impl<T, const N: usize> Drop for InlineVecIter<T, N> {
147154
fn drop(&mut self) {
148155
if core::mem::needs_drop::<T>() {
149-
let base = unsafe { self.vec.as_mut_ptr() };
156+
let base = self.vec.as_mut_ptr();
150157
for i in self.live_range() {
151158
unsafe { base.add(i).drop_in_place() }
152159
}
@@ -232,7 +239,7 @@ mod tests {
232239

233240
const TEST_INLINE_VEC: InlineVec<bool, 2> = {
234241
let mut vec = InlineVec::from([false]);
235-
if let Err(e) = vec.try_push(true) {
242+
if vec.try_push(true).is_err() {
236243
panic!("expected to be able push another item into the vec")
237244
}
238245
vec

profiling/src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
pub mod bindings;
2+
pub mod bitset;
23
pub mod capi;
4+
pub mod inlinevec;
5+
pub mod profiling;
6+
37
mod clocks;
48
mod config;
5-
mod inlinevec;
69
mod logging;
7-
pub mod profiling;
810
mod pthread;
911
mod sapi;
1012
mod thin_str;
13+
mod vec_ext;
1114
mod wall_time;
1215

1316
#[cfg(php_run_time_cache)]
@@ -22,10 +25,8 @@ mod io;
2225
#[cfg(feature = "exception_profiling")]
2326
mod exception;
2427

25-
mod bitset;
2628
#[cfg(feature = "timeline")]
2729
mod timeline;
28-
mod vec_ext;
2930

3031
use crate::config::{SystemSettings, INITIAL_SYSTEM_SETTINGS};
3132
use crate::zend::datadog_sapi_globals_request_info;

profiling/src/profiling/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ pub struct LocalRootSpanResourceMessage {
177177
pub resource: String,
178178
}
179179

180+
// Allow large enum variant for now, because we're avoiding an allocation on
181+
// a hot path. The correct fix is probably to take some kind of
182+
// `InlineVec<SampleValue>` where `SampleValue` is an enum per profile type.
183+
#[allow(clippy::large_enum_variant)]
180184
#[derive(Debug)]
181185
pub enum ProfilerMessage {
182186
Cancel,

profiling/src/profiling/samples.rs

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ pub const PROFILE_TYPES: [ProfileType; NUM_PROFILE_TYPES] = [
3535
/// 1. Always enabled types.
3636
/// 2. On by default types.
3737
/// 3. Off by default types.
38+
///
3839
/// But this doesn't really matter anymore, because the number of sample types
39-
/// has grown.
40+
/// has grown and the optimizations used don't work well anymore.
4041
#[derive(Default, Debug)]
4142
#[repr(C)]
4243
pub struct SampleValues {
@@ -65,30 +66,30 @@ pub struct SampleValues {
6566
pub file_write_size_samples: i64,
6667
}
6768

68-
/// The sample values for a given profile type.
69-
///
70-
/// The repr(u8) is valid even though this holds data larger than u8; see the
71-
/// documentation on primitive representations:
72-
/// https://doc.rust-lang.org/reference/type-layout.html#primitive-representations
73-
///
74-
/// If the order of the enum is changed, or if variants are added or removed,
75-
/// then [`PROFILE_TYPES`] needs to be changed.
76-
#[repr(u8)]
77-
pub enum SampleValue {
78-
WallTime { nanoseconds: i64, count: i64 },
79-
CpuTime { nanoseconds: i64 },
80-
Alloc { bytes: i64, count: i64 },
81-
Timeline { nanoseconds: i64 },
82-
Exception { count: i64 },
83-
FileIoReadTime { nanoseconds: i64, count: i64 },
84-
FileIoWriteTime { nanoseconds: i64, count: i64 },
85-
FileIoReadSize { bytes: i64, count: i64 },
86-
FileIoWriteSize { bytes: i64, count: i64 },
87-
SocketReadTime { nanoseconds: i64, count: i64 },
88-
SocketWriteTime { nanoseconds: i64, count: i64 },
89-
SocketReadSize { bytes: i64, count: i64 },
90-
SocketWriteSize { bytes: i64, count: i64 },
91-
}
69+
// /// The sample values for a given profile type.
70+
// ///
71+
// /// The repr(u8) is valid even though this holds data larger than u8; see the
72+
// /// documentation on primitive representations:
73+
// /// https://doc.rust-lang.org/reference/type-layout.html#primitive-representations
74+
// ///
75+
// /// If the order of the enum is changed, or if variants are added or removed,
76+
// /// then [`PROFILE_TYPES`] needs to be changed (or vice versa)
77+
// #[repr(u8)]
78+
// pub enum SampleValue {
79+
// WallTime { nanoseconds: i64, count: i64 },
80+
// CpuTime { nanoseconds: i64 },
81+
// Alloc { bytes: i64, count: i64 },
82+
// Timeline { nanoseconds: i64 },
83+
// Exception { count: i64 },
84+
// FileIoReadTime { nanoseconds: i64, count: i64 },
85+
// FileIoWriteTime { nanoseconds: i64, count: i64 },
86+
// FileIoReadSize { bytes: i64, count: i64 },
87+
// FileIoWriteSize { bytes: i64, count: i64 },
88+
// SocketReadTime { nanoseconds: i64, count: i64 },
89+
// SocketWriteTime { nanoseconds: i64, count: i64 },
90+
// SocketReadSize { bytes: i64, count: i64 },
91+
// SocketWriteSize { bytes: i64, count: i64 },
92+
// }
9293

9394
/// Tracks which profile types are enabled. Since there are 1 or 2 sample
9495
/// types per profile, it also keeps a bitset for which sample types and
@@ -234,8 +235,8 @@ impl EnabledProfiles {
234235
pub fn filter<'a>(
235236
&self,
236237
sample_values: &'a SampleValues,
237-
) -> SampleIter<i64, impl Iterator<Item = i64> + 'a> {
238-
let bitset = self.samples.clone();
238+
) -> SampleIter<impl Iterator<Item = i64> + 'a> {
239+
let bitset = self.samples;
239240
let len = bitset.len();
240241
let iter =
241242
sample_values
@@ -252,9 +253,7 @@ impl EnabledProfiles {
252253
SampleIter { len, iter }
253254
}
254255

255-
pub fn enabled_profile_types<'a>(
256-
&'a self,
257-
) -> SampleIter<ProfileType, impl Iterator<Item = ProfileType> + 'a> {
256+
pub fn enabled_profile_types(&self) -> SampleIter<impl Iterator<Item = ProfileType> + '_> {
258257
let len = self.num_enabled_profiles();
259258
let iter = PROFILE_TYPES
260259
.iter()
@@ -265,9 +264,7 @@ impl EnabledProfiles {
265264
SampleIter { len, iter }
266265
}
267266

268-
pub fn enabled_sample_types<'a>(
269-
&'a self,
270-
) -> SampleIter<ValueType, impl Iterator<Item = ValueType> + 'a> {
267+
pub fn enabled_sample_types(&self) -> SampleIter<impl Iterator<Item = ValueType> + '_> {
271268
let len = self.num_enabled_sample_types();
272269
let iter = self.enabled_profile_types().flatten();
273270
SampleIter { len, iter }
@@ -399,28 +396,26 @@ const SAMPLE_TYPE_FILE_IO_WRITE_SIZE: ProfileType = ProfileType::from([
399396
},
400397
]);
401398

402-
impl SampleValue {
403-
fn discriminant(&self) -> usize {
404-
// SAFETY: SampleValue uses a primitive representation.
405-
let r#repr = unsafe { *(self as *const Self as *const u8) };
406-
r#repr as usize
407-
}
408-
}
409-
410-
impl SampleValue {
411-
pub fn sample_types(&self) -> ProfileType {
412-
let discriminant = self.discriminant();
413-
PROFILE_TYPES[discriminant]
414-
}
415-
}
416-
417-
pub struct SampleIter<T, I: Iterator<Item = T>> {
399+
// impl SampleValue {
400+
// pub fn discriminant(&self) -> usize {
401+
// // SAFETY: SampleValue uses a primitive representation.
402+
// let r#repr = unsafe { *(self as *const Self as *const u8) };
403+
// r#repr as usize
404+
// }
405+
//
406+
// pub fn sample_types(&self) -> ProfileType {
407+
// let discriminant = self.discriminant();
408+
// PROFILE_TYPES[discriminant]
409+
// }
410+
// }
411+
412+
pub struct SampleIter<I: Iterator> {
418413
len: usize,
419414
iter: I,
420415
}
421416

422-
impl<T, I: Iterator<Item = T>> Iterator for SampleIter<T, I> {
423-
type Item = T;
417+
impl<I: Iterator> Iterator for SampleIter<I> {
418+
type Item = I::Item;
424419
fn next(&mut self) -> Option<Self::Item> {
425420
let next = self.iter.next();
426421
if next.is_some() {
@@ -435,7 +430,7 @@ impl<T, I: Iterator<Item = T>> Iterator for SampleIter<T, I> {
435430
}
436431
}
437432

438-
impl<T, I: Iterator<Item = T>> ExactSizeIterator for SampleIter<T, I> {
433+
impl<I: Iterator> ExactSizeIterator for SampleIter<I> {
439434
fn len(&self) -> usize {
440435
self.len
441436
}

0 commit comments

Comments
 (0)