mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-18 05:30:37 +00:00
provide EscapedStr type for faster string encoding
This commit is contained in:
@@ -18,6 +18,9 @@ struct Bar {
|
||||
|
||||
pub fn escape(c: &mut Criterion) {
|
||||
c.bench_function("small", |b| bench_json_encode_inner(b, "object_key"));
|
||||
c.bench_function("small_static", |b| {
|
||||
bench_json_encode_inner(b, &json::EscapedStr::from_static("object_key"));
|
||||
});
|
||||
c.bench_function("large_fmt", |b| {
|
||||
let value = Foo {
|
||||
some_field: Bar {
|
||||
|
||||
@@ -81,6 +81,7 @@ mod macros;
|
||||
mod str;
|
||||
mod value;
|
||||
|
||||
pub use str::EscapedStr;
|
||||
pub use value::{KeyEncoder, Null, ValueEncoder};
|
||||
|
||||
#[must_use]
|
||||
|
||||
@@ -8,10 +8,63 @@
|
||||
//!
|
||||
//! With modifications by Conrad Ludgate on behalf of Databricks.
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
fmt::{self, Write},
|
||||
};
|
||||
|
||||
use crate::{KeyEncoder, ValueEncoder, ValueSer};
|
||||
|
||||
pub struct EscapedStr(Cow<'static, [u8]>);
|
||||
|
||||
impl EscapedStr {
|
||||
/// Assumes the string does not need escaping.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This will panic if the string does need escaping.
|
||||
pub const fn from_static(s: &'static str) -> Self {
|
||||
let bytes = s.as_bytes();
|
||||
|
||||
let mut i = 0;
|
||||
while i < bytes.len() {
|
||||
let byte = bytes[i];
|
||||
let escape = ESCAPE[byte as usize];
|
||||
|
||||
assert!(escape == 0, "a character in the string needed escaping");
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Self(Cow::Borrowed(bytes))
|
||||
}
|
||||
|
||||
/// Escapes the string eagerly.
|
||||
pub fn escape(s: &str) -> Self {
|
||||
let mut writer = Vec::with_capacity(s.len());
|
||||
|
||||
Collect { buf: &mut writer }
|
||||
.write_str(s)
|
||||
.expect("formatting should not error");
|
||||
|
||||
Self(Cow::Owned(writer))
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyEncoder for &EscapedStr {}
|
||||
impl ValueEncoder for &EscapedStr {
|
||||
fn encode(self, v: crate::ValueSer<'_>) {
|
||||
let buf = &mut *v.buf;
|
||||
buf.reserve(2 + self.0.len());
|
||||
|
||||
buf.push(b'"');
|
||||
buf.extend_from_slice(&self.0);
|
||||
buf.push(b'"');
|
||||
|
||||
v.finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyEncoder for &str {}
|
||||
impl ValueEncoder for &str {
|
||||
#[inline]
|
||||
|
||||
@@ -84,6 +84,7 @@ impl<T: ValueEncoder> ValueEncoder for Option<T> {
|
||||
}
|
||||
|
||||
/// Represents the JSON null value.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Null;
|
||||
|
||||
impl ValueEncoder for Null {
|
||||
|
||||
Reference in New Issue
Block a user