perf: drop intermediate allocs in WebDAV href encoding; fold group-list COUNT into one query
webdav encode_uri_path runs on every PROPFIND href and did
.map(...).collect::<Vec<_>>().join("/"), allocating a String per segment plus
a joined Vec. Write each utf8_percent_encode Display adapter straight into a
single preallocated String. Behavior is identical (split on '/', encode each
segment, join with '/'), including leading/trailing-slash edge cases.
subject_group list / list_with_counts each issued a second SELECT COUNT(*)
round-trip for the total. Fold it into the page query via COUNT(*) OVER() —
the pattern folder_db_repository already uses — halving the round-trips.
total_count is read from the first row and is 0 on an empty page, matching
folder_db_repository's documented convention.
https://claude.ai/code/session_01UtfkS3nZF1vrF5jNAps6wV
This commit is contained in:
@@ -63,10 +63,23 @@ fn encode_path_segment(segment: &str) -> String {
|
||||
|
||||
/// Percent-encode a full slash-separated path, encoding each segment individually.
|
||||
pub(crate) fn encode_uri_path(path: &str) -> String {
|
||||
path.split('/')
|
||||
.map(encode_path_segment)
|
||||
.collect::<Vec<_>>()
|
||||
.join("/")
|
||||
use std::fmt::Write as _;
|
||||
// `utf8_percent_encode` returns a `Display` adapter, so write each encoded
|
||||
// segment straight into `out` — avoids a String per segment and the joined
|
||||
// Vec the previous `.map(...).collect::<Vec<_>>().join("/")` allocated on
|
||||
// every PROPFIND href.
|
||||
let mut out = String::with_capacity(path.len() + 8);
|
||||
for (i, segment) in path.split('/').enumerate() {
|
||||
if i > 0 {
|
||||
out.push('/');
|
||||
}
|
||||
let _ = write!(
|
||||
out,
|
||||
"{}",
|
||||
utf8_percent_encode(segment, PATH_SEGMENT_ENCODE_SET)
|
||||
);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Build the `<D:href>` value for a non-collection (file) resource.
|
||||
|
||||
Reference in New Issue
Block a user