commit 9fd9f8217e102c24ca980ec92f689403a64f3c2a
parent 77e9bb891753ecc6ef06660b7a339c9e07675ff4
Author: Antoine A <>
Date: Sat, 11 Jan 2025 16:39:27 +0100
common: optimize subject parsing
Diffstat:
1 file changed, 12 insertions(+), 28 deletions(-)
diff --git a/common/taler-api/src/subject.rs b/common/taler-api/src/subject.rs
@@ -163,27 +163,13 @@ pub fn parse_incoming_unstructured(subject: &str) -> Option<IncomingSubjectResul
// Find and concatenate valid parts of a keys
let (parts, concatenated) = {
- let mut parts = Vec::new();
- let mut concatenated = String::new();
- let mut part = None;
- for (i, b) in subject.as_bytes().iter().enumerate() {
- if b.is_ascii_alphanumeric() {
- if part.is_none() {
- part = Some(i);
- }
- } else if let Some(from) = part {
- let start = concatenated.len() as u16;
- concatenated.push_str(&subject[from..i]);
- let end = concatenated.len() as u16;
- parts.push(start..end);
- part = None;
- }
- }
- if let Some(from) = part {
- let start = concatenated.len() as u16;
- concatenated.push_str(&subject[from..]);
- let end = concatenated.len() as u16;
- parts.push(start..end);
+ let mut parts = Vec::with_capacity(4);
+ let mut concatenated = String::with_capacity(subject.len().min(KYC_SIZE + 10));
+ parts.push(0u16);
+ for part in subject.as_bytes().split(|b| !b.is_ascii_alphanumeric()) {
+ // SAFETY: part are all valid ASCII alphanumeric
+ concatenated.push_str(unsafe { std::str::from_utf8_unchecked(part) });
+ parts.push(concatenated.len() as u16);
}
(parts, concatenated)
};
@@ -191,19 +177,17 @@ pub fn parse_incoming_unstructured(subject: &str) -> Option<IncomingSubjectResul
// Find best candidates
let mut best: Option<Candidate> = None;
// For each part as a starting point
- for (i, start) in parts.iter().enumerate() {
+ for (i, &start) in parts.iter().enumerate() {
// Use progressively longer concatenation
- for end in parts[i..].iter() {
- let range = start.start..end.end;
+ for &end in &parts[i..] {
// Until they are to long to be a key
- if range.len() > KYC_SIZE {
+ if (end - start) as usize > KYC_SIZE {
break;
- }
+ };
// Parse the concatenated parts
// SAFETY: we now end.end <= concatenated.len
- let slice =
- unsafe { &concatenated.get_unchecked(start.start as usize..end.end as usize) };
+ let slice = unsafe { &concatenated.get_unchecked(start as usize..end as usize) };
if let Some(other) = parse_single(slice) {
// On success update best candidate
match &mut best {