Skip to content

Commit

Permalink
more caching #41, #40
Browse files Browse the repository at this point in the history
  • Loading branch information
frosklis committed Feb 27, 2021
1 parent 90375c8 commit 1f17a5c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 30 deletions.
15 changes: 14 additions & 1 deletion src/commands/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::path::PathBuf;
use colored::Colorize;

use crate::models::{conversion, Account, Balance, Currency, HasName, Money};
use crate::parser::value_expr::build_root_node_from_expression;
use crate::parser::Tokenizer;
use crate::Error;
use crate::{filter, CommonOpts};
Expand All @@ -24,9 +25,21 @@ pub fn execute(options: &CommonOpts, flat: bool, show_total: bool) -> Result<(),

let mut balances: HashMap<Rc<Account>, Balance> = HashMap::new();

// Build a cache of abstract value trees, it takes time to parse expressions, so better do it only once
let mut regexes = HashMap::new();
let query = filter::preprocess_query(&options.query);
let node = if query.len() > 2 {
Some(build_root_node_from_expression(
query.as_str(),
&mut regexes,
))
} else {
None
};

for t in ledger.transactions.iter() {
for p in t.postings_iter() {
if !filter::filter(&options, t, p, &mut ledger.commodities)? {
if !filter::filter(&options, &node, t, p, &mut ledger.commodities)? {
continue;
}
let mut cur_bal = balances
Expand Down
17 changes: 16 additions & 1 deletion src/commands/register.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::models::{Balance, Money};
use crate::parser::value_expr::build_root_node_from_expression;
use crate::parser::Tokenizer;
use crate::Error;
use crate::{filter, CommonOpts};
use colored::Colorize;
use std::collections::HashMap;
use terminal_size::{terminal_size, Width};

/// Register report
Expand Down Expand Up @@ -33,10 +35,23 @@ pub fn execute(options: &CommonOpts) -> Result<(), Error> {
} else {
width - w_date - w_description - w_amount - w_balance
};

// Build a cache of abstract value trees, it takes time to parse expressions, so better do it only once
let mut regexes = HashMap::new();
let query = filter::preprocess_query(&options.query);
let node = if query.len() > 2 {
Some(build_root_node_from_expression(
query.as_str(),
&mut regexes,
))
} else {
None
};

for t in ledger.transactions.iter() {
let mut counter = 0;
for p in t.postings_iter() {
if !filter::filter(&options, t, p, &mut ledger.commodities)? {
if !filter::filter(&options, &node, t, p, &mut ledger.commodities)? {
continue;
}
counter += 1;
Expand Down
31 changes: 4 additions & 27 deletions src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use std::collections::HashMap;

pub fn filter(
options: &CommonOpts,
node: &Option<Node>,
transaction: &Transaction<Posting>,
posting: &Posting,
commodities: &mut List<Currency>,
) -> Result<bool, Error> {
// Get what's needed
let predicate = preprocess_query(&options.query);
let real = options.real;

// Check for real postings
Expand All @@ -35,32 +35,9 @@ pub fn filter(
return Ok(false);
}
}

filter_predicate(
predicate.as_str(),
posting,
transaction,
commodities,
&mut HashMap::new(),
)
}

pub fn filter_predicate(
predicate: &str,
posting: &Posting,
transaction: &Transaction<Posting>,
commodities: &mut List<Currency>,
regexes: &mut HashMap<String, Regex>,
) -> Result<bool, Error> {
if (predicate.len() == 0) | (predicate == "()") {
return Ok(true);
}
let result = eval_expression(predicate, posting, transaction, commodities, regexes);
match result {
EvalResult::Boolean(b) => Ok(b),
_ => Err(Error {
message: vec![predicate.red().bold(), "should return a boolean".normal()],
}),
match node {
Some(x) => filter_expression(x, posting, transaction, commodities, &mut HashMap::new()),
None => Ok(true),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub use transaction::{
};

use crate::filter::filter_expression;
use crate::models::transaction::Cost;
use crate::parser::value_expr::build_root_node_from_expression;
use crate::parser::ParsedLedger;
use crate::parser::{tokenizers, value_expr};
use crate::{filter::filter_predicate, models::transaction::Cost};
use crate::{Error, List};
use num::BigInt;
use std::rc::Rc;
Expand Down

0 comments on commit 1f17a5c

Please sign in to comment.