Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ serde = { version = "1", features = ["derive"], optional = true }
serde_json = { version = "1", default-features = false, optional = true, features = ["std", "raw_value"] }
serde_yaml_ng = { version = "0.10.0" }
simdutf8 = { version = "0.1.5", optional = true }
smol_str = { version = "0.2", features = ["serde"] }
fancy-regex = { version = "0.17", default-features = false, optional = true }
sha1 = { version = "0.10", optional = true }
sha2 = { version = "0.10", optional = true }
Expand Down
1 change: 1 addition & 0 deletions LICENSE-3rdparty.csv
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ simdutf8,https://github.com/rusticstuff/simdutf8,MIT OR Apache-2.0,Hans Kratz <h
siphasher,https://github.com/jedisct1/rust-siphash,MIT OR Apache-2.0,Frank Denis <github@pureftpd.org>
slab,https://github.com/tokio-rs/slab,MIT,Carl Lerche <me@carllerche.com>
smallvec,https://github.com/servo/rust-smallvec,MIT OR Apache-2.0,The Servo Project Developers
smol_str,https://github.com/rust-analyzer/smol_str,MIT OR Apache-2.0,Aleksey Kladov <aleksey.kladov@gmail.com>
snafu,https://github.com/shepmaster/snafu,MIT OR Apache-2.0,Jake Goulding <jake.goulding@gmail.com>
snafu-derive,https://github.com/shepmaster/snafu,MIT OR Apache-2.0,Jake Goulding <jake.goulding@gmail.com>
snap,https://github.com/BurntSushi/rust-snappy,BSD-3-Clause,Andrew Gallant <jamslam@gmail.com>
Expand Down
3 changes: 3 additions & 0 deletions changelog.d/1825.enhancement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Improved performance of VRL programs that read and write event fields.

authors: thomasqueirozb
47 changes: 31 additions & 16 deletions src/value/keystring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@ use std::borrow::Cow;
use std::fmt::{self, Display, Formatter};

use serde::{Deserialize, Serialize};
use smol_str::SmolStr;

/// The key type value. This is a simple zero-overhead wrapper set up to make it explicit that
/// object keys are read-only and their underlying type is opaque and may change for efficiency.
/// The key type for event objects. Backed by [`SmolStr`] so that strings up to
/// 22 bytes are stored inline (no heap allocation). Every capture-group name in
/// a typical regex (e.g. "host", "user", "timestamp") fits inline, making
/// `clone()` a plain 24-byte stack copy — no malloc, no atomic ops.
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
#[cfg_attr(any(test, feature = "proptest"), derive(proptest_derive::Arbitrary))]
#[serde(transparent)]
pub struct KeyString(String);
pub struct KeyString(SmolStr);

impl KeyString {
/// Convert the key into a boxed slice of bytes (`u8`).
#[inline]
#[must_use]
pub fn into_bytes(self) -> Box<[u8]> {
self.0.into_bytes().into()
self.0.as_bytes().to_vec().into_boxed_slice()
}

/// Is this string empty?
Expand All @@ -36,7 +38,7 @@ impl KeyString {
#[inline]
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
self.0.as_str()
}
}

Expand All @@ -48,50 +50,50 @@ impl Display for KeyString {

impl AsRef<str> for KeyString {
fn as_ref(&self) -> &str {
&self.0
self.0.as_str()
}
}

impl std::ops::Deref for KeyString {
type Target = str;
fn deref(&self) -> &str {
&self.0
self.0.as_str()
}
}

impl std::borrow::Borrow<str> for KeyString {
fn borrow(&self) -> &str {
&self.0
self.0.as_str()
}
}

impl PartialEq<str> for KeyString {
fn eq(&self, that: &str) -> bool {
self.0[..].eq(that)
self.0.as_str() == that
}
}

impl From<&str> for KeyString {
fn from(s: &str) -> Self {
Self(s.into())
Self(SmolStr::new(s))
}
}

impl From<String> for KeyString {
fn from(s: String) -> Self {
Self(s)
Self(SmolStr::new(s.as_str()))
}
}

impl From<Cow<'_, str>> for KeyString {
fn from(s: Cow<'_, str>) -> Self {
Self(s.into())
Self(SmolStr::new(s.as_ref()))
}
}

impl From<KeyString> for String {
fn from(s: KeyString) -> Self {
s.0
s.0.as_str().to_owned()
}
}

Expand All @@ -102,11 +104,24 @@ impl quickcheck::Arbitrary for KeyString {
}

fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let s = self.0.clone();
let s = self.0.as_str().to_string();
Box::new(s.shrink().map(Into::into))
}
}

#[cfg(any(test, feature = "proptest"))]
impl proptest::arbitrary::Arbitrary for KeyString {
type Parameters = ();
type Strategy = proptest::strategy::BoxedStrategy<Self>;

fn arbitrary_with((): Self::Parameters) -> Self::Strategy {
use proptest::prelude::Strategy;
proptest::arbitrary::any::<String>()
.prop_map(KeyString::from)
.boxed()
}
}

#[cfg(any(test, feature = "lua"))]
mod lua {
use mlua::prelude::LuaResult;
Expand All @@ -122,7 +137,7 @@ mod lua {

impl IntoLua for KeyString {
fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
self.0.into_lua(lua)
self.0.as_str().to_owned().into_lua(lua)
}
}
}
Loading