Skip to content

Commit 8145a59

Browse files
committed
Interned empty string, as Ivo requested
1 parent 6d3c4cd commit 8145a59

File tree

4 files changed

+32
-3
lines changed

4 files changed

+32
-3
lines changed

profiling-ffi/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
pub use symbolizer_ffi::*;
66

77
mod exporter;
8+
mod exporter2;
89
mod profiles;
910
mod string_storage;
1011

profiling-ffi/src/profiles/interning_api.rs

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use datadog_profiling::{
88
api::ManagedStringId,
99
collections::identifiable::StringId,
1010
internal::{
11+
self,
1112
interning_api::{Generation, GenerationalId},
1213
FunctionId, LabelId, LabelSetId, LocationId, MappingId, StackTraceId,
1314
},
@@ -314,6 +315,15 @@ pub unsafe extern "C" fn ddog_prof_Profile_intern_string(
314315
wrap_with_ffi_result!({ profile_ptr_to_inner(profile)?.intern_string(s.try_to_utf8()?) })
315316
}
316317

318+
/// This functions returns an interned id for an empty string
319+
///
320+
/// # Safety
321+
/// No preconditions
322+
#[no_mangle]
323+
pub unsafe extern "C" fn ddog_prof_Profile_interned_empty_string() -> GenerationalId<StringId> {
324+
internal::Profile::INTERNED_EMPTY_STRING
325+
}
326+
317327
/// This functions interns its argument into the profiler.
318328
/// If successful, it an opaque interning ID.
319329
/// This ID is valid for use on this profiler, until the profiler is reset.

profiling/src/internal/profile/interning_api/generational_ids.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub struct Generation {
1111
}
1212

1313
impl Generation {
14+
const IMMORTAL: Self = Self { id: u64::MAX };
15+
1416
/// The only way to create a generation. Guaranteed to give a new value each time.
1517
pub fn new() -> Self {
1618
static COUNTER: AtomicU64 = AtomicU64::new(0);
@@ -33,11 +35,20 @@ pub struct GenerationalId<T: Copy> {
3335

3436
impl<T: Copy> GenerationalId<T> {
3537
pub fn get(&self, expected_generation: Generation) -> anyhow::Result<T> {
36-
anyhow::ensure!(self.generation == expected_generation);
38+
anyhow::ensure!(
39+
self.generation == expected_generation || self.generation == Generation::IMMORTAL
40+
);
3741
Ok(self.id)
3842
}
3943

40-
pub fn new(id: T, generation: Generation) -> Self {
44+
pub const fn new(id: T, generation: Generation) -> Self {
4145
Self { id, generation }
4246
}
47+
48+
pub const fn new_immortal(id: T) -> Self {
49+
Self {
50+
id,
51+
generation: Generation::IMMORTAL,
52+
}
53+
}
4354
}

profiling/src/internal/profile/interning_api/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,15 @@ impl Profile {
156156
Ok(GenerationalId::new(id, self.generation))
157157
}
158158

159+
pub const INTERNED_EMPTY_STRING: GenerationalId<StringId> =
160+
GenerationalId::new_immortal(StringId::ZERO);
161+
159162
pub fn intern_string(&mut self, s: &str) -> anyhow::Result<GenerationalId<StringId>> {
160-
Ok(GenerationalId::new(self.intern(s), self.generation))
163+
if s.is_empty() {
164+
Ok(Self::INTERNED_EMPTY_STRING)
165+
} else {
166+
Ok(GenerationalId::new(self.intern(s), self.generation))
167+
}
161168
}
162169

163170
pub fn intern_strings(

0 commit comments

Comments
 (0)