Skip to content

Commit 2592211

Browse files
committed
chore: various doc and small code improvements
1 parent bc03199 commit 2592211

1 file changed

Lines changed: 42 additions & 17 deletions

File tree

  • libdd-trace-utils/src/change_buffer

libdd-trace-utils/src/change_buffer/mod.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,16 @@ use crate::span::v04::Span;
9292
use crate::span::vec_map::VecMap;
9393
use crate::span::{SpanText, TraceData};
9494

95+
/// A stateful wrapper around a change buffer for processing and span reconstructions.
9596
pub struct ChangeBufferState<T: TraceData> {
9697
change_buffer: ChangeBuffer,
9798
spans: Vec<Option<Span<T>>>,
9899
traces: SmallTraceMap<T::Text>,
99-
/// String table indexed by sequential u32 IDs (O(1) lookup vs HashMap).
100+
/// Interned string table (O(1) lookup vs HashMap).
101+
///
102+
/// Note: currently the string table never shrinks (it is never compacted). When entries are
103+
/// evicted (freeing the backing strings), a small amount of memory is leaked (to hold the
104+
/// `None` value).
100105
string_table: Vec<Option<T::Text>>,
101106
tracer_service: T::Text,
102107
tracer_language: T::Text,
@@ -175,10 +180,6 @@ where
175180
tracer_language: T::Text,
176181
pid: u32,
177182
) -> Self {
178-
eprintln!(
179-
"[libdatadog pipeline] experiment: baseline (commit: {})",
180-
env!("GIT_COMMIT")
181-
);
182183
ChangeBufferState {
183184
change_buffer,
184185
spans: Vec::with_capacity(256),
@@ -346,6 +347,11 @@ where
346347
let mut count = self.change_buffer.read::<u64>(&mut index)? as u32;
347348

348349
let mut cached_slot: u32 = u32::MAX;
350+
// We keep a bunch of cached internal pointers. They are safe to use as long as we don't
351+
// modify their parent vector and keep a unique borrow to `self` overall.
352+
//
353+
// Using mutable references instead would be better, but is not possible (or very hard)
354+
// given we iterate and nest calls to different submethods taking a `&mut self`.
349355
let mut cached_span_ptr: *mut Span<T> = std::ptr::null_mut();
350356
let mut cached_deferred_meta: *mut VecMap<u32, u32> = std::ptr::null_mut();
351357
let mut cached_deferred_metrics: *mut VecMap<u32, f64> = std::ptr::null_mut();
@@ -407,11 +413,18 @@ where
407413
span
408414
};
409415

410-
// SAFETY: span_ptr is valid it was obtained from self.spans above
411-
// or from the cache which was set in a previous iteration of the same loop.
412-
// self.spans is not modified during this function (no inserts/removes).
416+
// SAFETY: span_ptr is valid for read and writes: it was obtained from self.spans above or
417+
// from the cache which was set in a previous iteration of the same loop. self.spans is not
418+
// modified during this function (no inserts/removes).
413419
let span = unsafe { &mut *span_ptr };
414420

421+
// SAFETY:
422+
//
423+
// - `cached_deferred_xxx`: they point to writable memory (derived from self), and we don't
424+
// modify, move nor drop the parent `deferred_xxx` vec, so the pointer should remain
425+
// valid.
426+
// - `xxx_unchecked`: we rely on the encoder side to write the correct arguments to an
427+
// opcode.
415428
match op.opcode {
416429
OpCode::SetMetaAttr => {
417430
let key_id: u32 = self.get_num_arg(index)?;
@@ -501,6 +514,9 @@ where
501514
.ok_or(ChangeBufferError::StringNotFound(num))
502515
}
503516

517+
/// # Safety
518+
///
519+
/// Caller must ensure `*index + size_of::<T::Tex>() <= self.change_buffer.len`.
504520
#[inline(always)]
505521
unsafe fn get_string_arg_unchecked(&self, index: &mut usize) -> T::Text {
506522
let num: u32 = self.change_buffer.read_unchecked(index);
@@ -514,12 +530,16 @@ where
514530
self.change_buffer.read(index)
515531
}
516532

533+
/// # Safety
534+
///
535+
/// Caller must ensure `*index + size_of::<U>() <= self.change_buffer.len`.
517536
#[inline(always)]
518537
unsafe fn get_num_arg_unchecked<U: Copy + FromBytes>(&self, index: &mut usize) -> U {
519-
self.change_buffer.read_unchecked(index)
538+
// Safety: this function's pre-condition
539+
unsafe { self.change_buffer.read_unchecked(index) }
520540
}
521541

522-
fn get_mut_span(&mut self, slot: u32) -> Result<&mut Span<T>> {
542+
fn get_span_mut(&mut self, slot: u32) -> Result<&mut Span<T>> {
523543
self.spans
524544
.get_mut(slot as usize)
525545
.and_then(|opt| opt.as_mut())
@@ -533,6 +553,7 @@ where
533553
.ok_or(ChangeBufferError::SpanNotFound(slot as u64))
534554
}
535555

556+
#[inline]
536557
pub fn get_trace(&self, id: &u128) -> Option<&Trace<T::Text>> {
537558
self.traces.get(id)
538559
}
@@ -627,12 +648,14 @@ where
627648
.ok_or(ChangeBufferError::SpanNotFound(*slot as u64))
628649
}
629650

651+
#[inline]
630652
pub fn get_string(&self, id: u32) -> Option<T::Text> {
631653
self.string_table
632654
.get(id as usize)
633655
.and_then(|opt| opt.clone())
634656
}
635657

658+
#[inline]
636659
pub fn set_default_meta(&mut self, tags: Vec<(T::Text, T::Text)>) {
637660
self.default_meta = tags;
638661
}
@@ -647,6 +670,7 @@ where
647670
let idx = slot as usize;
648671
if idx < self.deferred_meta.len() {
649672
let pairs: Vec<(u32, u32)> = self.deferred_meta[idx].drain(..).collect();
673+
650674
for (key_id, val_id) in pairs {
651675
if let (Some(key), Some(val)) = (self.get_string(key_id), self.get_string(val_id)) {
652676
span.meta.insert(key, val);
@@ -655,6 +679,7 @@ where
655679
}
656680
if idx < self.deferred_metrics.len() {
657681
let pairs: Vec<(u32, f64)> = self.deferred_metrics[idx].drain(..).collect();
682+
658683
for (key_id, val) in pairs {
659684
if let Some(key) = self.get_string(key_id) {
660685
span.metrics.insert(key, val);
@@ -737,25 +762,25 @@ where
737762
}
738763
}
739764
OpCode::SetServiceName => {
740-
self.get_mut_span(op.slot_index)?.service = self.get_string_arg(index)?;
765+
self.get_span_mut(op.slot_index)?.service = self.get_string_arg(index)?;
741766
}
742767
OpCode::SetResourceName => {
743-
self.get_mut_span(op.slot_index)?.resource = self.get_string_arg(index)?;
768+
self.get_span_mut(op.slot_index)?.resource = self.get_string_arg(index)?;
744769
}
745770
OpCode::SetError => {
746-
self.get_mut_span(op.slot_index)?.error = self.get_num_arg(index)?;
771+
self.get_span_mut(op.slot_index)?.error = self.get_num_arg(index)?;
747772
}
748773
OpCode::SetStart => {
749-
self.get_mut_span(op.slot_index)?.start = self.get_num_arg(index)?;
774+
self.get_span_mut(op.slot_index)?.start = self.get_num_arg(index)?;
750775
}
751776
OpCode::SetDuration => {
752-
self.get_mut_span(op.slot_index)?.duration = self.get_num_arg(index)?;
777+
self.get_span_mut(op.slot_index)?.duration = self.get_num_arg(index)?;
753778
}
754779
OpCode::SetType => {
755-
self.get_mut_span(op.slot_index)?.r#type = self.get_string_arg(index)?;
780+
self.get_span_mut(op.slot_index)?.r#type = self.get_string_arg(index)?;
756781
}
757782
OpCode::SetName => {
758-
self.get_mut_span(op.slot_index)?.name = self.get_string_arg(index)?;
783+
self.get_span_mut(op.slot_index)?.name = self.get_string_arg(index)?;
759784
}
760785
OpCode::SetTraceMetaAttr => {
761786
let name = self.get_string_arg(index)?;

0 commit comments

Comments
 (0)