Skip to content

Commit 68c3214

Browse files
author
borney
committed
Optimize the filter
1 parent 32fa623 commit 68c3214

File tree

7 files changed

+50
-111
lines changed

7 files changed

+50
-111
lines changed

src/filter/buffer_filter.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
use crate::filter::Filter;
22
use crate::log::Log;
33
use async_trait::async_trait;
4-
use std::sync::Arc;
54

65
pub(crate) struct BufferFilter {
7-
filter: Option<Arc<dyn Filter>>,
86
buffers: Vec<String>,
97
all: bool,
108
}
119

1210
impl BufferFilter {
1311
#[allow(dead_code)]
14-
pub(crate) fn new(buffers: Vec<String>, filter: Option<Arc<dyn Filter>>) -> Self {
12+
pub(crate) fn new(buffers: Vec<String>) -> Self {
1513
let mut s = Self {
1614
buffers,
17-
filter,
1815
all: false,
1916
};
2017

@@ -26,26 +23,17 @@ impl BufferFilter {
2623

2724
#[async_trait]
2825
impl Filter for BufferFilter {
29-
async fn filter(&self, mut log: Log) -> Option<Log> {
30-
if let Some(f) = &self.filter {
31-
let f = Arc::clone(f);
32-
if let Some(r) = f.filter(log).await {
33-
log = r;
34-
} else {
35-
return None;
36-
}
37-
}
38-
26+
async fn filter(&self, log: &Log) -> bool {
3927
if self.all {
40-
return Some(log);
28+
return false;
4129
}
4230

4331
for b in &self.buffers {
4432
if b == &log.buffer {
45-
return Some(log);
33+
return false;
4634
}
4735
}
4836

49-
None
37+
true
5038
}
5139
}

src/filter/level_filter.rs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,28 @@
11
use crate::filter::Filter;
22
use crate::log::{Level, Log};
33
use async_trait::async_trait;
4-
use std::sync::Arc;
54

65
pub(crate) struct LevelFilter {
7-
filter: Option<Arc<dyn Filter>>,
86
level: Level,
97
}
108

119
impl LevelFilter {
1210
#[allow(dead_code)]
13-
pub(crate) fn new(level: Level, filter: Option<Arc<dyn Filter>>) -> Self {
14-
Self { level, filter }
11+
pub(crate) fn new(level: Level) -> Self {
12+
Self { level }
1513
}
1614
}
1715

1816
#[async_trait]
1917
impl Filter for LevelFilter {
20-
async fn filter(&self, mut log: Log) -> Option<Log> {
21-
if let Some(f) = &self.filter {
22-
let f = Arc::clone(f);
23-
if let Some(r) = f.filter(log).await {
24-
log = r;
25-
} else {
26-
return None;
27-
}
28-
}
29-
18+
async fn filter(&self, log: &Log) -> bool {
3019
use std::str::FromStr;
3120

3221
if let Ok(level) = Level::from_str(&log.level) {
3322
if level >= self.level {
34-
Some(log)
35-
} else {
36-
None
23+
return false;
3724
}
38-
} else {
39-
None
4025
}
26+
true
4127
}
4228
}

src/filter/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,11 @@ pub(crate) use tag_filter::TagFilter;
1818
use crate::log::Log;
1919

2020
use async_trait::async_trait;
21-
use std::sync::Arc;
22-
23-
#[allow(dead_code)]
24-
pub(crate) type ArcFilter = Arc<dyn Filter>;
2521

2622
///
2723
/// Filter trait used to filter log
2824
///
2925
#[async_trait]
3026
pub trait Filter: Send + Sync {
31-
async fn filter(&self, log: Log) -> Option<Log>;
27+
async fn filter(&self, log: &Log) -> bool;
3228
}

src/filter/pid_filter.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,19 @@ use crate::log::Log;
33
use async_trait::async_trait;
44
use dashmap::DashSet;
55
use std::sync::atomic::{AtomicBool, Ordering};
6-
use std::sync::Arc;
76
use tokio::io::AsyncBufReadExt;
87
use tokio::process::{Child, Command};
98

109
pub(crate) struct PidFilter {
11-
filter: Option<Arc<dyn Filter>>,
1210
process: DashSet<String>,
1311
pids: DashSet<String>,
1412
first_filter: AtomicBool,
1513
}
1614

1715
impl PidFilter {
1816
#[allow(dead_code)]
19-
pub(crate) fn new(process: Vec<String>, filter: Option<Arc<dyn Filter>>) -> Self {
17+
pub(crate) fn new(process: Vec<String>) -> Self {
2018
Self {
21-
filter,
2219
process: DashSet::from_iter(process.into_iter()),
2320
pids: DashSet::new(),
2421
first_filter: AtomicBool::new(true),
@@ -36,18 +33,9 @@ impl PidFilter {
3633

3734
#[async_trait]
3835
impl Filter for PidFilter {
39-
async fn filter(&self, mut log: Log) -> Option<Log> {
40-
if let Some(f) = &self.filter {
41-
let f = Arc::clone(f);
42-
if let Some(r) = f.filter(log).await {
43-
log = r;
44-
} else {
45-
return None;
46-
}
47-
}
48-
36+
async fn filter(&self, log: &Log) -> bool {
4937
if self.process.is_empty() {
50-
return Some(log);
38+
return false;
5139
}
5240

5341
if self.first_filter.load(Ordering::Acquire) && self.pids.is_empty() {
@@ -102,15 +90,15 @@ impl Filter for PidFilter {
10290
_ => {}
10391
}
10492

105-
let mut r = None;
93+
let mut r = true;
10694

10795
if self.pids.contains(&log.pid) {
108-
r = Some(log);
96+
r = false;
10997
} else {
11098
for p in self.pids.iter() {
11199
let ptr = p.key().as_str();
112100
if log.is_events() && log.message.contains(ptr) {
113-
r = Some(log);
101+
r = false;
114102
break;
115103
}
116104
}

src/filter/revert_filter.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,16 @@ use crate::filter::Filter;
22
use crate::log::Log;
33
use async_trait::async_trait;
44
use regex::{Error, Regex, RegexBuilder};
5-
use std::sync::Arc;
65

76
pub(crate) struct RevertFilter {
8-
filter: Option<Arc<dyn Filter>>,
97
revert: String,
108
re: Result<Regex, Error>,
119
}
1210

1311
impl RevertFilter {
1412
#[allow(dead_code)]
15-
pub(crate) fn new(revert: String, ignore: bool, filter: Option<Arc<dyn Filter>>) -> Self {
13+
pub(crate) fn new(revert: String, ignore: bool) -> Self {
1614
Self {
17-
filter,
1815
revert: revert.clone(),
1916
re: RegexBuilder::new(&revert).case_insensitive(ignore).build(),
2017
}
@@ -23,28 +20,16 @@ impl RevertFilter {
2320

2421
#[async_trait]
2522
impl Filter for RevertFilter {
26-
async fn filter(&self, mut log: Log) -> Option<Log> {
27-
if let Some(f) = &self.filter {
28-
let f = Arc::clone(f);
29-
if let Some(r) = f.filter(log).await {
30-
log = r;
31-
} else {
32-
return None;
33-
}
34-
}
35-
23+
async fn filter(&self, log: &Log) -> bool {
3624
if self.revert.is_empty() {
37-
return Some(log);
25+
return false;
3826
}
3927

4028
if let Ok(re) = &self.re {
4129
if re.is_match(&log.tag) || re.is_match(&log.message) {
42-
None
43-
} else {
44-
Some(log)
30+
return true;
4531
}
46-
} else {
47-
Some(log)
4832
}
33+
false
4934
}
5035
}

src/filter/tag_filter.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,16 @@ use crate::log::Log;
33
use anyhow::Result;
44
use async_trait::async_trait;
55
use regex::{Error, Regex, RegexBuilder};
6-
use std::sync::Arc;
76

87
pub(crate) struct TagFilter {
9-
filter: Option<Arc<dyn Filter>>,
108
tag: String,
119
re: Result<Regex, Error>,
1210
}
1311

1412
impl TagFilter {
1513
#[allow(dead_code)]
16-
pub(crate) fn new(tag: String, ignore: bool, filter: Option<Arc<dyn Filter>>) -> Self {
14+
pub(crate) fn new(tag: String, ignore: bool) -> Self {
1715
Self {
18-
filter,
1916
tag: tag.clone(),
2017
re: RegexBuilder::new(&tag).case_insensitive(ignore).build(),
2118
}
@@ -24,28 +21,19 @@ impl TagFilter {
2421

2522
#[async_trait]
2623
impl Filter for TagFilter {
27-
async fn filter(&self, mut log: Log) -> Option<Log> {
28-
if let Some(f) = &self.filter {
29-
let f = Arc::clone(f);
30-
if let Some(r) = f.filter(log).await {
31-
log = r;
32-
} else {
33-
return None;
34-
}
35-
}
36-
24+
async fn filter(&self, log: &Log) -> bool {
3725
if self.tag.is_empty() {
38-
return Some(log);
26+
return false;
3927
}
4028

4129
if let Ok(re) = &self.re {
4230
if re.is_match(&log.tag) || re.is_match(&log.message) {
43-
Some(log)
31+
false
4432
} else {
45-
None
33+
true
4634
}
4735
} else {
48-
Some(log)
36+
false
4937
}
5038
}
5139
}

src/main.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::cli::Cli;
2-
use crate::filter::{ArcFilter, BufferFilter, LevelFilter, PidFilter, RevertFilter, TagFilter};
2+
use crate::filter::{BufferFilter, Filter, LevelFilter, PidFilter, RevertFilter, TagFilter};
33
use crate::sink::{FileSink, Sink, TerminalSink};
44
use crate::source::{ADBSource, Source};
55
use anyhow::Result;
66
use futures::StreamExt;
7-
use std::sync::Arc;
87
use tokio::process::{Child, Command};
98

109
mod cli;
@@ -38,23 +37,26 @@ async fn main() {
3837
}
3938

4039
async fn fetch(cli: Cli) {
41-
let source = Arc::new(ADBSource::new(if cli.device.is_empty() {
40+
let source = ADBSource::new(if cli.device.is_empty() {
4241
None
4342
} else {
4443
Some(cli.device)
45-
}));
44+
});
4645

47-
let filter: ArcFilter = Arc::new(PidFilter::new(cli.process, None));
48-
let filter: ArcFilter = Arc::new(BufferFilter::new(cli.buffers, Some(filter)));
49-
let filter: ArcFilter = Arc::new(LevelFilter::new(cli.level, Some(filter)));
50-
let filter: ArcFilter = Arc::new(TagFilter::new(cli.tag, cli.ignore, Some(filter)));
51-
let filter: ArcFilter = Arc::new(RevertFilter::new(cli.revert, cli.ignore, Some(filter)));
46+
let filters: Vec<Box<dyn Filter>> = vec![
47+
Box::new(PidFilter::new(cli.process)),
48+
Box::new(BufferFilter::new(cli.buffers)),
49+
Box::new(LevelFilter::new(cli.level)),
50+
Box::new(TagFilter::new(cli.tag, cli.ignore)),
51+
Box::new(RevertFilter::new(cli.revert, cli.ignore)),
52+
];
5253

53-
let mut sinks: Vec<Arc<dyn Sink>> = Vec::new();
54-
sinks.push(Arc::new(TerminalSink::new(cli.color, cli.tag_width)));
54+
let mut sinks: Vec<Box<dyn Sink>> = Vec::new();
55+
56+
sinks.push(Box::new(TerminalSink::new(cli.color, cli.tag_width)));
5557
if let Some(file) = cli.output {
5658
if let Ok(file) = FileSink::new(file).await {
57-
sinks.push(Arc::new(file));
59+
sinks.push(Box::new(file));
5860
}
5961
}
6062

@@ -63,9 +65,15 @@ async fn fetch(cli: Cli) {
6365
while let Some(r) = logs.next().await {
6466
match r {
6567
Ok(log) => {
66-
let l = { filter.filter(log).await };
68+
let mut is_filter = false;
69+
for filter in &filters {
70+
if filter.filter(&log).await {
71+
is_filter = true;
72+
break;
73+
}
74+
}
6775

68-
if let Some(log) = l {
76+
if !is_filter {
6977
for sink in &sinks {
7078
sink.write(log.clone()).await;
7179
}

0 commit comments

Comments
 (0)