summaryrefslogtreecommitdiffstats
path: root/vendor/measureme/src/event_id.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/measureme/src/event_id.rs')
-rw-r--r--vendor/measureme/src/event_id.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/vendor/measureme/src/event_id.rs b/vendor/measureme/src/event_id.rs
new file mode 100644
index 000000000..ec4f5a4cb
--- /dev/null
+++ b/vendor/measureme/src/event_id.rs
@@ -0,0 +1,97 @@
+use smallvec::SmallVec;
+
+use crate::{Profiler, StringComponent, StringId};
+
+/// Event IDs are strings conforming to the following grammar:
+///
+/// ```ignore
+/// <event_id> = <label> {<argument>}
+/// <label> = <text>
+/// <argument> = '\x1E' <text>
+/// <text> = regex([^[[:cntrl:]]]+) // Anything but ASCII control characters
+/// ```
+///
+/// This means there's always a "label", followed by an optional list of
+/// arguments. Future versions my support other optional suffixes (with a tag
+/// other than '\x11' after the '\x1E' separator), such as a "category".
+
+/// The byte used to separate arguments from the label and each other.
+pub const SEPARATOR_BYTE: &str = "\x1E";
+
+/// An `EventId` is a `StringId` with the additional guarantee that the
+/// corresponding string conforms to the event_id grammar.
+#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
+#[repr(C)]
+pub struct EventId(StringId);
+
+impl EventId {
+ pub const INVALID: EventId = EventId(StringId::INVALID);
+
+ #[inline]
+ pub fn to_string_id(self) -> StringId {
+ self.0
+ }
+
+ #[inline]
+ pub fn as_u32(self) -> u32 {
+ self.0.as_u32()
+ }
+
+ #[inline]
+ pub fn from_label(label: StringId) -> EventId {
+ EventId(label)
+ }
+
+ #[inline]
+ pub fn from_virtual(virtual_id: StringId) -> EventId {
+ EventId(virtual_id)
+ }
+
+ /// Create an EventId from a raw u32 value. Only used internally for
+ /// deserialization.
+ #[inline]
+ pub fn from_u32(raw_id: u32) -> EventId {
+ EventId(StringId::new(raw_id))
+ }
+}
+
+pub struct EventIdBuilder<'p> {
+ profiler: &'p Profiler,
+}
+
+impl<'p> EventIdBuilder<'p> {
+ pub fn new(profiler: &Profiler) -> EventIdBuilder<'_> {
+ EventIdBuilder { profiler }
+ }
+
+ #[inline]
+ pub fn from_label(&self, label: StringId) -> EventId {
+ // Just forward the string ID, a single identifier is a valid event_id
+ EventId::from_label(label)
+ }
+
+ pub fn from_label_and_arg(&self, label: StringId, arg: StringId) -> EventId {
+ EventId(self.profiler.alloc_string(&[
+ // Label
+ StringComponent::Ref(label),
+ // Seperator and start tag for arg
+ StringComponent::Value(SEPARATOR_BYTE),
+ // Arg string id
+ StringComponent::Ref(arg),
+ ]))
+ }
+
+ pub fn from_label_and_args(&self, label: StringId, args: &[StringId]) -> EventId {
+ // Store up to 7 components on the stack: 1 label + 3 arguments + 3 argument separators
+ let mut parts = SmallVec::<[StringComponent<'_>; 7]>::with_capacity(1 + args.len() * 2);
+
+ parts.push(StringComponent::Ref(label));
+
+ for arg in args {
+ parts.push(StringComponent::Value(SEPARATOR_BYTE));
+ parts.push(StringComponent::Ref(*arg));
+ }
+
+ EventId(self.profiler.alloc_string(&parts[..]))
+ }
+}