Skip to content

Commit 9daf790

Browse files
Add EventId type that gives additional guarantees on top of StringId.
1 parent 4968d22 commit 9daf790

File tree

8 files changed

+80
-53
lines changed

8 files changed

+80
-53
lines changed

analyzeme/src/event.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl<'a> Parser<'a> {
104104

105105
self.pos = end;
106106

107-
if self.full_text[start .. end].iter().any(u8::is_ascii_control) {
107+
if self.full_text[start..end].iter().any(u8::is_ascii_control) {
108108
return self.err("Found ASCII control character in <text>");
109109
}
110110

@@ -166,8 +166,7 @@ mod tests {
166166

167167
#[test]
168168
fn parse_event_id_n_args() {
169-
let (label, args) =
170-
Event::parse_event_id(Cow::from("foo\x1earg1\x1earg2\x1earg3"));
169+
let (label, args) = Event::parse_event_id(Cow::from("foo\x1earg1\x1earg2\x1earg3"));
171170

172171
assert_eq!(label, "foo");
173172
assert_eq!(

analyzeme/src/profiling_data.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use measureme::file_header::{
77
FILE_MAGIC_EVENT_STREAM,
88
};
99
use measureme::ByteVecSink;
10-
use measureme::{ProfilerFiles, RawEvent, SerializationSink, StringTableBuilder};
10+
use measureme::{EventId, ProfilerFiles, RawEvent, SerializationSink, StringTableBuilder};
1111
use serde::{Deserialize, Deserializer};
1212
use std::error::Error;
1313
use std::fs;
@@ -94,7 +94,9 @@ impl ProfilingData {
9494

9595
let timestamp = Timestamp::from_raw_event(&raw_event, self.metadata.start_time);
9696

97-
let event_id = string_table.get(raw_event.event_id).to_string();
97+
let event_id = string_table
98+
.get(raw_event.event_id.to_string_id())
99+
.to_string();
98100
// Parse out the label and arguments from the `event_id`.
99101
let (label, additional_data) = Event::parse_event_id(event_id);
100102

@@ -230,7 +232,7 @@ impl ProfilingDataBuilder {
230232
F: FnOnce(&mut Self),
231233
{
232234
let event_kind = self.string_table.alloc(event_kind);
233-
let event_id = self.string_table.alloc(event_id);
235+
let event_id = EventId::from_label(self.string_table.alloc(event_id));
234236

235237
inner(self);
236238

@@ -251,7 +253,7 @@ impl ProfilingDataBuilder {
251253
timestamp_nanos: u64,
252254
) -> &mut Self {
253255
let event_kind = self.string_table.alloc(event_kind);
254-
let event_id = self.string_table.alloc(event_id);
256+
let event_id = EventId::from_label(self.string_table.alloc(event_id));
255257

256258
let raw_event = RawEvent::new_instant(event_kind, event_id, thread_id, timestamp_nanos);
257259

analyzeme/src/stringtable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use measureme::file_header::{
77
};
88
use measureme::stringtable::{METADATA_STRING_ID, STRING_ID_MASK, TERMINATOR};
99
use measureme::{Addr, StringId};
10+
use memchr::memchr;
1011
use rustc_hash::FxHashMap;
1112
use std::borrow::Cow;
1213
use std::error::Error;
13-
use memchr::memchr;
1414

1515
fn deserialize_index_entry(bytes: &[u8]) -> (StringId, Addr) {
1616
(

analyzeme/src/testing_common.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::timestamp::Timestamp;
22
use crate::{Event, ProfilingData};
3-
use measureme::{EventIdBuilder, Profiler, SerializationSink, StringId};
3+
use measureme::{EventId, EventIdBuilder, Profiler, SerializationSink, StringId};
44
use rustc_hash::FxHashMap;
55
use std::borrow::Cow;
66
use std::default::Default;
@@ -26,11 +26,7 @@ struct ExpectedEvent {
2626
}
2727

2828
impl ExpectedEvent {
29-
fn new(
30-
kind: &'static str,
31-
label: &'static str,
32-
args: &[&'static str]
33-
) -> ExpectedEvent {
29+
fn new(kind: &'static str, label: &'static str, args: &[&'static str]) -> ExpectedEvent {
3430
ExpectedEvent {
3531
kind: Cow::from(kind),
3632
label: Cow::from(label),
@@ -47,21 +43,20 @@ fn generate_profiling_data<S: SerializationSink>(
4743
) -> Vec<Event<'static>> {
4844
let profiler = Arc::new(Profiler::<S>::new(Path::new(filestem)).unwrap());
4945

50-
let event_id_virtual = StringId::new_virtual(42);
51-
46+
let event_id_virtual = EventId::from_label(StringId::new_virtual(42));
5247
let event_id_builder = EventIdBuilder::new(&profiler);
5348

54-
let event_ids = vec![
49+
let event_ids: Vec<(StringId, EventId)> = vec![
5550
(
5651
profiler.alloc_string("Generic"),
57-
profiler.alloc_string("SomeGenericActivity"),
52+
EventId::from_label(profiler.alloc_string("SomeGenericActivity")),
5853
),
5954
(profiler.alloc_string("Query"), event_id_virtual),
6055
(
6156
profiler.alloc_string("QueryWithArg"),
6257
event_id_builder.from_label_and_arg(
6358
profiler.alloc_string("AQueryWithArg"),
64-
profiler.alloc_string("some_arg")
59+
profiler.alloc_string("some_arg"),
6560
),
6661
),
6762
];
@@ -104,7 +99,7 @@ fn generate_profiling_data<S: SerializationSink>(
10499
// An example of allocating the string contents of an event id that has
105100
// already been used
106101
profiler.map_virtual_to_concrete_string(
107-
event_id_virtual,
102+
event_id_virtual.to_string_id(),
108103
profiler.alloc_string("SomeQuery")
109104
);
110105

@@ -195,7 +190,7 @@ fn pseudo_invocation<S: SerializationSink>(
195190
random: usize,
196191
thread_id: u32,
197192
recursions_left: usize,
198-
event_ids: &[(StringId, StringId)],
193+
event_ids: &[(StringId, EventId)],
199194
expected_events_templates: &[ExpectedEvent],
200195
expected_events: &mut Vec<Event<'static>>,
201196
) {

measureme/src/event_id.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,39 @@ use crate::{Profiler, SerializationSink, StringComponent, StringId};
1313
/// arguments. Future versions my support other optional suffixes (with a tag
1414
/// other than '\x11' after the '\x1E' separator), such as a "category".
1515
16-
1716
/// The byte used to separate arguments from the label and each other.
1817
pub const SEPARATOR_BYTE: &str = "\x1E";
1918

19+
/// An `EventId` is a `StringId` with the additional guarantee that the
20+
/// corresponding string conforms to the event_id grammar.
21+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
22+
#[repr(C)]
23+
pub struct EventId(StringId);
24+
25+
impl EventId {
26+
pub const INVALID: EventId = EventId(StringId::INVALID);
27+
28+
#[inline]
29+
pub fn to_string_id(self) -> StringId {
30+
self.0
31+
}
32+
33+
#[inline]
34+
pub fn as_u32(self) -> u32 {
35+
self.0.as_u32()
36+
}
37+
38+
#[inline]
39+
pub fn from_label(label: StringId) -> EventId {
40+
EventId(label)
41+
}
42+
43+
#[inline]
44+
pub fn from_virtual(virtual_id: StringId) -> EventId {
45+
EventId(virtual_id)
46+
}
47+
}
48+
2049
pub struct EventIdBuilder<'p, S: SerializationSink> {
2150
profiler: &'p Profiler<S>,
2251
}
@@ -26,19 +55,20 @@ impl<'p, S: SerializationSink> EventIdBuilder<'p, S> {
2655
EventIdBuilder { profiler }
2756
}
2857

29-
pub fn from_label(&self, label: StringId) -> StringId {
30-
// Just forward the string ID, i single identifier is a valid event_id
31-
label
58+
#[inline]
59+
pub fn from_label(&self, label: StringId) -> EventId {
60+
// Just forward the string ID, a single identifier is a valid event_id
61+
EventId::from_label(label)
3262
}
3363

34-
pub fn from_label_and_arg(&self, label: StringId, arg: StringId) -> StringId {
35-
self.profiler.alloc_string(&[
64+
pub fn from_label_and_arg(&self, label: StringId, arg: StringId) -> EventId {
65+
EventId(self.profiler.alloc_string(&[
3666
// Label
3767
StringComponent::Ref(label),
3868
// Seperator and start tag for arg
3969
StringComponent::Value(SEPARATOR_BYTE),
4070
// Arg string id
4171
StringComponent::Ref(arg),
42-
])
72+
]))
4373
}
4474
}

measureme/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub mod stringtable;
5050

5151
pub mod rustc;
5252

53-
pub use crate::event_id::EventIdBuilder;
53+
pub use crate::event_id::{EventId, EventIdBuilder};
5454
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
5555
pub use crate::file_serialization_sink::FileSerializationSink;
5656
#[cfg(not(target_arch = "wasm32"))]

measureme/src/profiler.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::event_id::EventId;
12
use crate::file_header::{write_file_header, FILE_MAGIC_EVENT_STREAM};
23
use crate::raw_event::RawEvent;
34
use crate::serialization::SerializationSink;
@@ -92,7 +93,7 @@ impl<S: SerializationSink> Profiler<S> {
9293

9394
/// Records an event with the given parameters. The event time is computed
9495
/// automatically.
95-
pub fn record_instant_event(&self, event_kind: StringId, event_id: StringId, thread_id: u32) {
96+
pub fn record_instant_event(&self, event_kind: StringId, event_id: EventId, thread_id: u32) {
9697
let raw_event =
9798
RawEvent::new_instant(event_kind, event_id, thread_id, self.nanos_since_start());
9899

@@ -105,7 +106,7 @@ impl<S: SerializationSink> Profiler<S> {
105106
pub fn start_recording_interval_event<'a>(
106107
&'a self,
107108
event_kind: StringId,
108-
event_id: StringId,
109+
event_id: EventId,
109110
thread_id: u32,
110111
) -> TimingGuard<'a, S> {
111112
TimingGuard {
@@ -135,7 +136,7 @@ impl<S: SerializationSink> Profiler<S> {
135136
#[must_use]
136137
pub struct TimingGuard<'a, S: SerializationSink> {
137138
profiler: &'a Profiler<S>,
138-
event_id: StringId,
139+
event_id: EventId,
139140
event_kind: StringId,
140141
thread_id: u32,
141142
start_ns: u64,
@@ -157,11 +158,10 @@ impl<'a, S: SerializationSink> Drop for TimingGuard<'a, S> {
157158
}
158159

159160
impl<'a, S: SerializationSink> TimingGuard<'a, S> {
160-
161161
/// This method set a new `event_id` right before actually recording the
162162
/// event.
163163
#[inline]
164-
pub fn finish_with_override_event_id(mut self, event_id: StringId) {
164+
pub fn finish_with_override_event_id(mut self, event_id: EventId) {
165165
self.event_id = event_id;
166166
// Let's be explicit about it: Dropping the guard will record the event.
167167
drop(self)

0 commit comments

Comments
 (0)