Skip to content

Commit 8b30ccd

Browse files
authored
Parallel Parsing (#4)
parse the log lines in parallel
1 parent 7ca380e commit 8b30ccd

File tree

5 files changed

+136
-14
lines changed

5 files changed

+136
-14
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
- name: Install SQLite
11-
run: sudo apt-get install libsqlite3-dev
11+
run: sudo apt-get update && sudo apt-get install libsqlite3-dev
1212

1313
- name: Checkout sources
1414
uses: actions/checkout@v2

Cargo.lock

Lines changed: 117 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "topngx"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
authors = ["Garrett Squire <github@garrettsquire.com>"]
55
edition = "2018"
66
description = "Top for NGINX"
@@ -14,6 +14,7 @@ atty = "0.2"
1414
env_logger = "0.7"
1515
log = "0.4"
1616
once_cell = "1.4"
17+
rayon = "1.3"
1718
regex = "1.3"
1819
rusqlite = "0.23"
1920
structopt = "0.3"

src/main.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::io::{self, BufRead, BufReader};
33

44
use anyhow::{anyhow, Result};
55
use log::{debug, info};
6+
use rayon::prelude::*;
67
use regex::Regex;
78
use rusqlite::types::ToSql;
89
use structopt::StructOpt;
@@ -136,15 +137,16 @@ fn run(opts: &Options, fields: Option<Vec<String>>, queries: Option<Vec<String>>
136137
}
137138

138139
fn parse_input(input: Box<dyn BufRead>, pattern: &Regex, processor: &Processor) -> Result<()> {
139-
let mut records = vec![];
140-
141-
for line in input.lines() {
142-
match pattern.captures(&line?) {
143-
None => {}
140+
let fields = processor.fields.clone();
141+
let lines: Vec<String> = input.lines().filter_map(|l| l.ok()).collect();
142+
let records: Vec<_> = lines
143+
.par_iter()
144+
.filter_map(|line| match pattern.captures(&line) {
145+
None => None,
144146
Some(c) => {
145-
let mut record: Vec<(String, Box<dyn ToSql>)> = vec![];
147+
let mut record: Vec<(String, Box<dyn ToSql + Send + Sync>)> = vec![];
146148

147-
for field in &processor.fields {
149+
for field in &fields {
148150
if field == STATUS_TYPE {
149151
let status = c.name("status").map_or("", |m| m.as_str());
150152
let status_type = status.parse::<u16>().unwrap_or(0) / 100;
@@ -169,10 +171,10 @@ fn parse_input(input: Box<dyn BufRead>, pattern: &Regex, processor: &Processor)
169171
}
170172
}
171173

172-
records.push(record);
174+
Some(record)
173175
}
174-
}
175-
}
176+
})
177+
.collect();
176178

177179
processor.process(records)
178180
}

src/processor.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ impl Processor {
5454
}
5555

5656
/// Insert all of the given records into the database.
57-
pub(crate) fn process(&self, records: Vec<Vec<(String, Box<dyn ToSql>)>>) -> Result<()> {
57+
pub(crate) fn process(
58+
&self,
59+
records: Vec<Vec<(String, Box<dyn ToSql + Send + Sync>)>>,
60+
) -> Result<()> {
5861
let insert_stmt = format!(
5962
"INSERT INTO LOG ({columns}) VALUES ({placeholders})",
6063
columns = self.columns,

0 commit comments

Comments
 (0)