From 6f1990a2e1b7c678571d24471511c17cb634fef8 Mon Sep 17 00:00:00 2001 From: Benedict Börger Date: Fri, 12 Jul 2019 22:52:26 +0200 Subject: [web_frontend] filering: perfomance optimization --- src/web_frontend/chart.rs | 4 ++-- src/web_frontend/transactions.rs | 6 +++--- src/web_frontend/util.rs | 45 ++++++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 28 deletions(-) (limited to 'src/web_frontend') diff --git a/src/web_frontend/chart.rs b/src/web_frontend/chart.rs index 1c74e80..c8e058a 100644 --- a/src/web_frontend/chart.rs +++ b/src/web_frontend/chart.rs @@ -85,9 +85,9 @@ pub fn chart_handler(account : &RawStr, start : Option<&RawStr>, end : Option<&R filter_string.push_str(";"); } } - let t_filtered_cloned = crate::web_frontend::util::apply_transaction_filter(filter_string.clone(), t_final.clone()); + let t_filtered_cloned = crate::web_frontend::util::apply_transaction_filter(&filter_string, &t_final); - let tmp = t_filtered_cloned.into_iter() + let tmp = t_filtered_cloned.iter() .fold(0.0, |acc, x| acc + x.amount); complete = complete + tmp.abs(); groups.insert(section_name, GroupValues{ amount: complete, filter : filter_string } ); diff --git a/src/web_frontend/transactions.rs b/src/web_frontend/transactions.rs index b3aa8cf..a8ca33c 100644 --- a/src/web_frontend/transactions.rs +++ b/src/web_frontend/transactions.rs @@ -19,8 +19,8 @@ use chrono::Datelike; * changes! */ #[derive(Serialize)] -struct TransactionContext { - transactions : Vec, +struct TransactionContext<'t> { + transactions : Vec<&'t crate::banking::account::Transaction>, account_name : String, filter : String, date_start : String, @@ -65,7 +65,7 @@ pub fn transaction_handler(account : &RawStr, start : Option<&RawStr>, end : Opt // apply date filters let t_filtered = crate::web_frontend::util::apply_date_filter(t.clone(), date_start, date_end); // apply filter - let ft = crate::web_frontend::util::apply_transaction_filter(transaction_filter.clone(), t_filtered); + let ft = crate::web_frontend::util::apply_transaction_filter(&transaction_filter, &t_filtered); let context = TransactionContext { transactions: ft, account_name : account_name, filter : transaction_filter, date_start : date_start.to_string()[0..7].to_string(), diff --git a/src/web_frontend/util.rs b/src/web_frontend/util.rs index 7a29173..9bfef25 100644 --- a/src/web_frontend/util.rs +++ b/src/web_frontend/util.rs @@ -68,13 +68,12 @@ struct TransactionFilter { * sender name of transation. The value is what is should be and can be a regex * key value pair is split by - */ -pub fn apply_transaction_filter(filter : String, transactions : Vec) -> Vec { - let mut tmp = transactions.clone(); +pub fn apply_transaction_filter<'t>(filter : &str , transactions : &'t Vec) -> Vec<&'t crate::banking::account::Transaction> { + let mut tmp; // special case if for general search if !filter.to_string().contains(";") { - println!("in special case"); let re = Regex::new(&filter).unwrap(); - tmp = transactions.into_iter().filter(|transaction| re.is_match(&transaction.sender_name) || re.is_match(&transaction.reference) ).collect(); + tmp = transactions.iter().filter(|transaction| re.is_match(&transaction.sender_name) || re.is_match(&transaction.reference) ).collect(); return tmp; } @@ -83,41 +82,41 @@ pub fn apply_transaction_filter(filter : String, transactions : Vec = entry.split("-").collect(); - println!("{:?}", v); if v.len() > 1 { if v[0] == "sender" { - println!("Filter for sender_name"); - sender_name_vec.push(v[1].to_string()); + let re_sender = RegexBuilder::new(v[1]) + .case_insensitive(true) + .build() + .expect("invalid regex"); + sender_name_vec.push(re_sender); } else if v[0] == "reference" { - println!("filter for reference"); - reference_vec.push(v[1].to_string()); + let re_reference = RegexBuilder::new(v[1]) + .case_insensitive(true) + .build() + .expect("invalid regex"); + reference_vec.push(re_reference); } } } - tmp = transactions.clone().into_iter().filter(|transaction| { - let mut sender_match = false; - let mut reference_match = false; + // prebuild regexes ... + println!("sender name len {}, reference name length {}", sender_name_vec.len(), reference_vec.len()); + tmp = transactions.iter().filter(|transaction| { for sender in &sender_name_vec { - let mut re_sender = RegexBuilder::new(&sender) - .case_insensitive(true) - .build() - .expect("invalid regex"); - if re_sender.is_match(&transaction.sender_name) { - sender_match = true; + if sender.is_match(&transaction.sender_name) { + return true; } } for reference in &reference_vec { - let re = Regex::new(&reference).unwrap(); - if re.is_match(&transaction.reference) { - reference_match = true; + if reference.is_match(&transaction.reference) { + return true; } } - sender_match || reference_match + return false; }).collect(); + println!("end filtering {}", filter); tmp - } pub fn apply_date_filter(transactions : Vec, date_start : chrono::NaiveDate, date_end : chrono::NaiveDate) -> Vec { -- cgit v1.2.3-70-g09d2