Skip to content

Commit 96b83b2

Browse files
CopilotByron
andcommitted
Optimize :(optional) prefix stripping to avoid unnecessary allocations
Co-authored-by: Byron <[email protected]>
1 parent 142cdda commit 96b83b2

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

gix-config-value/src/path.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,16 @@ impl<'a> From<Cow<'a, BStr>> for Path<'a> {
112112

113113
// Check if the value starts with ":(optional)" prefix
114114
if value.starts_with(OPTIONAL_PREFIX) {
115-
// Strip the prefix and create a path marked as optional
116-
let stripped = &value[OPTIONAL_PREFIX.len()..];
115+
// Strip the prefix while preserving the Cow variant to avoid unnecessary allocations
116+
let stripped = match value {
117+
Cow::Borrowed(b) => Cow::Borrowed(&b[OPTIONAL_PREFIX.len()..]),
118+
Cow::Owned(mut b) => {
119+
b.drain(..OPTIONAL_PREFIX.len());
120+
Cow::Owned(b)
121+
}
122+
};
117123
Path {
118-
value: Cow::Owned(stripped.into()),
124+
value: stripped,
119125
is_optional: true,
120126
}
121127
} else {

gix-config-value/tests/value/path.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ mod interpolate {
131131
mod optional_prefix {
132132
use std::borrow::Cow;
133133

134+
use bstr::ByteSlice;
134135
use crate::{b, cow_str};
135136

136137
#[test]
@@ -215,4 +216,28 @@ mod optional_prefix {
215216

216217
Ok(())
217218
}
219+
220+
#[test]
221+
fn borrowed_path_stays_borrowed_after_prefix_stripping() {
222+
// Verify that we don't unnecessarily allocate when stripping the prefix from borrowed data
223+
let borrowed_input: &[u8] = b":(optional)/some/path";
224+
let path = gix_config_value::Path::from(Cow::Borrowed(borrowed_input.as_bstr()));
225+
226+
assert!(path.is_optional());
227+
assert_eq!(path.value.as_ref(), b"/some/path");
228+
// Verify it's still borrowed (no unnecessary allocation)
229+
assert!(matches!(path.value, Cow::Borrowed(_)));
230+
}
231+
232+
#[test]
233+
fn owned_path_stays_owned_after_prefix_stripping() {
234+
// Verify that owned data remains owned after prefix stripping (but efficiently)
235+
let owned_input = bstr::BString::from(":(optional)/some/path");
236+
let path = gix_config_value::Path::from(Cow::Owned(owned_input));
237+
238+
assert!(path.is_optional());
239+
assert_eq!(path.value.as_ref(), b"/some/path");
240+
// Verify it's still owned
241+
assert!(matches!(path.value, Cow::Owned(_)));
242+
}
218243
}

0 commit comments

Comments
 (0)