diff options
author | Daniel <kingdread@gmx.de> | 2019-05-24 17:50:53 +0200 |
---|---|---|
committer | Daniel <kingdread@gmx.de> | 2019-05-24 17:50:53 +0200 |
commit | 9243e9c6cc6cdefe1565291a2933cc58556ebe9b (patch) | |
tree | c03c6117e81016b1548d9d83c31f03b2acdb14d9 /src/filters.rs | |
parent | 54e29430b3a668e9e98d3fc6e1a107fd36af8af4 (diff) | |
download | raidgrep-9243e9c6cc6cdefe1565291a2933cc58556ebe9b.tar.gz raidgrep-9243e9c6cc6cdefe1565291a2933cc58556ebe9b.tar.bz2 raidgrep-9243e9c6cc6cdefe1565291a2933cc58556ebe9b.zip |
lazily parse log events
A lot of time is spent parsing the actual log events, especially when
they are zipped, as they have to be decompressed first. This results in
huge run-time hits, especially for files where we could determine very
early if we actually need it.
For example, player names are saved in the header, which can be examined
very quickly. If we can determine at that stage that a log file will not
appear in the result set, we don't need to parse all the log events.
This patch relies on the partial parsing support of evtclib to do
exactly that. It parses only the header with the player names, and only
if there's a match, it will proceed to parse the events and do more
filtering.
In the future, we can extend this even more, for example we can also
check the boss ID that way, since we can also access that in the header.
On the downside, we now have the zip handling logic replicated in
raidgrep, as we want a "common" interface to extract the actual data
stream. But this logic could be pushed back to evtclib after polishing
it a bit. There are some problems with Rust's borrow checking though,
which is why it looks a bit convoluted.
Diffstat (limited to 'src/filters.rs')
-rw-r--r-- | src/filters.rs | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/src/filters.rs b/src/filters.rs index d8d43ea..8433690 100644 --- a/src/filters.rs +++ b/src/filters.rs @@ -1,16 +1,21 @@ -use evtclib::{AgentName, Log}; +use evtclib::{Agent, AgentName}; +use evtclib::raw::parser::PartialEvtc; use super::{SearchField, LogResult, Opt}; use chrono::Datelike; /// Do filtering based on the character or account name. -pub fn filter_name(log: &Log, opt: &Opt) -> bool { - for player in log.players() { - match player.name() { +pub fn filter_name(evtc: &PartialEvtc, opt: &Opt) -> bool { + for player in &evtc.agents { + let fancy = Agent::from_raw(player); + if fancy.is_err() { + continue; + } + match fancy.unwrap().name() { AgentName::Player { - account_name, - character_name, + ref account_name, + ref character_name, .. } => { if (opt.field.contains(&SearchField::Account) && opt.expression.is_match(account_name)) @@ -19,7 +24,7 @@ pub fn filter_name(log: &Log, opt: &Opt) -> bool { return true; } } - _ => unreachable!(), + _ => (), } } false |