44use super :: datatypes:: {
55 ddog_prof_EncodedProfile_drop, Period , ProfileResult , SampleType , SerializeResult ,
66} ;
7+ use crate :: arc_handle:: ArcHandle ;
78use anyhow:: Context ;
89use function_name:: named;
910use libdd_common_ffi:: slice:: { AsBytes , CharSlice , Slice } ;
1011use libdd_common_ffi:: { wrap_with_ffi_result, Error , Result , Timespec } ;
1112use libdd_profiling:: dynamic:: {
12- DynamicFunctionIndex as InnerDynamicFunctionIndex , DynamicLabel as InnerDynamicLabel ,
13- DynamicLocation as InnerDynamicLocation , DynamicProfile as InnerDynamicProfile ,
13+ DynamicFunction as InnerDynamicFunction , DynamicFunctionIndex as InnerDynamicFunctionIndex ,
14+ DynamicLabel as InnerDynamicLabel , DynamicLocation as InnerDynamicLocation ,
15+ DynamicProfile as InnerDynamicProfile ,
16+ DynamicProfilesDictionary as InnerDynamicProfilesDictionary ,
1417 DynamicSample as InnerDynamicSample , DynamicStackTraceIndex as InnerDynamicStackTraceIndex ,
1518 DynamicStringIndex as InnerDynamicStringIndex ,
1619} ;
@@ -77,6 +80,31 @@ pub struct DynamicFunctionIndex {
7780 pub value : u32 ,
7881}
7982
83+ #[ repr( C ) ]
84+ #[ derive( Copy , Clone , Debug , Default , Eq , PartialEq , Hash ) ]
85+ pub struct DynamicFunction {
86+ pub name : DynamicStringIndex ,
87+ pub filename : DynamicStringIndex ,
88+ }
89+
90+ impl From < InnerDynamicFunction > for DynamicFunction {
91+ fn from ( value : InnerDynamicFunction ) -> Self {
92+ Self {
93+ name : value. name . into ( ) ,
94+ filename : value. filename . into ( ) ,
95+ }
96+ }
97+ }
98+
99+ impl From < DynamicFunction > for InnerDynamicFunction {
100+ fn from ( value : DynamicFunction ) -> Self {
101+ Self {
102+ name : value. name . into ( ) ,
103+ filename : value. filename . into ( ) ,
104+ }
105+ }
106+ }
107+
80108impl From < InnerDynamicFunctionIndex > for DynamicFunctionIndex {
81109 fn from ( value : InnerDynamicFunctionIndex ) -> Self {
82110 Self { value : value. value }
@@ -191,18 +219,37 @@ fn ffi_sample_to_parts<'a>(
191219
192220#[ must_use]
193221#[ no_mangle]
194- pub unsafe extern "C" fn ddog_prof_DynamicProfile_new (
222+ pub unsafe extern "C" fn ddog_prof_DynamicProfile_with_dictionary (
223+ out : * mut DynamicProfile ,
224+ dict : & ArcHandle < InnerDynamicProfilesDictionary > ,
225+ sample_types : Slice < SampleType > ,
226+ period : Option < & Period > ,
227+ start_time : Option < & Timespec > ,
228+ ) -> crate :: profile_status:: ProfileStatus {
229+ crate :: ensure_non_null_out_parameter!( out) ;
230+ match unsafe { dynamic_profile_with_dictionary ( dict, sample_types, period, start_time) } {
231+ Ok ( profile) => unsafe {
232+ out. write ( profile) ;
233+ crate :: profile_status:: ProfileStatus :: OK
234+ } ,
235+ Err ( err) => crate :: profile_status:: ProfileStatus :: from ( err) ,
236+ }
237+ }
238+
239+ unsafe fn dynamic_profile_with_dictionary (
240+ dict : & ArcHandle < InnerDynamicProfilesDictionary > ,
195241 sample_types : Slice < SampleType > ,
196242 period : Option < & Period > ,
197243 start_time : Option < & Timespec > ,
198- ) -> DynamicProfileNewResult {
199- let sample_types = sample_types. into_slice ( ) ;
244+ ) -> std :: result :: Result < DynamicProfile , crate :: ProfileError > {
245+ let sample_types = sample_types. try_as_slice ( ) ? ;
200246 let period = period. copied ( ) ;
201247 let start_time = start_time. map ( Into :: into) ;
202- match InnerDynamicProfile :: try_new ( sample_types, period, start_time) {
203- Ok ( profile) => DynamicProfileNewResult :: Ok ( DynamicProfile :: new ( profile) ) ,
204- Err ( err) => DynamicProfileNewResult :: Err ( anyhow:: Error :: from ( err) . into ( ) ) ,
205- }
248+ let dict = dict. try_clone_into_arc ( ) ?;
249+ let profile =
250+ InnerDynamicProfile :: try_new_with_dictionary ( sample_types, period, start_time, dict)
251+ . map_err ( crate :: ProfileError :: from_display) ?;
252+ Ok ( DynamicProfile :: new ( profile) )
206253}
207254
208255#[ no_mangle]
@@ -212,38 +259,6 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_drop(profile: *mut DynamicProf
212259 }
213260}
214261
215- #[ must_use]
216- #[ no_mangle]
217- #[ named]
218- pub unsafe extern "C" fn ddog_prof_DynamicProfile_intern_string (
219- profile : * mut DynamicProfile ,
220- s : CharSlice ,
221- ) -> Result < DynamicStringIndex > {
222- wrap_with_ffi_result ! ( {
223- let profile = dynamic_profile_ptr_to_inner( profile) ?;
224- let s = str :: from_utf8( s. try_as_bytes( ) ?) ?;
225- Ok :: <DynamicStringIndex , anyhow:: Error >( profile. intern_string( s) ?. into( ) )
226- } )
227- }
228-
229- #[ must_use]
230- #[ no_mangle]
231- #[ named]
232- pub unsafe extern "C" fn ddog_prof_DynamicProfile_intern_function (
233- profile : * mut DynamicProfile ,
234- name : DynamicStringIndex ,
235- filename : DynamicStringIndex ,
236- ) -> Result < DynamicFunctionIndex > {
237- wrap_with_ffi_result ! ( {
238- let profile = dynamic_profile_ptr_to_inner( profile) ?;
239- Ok :: <DynamicFunctionIndex , anyhow:: Error >(
240- profile
241- . intern_function( name. into( ) , filename. into( ) ) ?
242- . into( ) ,
243- )
244- } )
245- }
246-
247262#[ must_use]
248263#[ no_mangle]
249264#[ named]
@@ -489,24 +504,70 @@ mod tests {
489504 fn ffi_roundtrip_serializes_dynamic_profile ( ) -> std:: result:: Result < ( ) , Error > {
490505 unsafe {
491506 let sample_type = SampleType :: WallTime ;
492- let mut profile = std:: result:: Result :: from ( ddog_prof_DynamicProfile_new (
507+ let mut dict = ArcHandle :: < InnerDynamicProfilesDictionary > :: default ( ) ;
508+ std:: result:: Result :: < ( ) , _ > :: from (
509+ crate :: profiles:: dynamic_profiles_dictionary:: ddog_prof_DynamicProfilesDictionary_new (
510+ & mut dict,
511+ ) ,
512+ )
513+ . unwrap ( ) ;
514+ let dict_ref = dict. as_inner ( ) . ok ( ) ;
515+
516+ let mut function_name = DynamicStringIndex :: default ( ) ;
517+ std:: result:: Result :: < ( ) , _ > :: from (
518+ crate :: profiles:: dynamic_profiles_dictionary:: ddog_prof_DynamicProfilesDictionary_insert_str (
519+ & mut function_name,
520+ dict_ref,
521+ CharSlice :: from ( "ruby_func" ) ,
522+ crate :: profiles:: utf8:: Utf8Option :: Validate ,
523+ ) ,
524+ )
525+ . unwrap ( ) ;
526+ let mut filename = DynamicStringIndex :: default ( ) ;
527+ std:: result:: Result :: < ( ) , _ > :: from (
528+ crate :: profiles:: dynamic_profiles_dictionary:: ddog_prof_DynamicProfilesDictionary_insert_str (
529+ & mut filename,
530+ dict_ref,
531+ CharSlice :: from ( "file.rb" ) ,
532+ crate :: profiles:: utf8:: Utf8Option :: Validate ,
533+ ) ,
534+ )
535+ . unwrap ( ) ;
536+ let mut label_key = DynamicStringIndex :: default ( ) ;
537+ std:: result:: Result :: < ( ) , _ > :: from (
538+ crate :: profiles:: dynamic_profiles_dictionary:: ddog_prof_DynamicProfilesDictionary_insert_str (
539+ & mut label_key,
540+ dict_ref,
541+ CharSlice :: from ( "thread id" ) ,
542+ crate :: profiles:: utf8:: Utf8Option :: Validate ,
543+ ) ,
544+ )
545+ . unwrap ( ) ;
546+ let mut function = DynamicFunctionIndex :: default ( ) ;
547+ let ffi_function = DynamicFunction {
548+ name : function_name,
549+ filename,
550+ } ;
551+ std:: result:: Result :: < ( ) , _ > :: from (
552+ crate :: profiles:: dynamic_profiles_dictionary:: ddog_prof_DynamicProfilesDictionary_insert_function (
553+ & mut function,
554+ dict_ref,
555+ & ffi_function,
556+ ) ,
557+ )
558+ . unwrap ( ) ;
559+
560+ let mut profile = DynamicProfile {
561+ inner : std:: ptr:: null_mut ( ) ,
562+ } ;
563+ std:: result:: Result :: < ( ) , _ > :: from ( ddog_prof_DynamicProfile_with_dictionary (
564+ & mut profile,
565+ & dict,
493566 Slice :: from_raw_parts ( & sample_type, 1 ) ,
494567 None ,
495568 None ,
496- ) ) ?;
497-
498- let function_name =
499- ddog_prof_DynamicProfile_intern_string ( & mut profile, CharSlice :: from ( "ruby_func" ) )
500- . unwrap ( ) ;
501- let filename =
502- ddog_prof_DynamicProfile_intern_string ( & mut profile, CharSlice :: from ( "file.rb" ) )
503- . unwrap ( ) ;
504- let function =
505- ddog_prof_DynamicProfile_intern_function ( & mut profile, function_name, filename)
506- . unwrap ( ) ;
507- let label_key =
508- ddog_prof_DynamicProfile_intern_string ( & mut profile, CharSlice :: from ( "thread id" ) )
509- . unwrap ( ) ;
569+ ) )
570+ . unwrap ( ) ;
510571
511572 let locations = [ DynamicLocation { function, line : 27 } ] ;
512573 let labels = [ DynamicLabel {
@@ -551,6 +612,9 @@ mod tests {
551612
552613 ddog_prof_EncodedProfile_drop ( & mut encoded) ;
553614 ddog_prof_DynamicProfile_drop ( & mut profile) ;
615+ crate :: profiles:: dynamic_profiles_dictionary:: ddog_prof_DynamicProfilesDictionary_drop (
616+ & mut dict,
617+ ) ;
554618 Ok ( ( ) )
555619 }
556620 }
0 commit comments