Skip to content

Commit a3e2149

Browse files
committed
feat(profiling): Set and StringSet
1 parent 35314d9 commit a3e2149

12 files changed

Lines changed: 1727 additions & 6 deletions

File tree

Cargo.lock

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

LICENSE-3rdparty.yml

Lines changed: 36 additions & 2 deletions
Large diffs are not rendered by default.

libdd-profiling/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ name = "main"
2121
harness = false
2222

2323
[dependencies]
24+
allocator-api2 = { version = "0.2", default-features = false, features = ["alloc"] }
2425
anyhow = "1.0"
2526
bitmaps = "3.2.0"
2627
byteorder = { version = "1.5", features = ["std"] }
@@ -30,6 +31,7 @@ libdd-alloc = { version = "1.0.0", path = "../libdd-alloc" }
3031
libdd-profiling-protobuf = { version = "1.0.0", path = "../libdd-profiling-protobuf", features = ["prost_impls"] }
3132
libdd-common = { version = "1.0.0", path = "../libdd-common" }
3233
futures = { version = "0.3", default-features = false }
34+
hashbrown = { version = "0.16", default-features = false }
3335
http = "1.0"
3436
hyper = { workspace = true}
3537
http-body-util = "0.1"
@@ -42,6 +44,7 @@ rustc-hash = { version = "1.1", default-features = false }
4244
serde = {version = "1.0", features = ["derive"]}
4345
serde_json = {version = "1.0"}
4446
target-triple = "0.1.4"
47+
thiserror = "2"
4548
tokio = {version = "1.23", features = ["rt", "macros"]}
4649
tokio-util = "0.7.1"
4750
zstd = { version = "0.13", default-features = false }
@@ -50,3 +53,4 @@ zstd = { version = "0.13", default-features = false }
5053
bolero = "0.13"
5154
criterion = "0.5.1"
5255
lz4_flex = { version = "0.9", default-features = false, features = ["std", "frame"] }
56+
proptest = "1"

libdd-profiling/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ pub mod exporter;
1212
pub mod internal;
1313
pub mod iter;
1414
pub mod pprof;
15-
mod profiles;
15+
pub mod profiles;

libdd-profiling/src/pprof/test_utils.rs

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

4-
use anyhow::Context;
54
use libdd_profiling_protobuf::prost_impls::{Profile, Sample};
6-
use std::io::Cursor;
75

86
fn deserialize_compressed_pprof(encoded: &[u8]) -> anyhow::Result<Profile> {
97
use prost::Message;
10-
use std::io::Read;
118

129
// The zstd bindings use FFI so they don't work under miri. This means the
1310
// buffer isn't compressed, so simply convert to a vec.
1411
#[cfg(miri)]
1512
let buf = encoded.to_vec();
1613
#[cfg(not(miri))]
1714
let buf = {
15+
use anyhow::Context;
16+
use std::io::{Cursor, Read};
1817
let mut decoder =
1918
zstd::Decoder::new(Cursor::new(encoded)).context("failed to create zstd decoder")?;
2019
let mut out = Vec::new();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#[repr(C)]
5+
#[derive(Debug, thiserror::Error)]
6+
pub enum SetError {
7+
#[error("set error: invalid argument")]
8+
InvalidArgument,
9+
#[error("set error: out of memory")]
10+
OutOfMemory,
11+
}
12+
13+
impl From<libdd_alloc::AllocError> for SetError {
14+
fn from(_: libdd_alloc::AllocError) -> Self {
15+
SetError::OutOfMemory
16+
}
17+
}
18+
19+
impl From<std::collections::TryReserveError> for SetError {
20+
fn from(_: std::collections::TryReserveError) -> Self {
21+
SetError::OutOfMemory
22+
}
23+
}
24+
25+
impl From<hashbrown::TryReserveError> for SetError {
26+
fn from(_: hashbrown::TryReserveError) -> Self {
27+
SetError::OutOfMemory
28+
}
29+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
mod error;
5+
mod set;
6+
mod slice_set;
7+
mod string_set;
8+
mod thin_str;
9+
10+
pub type SetHasher = core::hash::BuildHasherDefault<rustc_hash::FxHasher>;
11+
12+
pub use error::*;
13+
pub use set::*;
14+
pub use slice_set::*;
15+
pub use string_set::*;
16+
pub use thin_str::*;
17+
18+
use std::any::TypeId;
19+
20+
/// Operations that somewhat abstract around Sets of single items and sets of
21+
/// slices for sharded sets.
22+
///
23+
/// # Safety
24+
///
25+
/// Implementors must ensure that all methods which take `&self` are safe to
26+
/// call under a read-lock, and all `&mut self` methods are safe to call under
27+
/// a write-lock, and are safe for `Send` and `Sync`.
28+
pub unsafe trait ShardedSetOps {
29+
type Lookup<'a>: Copy
30+
where
31+
Self: 'a;
32+
33+
/// Owned payload used for insertion. For some containers (e.g. slice-backed
34+
/// sets) this can be a borrowed view like `&'a [T]` because the container
35+
/// copies data into its own arena during insertion.
36+
type Owned<'a>
37+
where
38+
Self: 'a;
39+
40+
type Id: Copy;
41+
42+
/// Returns the `TypeId` of the logical element type stored by this set.
43+
fn type_id(&self) -> TypeId;
44+
45+
fn try_with_capacity(capacity: usize) -> Result<Self, SetError>
46+
where
47+
Self: Sized;
48+
49+
fn len(&self) -> usize;
50+
51+
#[inline]
52+
fn is_empty(&self) -> bool {
53+
self.len() == 0
54+
}
55+
56+
/// # Safety
57+
/// Same safety contract as the underlying container's find_with_hash.
58+
unsafe fn find_with_hash(&self, hash: u64, key: Self::Lookup<'_>) -> Option<Self::Id>;
59+
60+
/// # Safety
61+
/// Same safety contract as the underlying container's insert_unique_uncontended_with_hash.
62+
unsafe fn insert_unique_uncontended_with_hash(
63+
&mut self,
64+
hash: u64,
65+
key: Self::Owned<'_>,
66+
) -> Result<Self::Id, SetError>;
67+
}

0 commit comments

Comments
 (0)