This commit is contained in:
Robin Appelman 2023-03-04 17:20:59 +01:00
commit a27d1a8f6b
9 changed files with 25 additions and 22 deletions

View file

@ -19,6 +19,7 @@ main_error = "0.1"
paste = "1" paste = "1"
logos = "0.12" logos = "0.12"
memchr = "2.5.0" memchr = "2.5.0"
ahash = "0.8.3"
[dev-dependencies] [dev-dependencies]
criterion = "0.4" criterion = "0.4"

View file

@ -1,7 +1,7 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion}; use criterion::{black_box, criterion_group, criterion_main, Criterion};
use std::fs::read_to_string; use std::fs::read_to_string;
use std::time::Duration; use std::time::Duration;
use tf_log_parser::{parse, GameEvent, RawEvent, LineSplit}; use tf_log_parser::{parse, GameEvent, LineSplit, RawEvent};
pub fn parse_benchmark(c: &mut Criterion) { pub fn parse_benchmark(c: &mut Criterion) {
let input = read_to_string("test_data/log_2892242.log").unwrap(); let input = read_to_string("test_data/log_2892242.log").unwrap();

View file

@ -1,5 +1,5 @@
use iai::black_box; use iai::black_box;
use tf_log_parser::{LineSplit, parse, RawEvent}; use tf_log_parser::{parse, LineSplit, RawEvent};
static LOG: &str = include_str!("../test_data/log_2892242.log"); static LOG: &str = include_str!("../test_data/log_2892242.log");

View file

@ -1,5 +1,5 @@
use crate::raw_event::{split_player_subject, RawSubject}; use crate::raw_event::{split_player_subject, RawSubject};
use enum_iterator::{Sequence, all}; use enum_iterator::{all, Sequence};
use serde::ser::SerializeMap; use serde::ser::SerializeMap;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use std::cmp::Ordering; use std::cmp::Ordering;

View file

@ -9,12 +9,12 @@ use crate::module::{
pub use crate::subjectmap::SubjectMap; pub use crate::subjectmap::SubjectMap;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
pub use event::{EventMeta, GameEvent}; pub use event::{EventMeta, GameEvent};
use memchr::memmem::{find_iter, FindIter};
use nom::Err; use nom::Err;
pub use raw_event::{RawEvent, RawEventType}; pub use raw_event::{RawEvent, RawEventType};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::convert::TryInto; use std::convert::TryInto;
use std::fmt::Debug; use std::fmt::Debug;
use memchr::memmem::{find_iter, FindIter};
use thiserror::Error; use thiserror::Error;
mod common; mod common;
@ -81,7 +81,7 @@ pub fn parse_with_handler<Handler: EventHandler>(
let mut handler = Handler::default(); let mut handler = Handler::default();
let mut start_time: Option<NaiveDateTime> = None; let mut start_time: Option<NaiveDateTime> = None;
let mut subjects = SubjectMap::<Handler::PerSubjectData>::default(); let mut subjects = SubjectMap::<Handler::PerSubjectData>::with_capacity(32);
for event_res in events { for event_res in events {
let raw_event = event_res?; let raw_event = event_res?;
@ -141,7 +141,7 @@ impl<'a> LineSplit<'a> {
LineSplit { LineSplit {
input, input,
start: 0, start: 0,
iter: find_iter(input.as_bytes(), b"L ") iter: find_iter(input.as_bytes(), b"L "),
} }
} }
} }
@ -155,15 +155,13 @@ impl<'a> Iterator for LineSplit<'a> {
let line = &self.input[self.start..next]; let line = &self.input[self.start..next];
self.start = next + 2; self.start = next + 2;
Some(line) Some(line)
}, }
None if self.start < self.input.len() => { None if self.start < self.input.len() => {
let line = &self.input[self.start..]; let line = &self.input[self.start..];
self.start = self.input.len(); self.start = self.input.len();
Some(line) Some(line)
} }
_ => { _ => None,
None
}
} }
} }
} }
@ -174,4 +172,4 @@ fn test_split() {
let split: Vec<_> = LineSplit::new(&input).collect(); let split: Vec<_> = LineSplit::new(&input).collect();
let expected: Vec<_> = input.split("L ").collect(); let expected: Vec<_> = input.split("L ").collect();
assert_eq!(expected, split); assert_eq!(expected, split);
} }

View file

@ -95,9 +95,7 @@ impl EventHandler for ClassStatsHandler {
} }
} }
fn finish_global(self, _subjects: &SubjectMap) -> Self::GlobalOutput { fn finish_global(self, _subjects: &SubjectMap) -> Self::GlobalOutput {}
}
fn finish_per_subject( fn finish_per_subject(
&mut self, &mut self,

View file

@ -235,7 +235,6 @@ impl<T: GlobalData> EventHandler for T {
_subject: &SubjectData, _subject: &SubjectData,
_data: Self::PerSubjectData, _data: Self::PerSubjectData,
) -> Self::PerSubjectOutput { ) -> Self::PerSubjectOutput {
} }
} }
@ -269,9 +268,7 @@ impl<T: PlayerSpecificData + Default> EventHandler for PlayerHandler<T> {
subject_data.handle_event(meta, subject, event) subject_data.handle_event(meta, subject, event)
} }
fn finish_global(self, _subjects: &SubjectMap) -> Self::GlobalOutput { fn finish_global(self, _subjects: &SubjectMap) -> Self::GlobalOutput {}
}
fn finish_per_subject( fn finish_per_subject(
&mut self, &mut self,

View file

@ -3,10 +3,10 @@ use crate::{Error, Result};
use crate::{SubjectError, SubjectId}; use crate::{SubjectError, SubjectId};
use chrono::{NaiveDate, NaiveDateTime}; use chrono::{NaiveDate, NaiveDateTime};
use logos::{Lexer, Logos}; use logos::{Lexer, Logos};
use memchr::memchr;
use nom::{IResult, Needed}; use nom::{IResult, Needed};
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::num::ParseIntError; use std::num::ParseIntError;
use memchr::memchr;
/// Event that has only been minimally parsed. /// Event that has only been minimally parsed.
/// that way we can decide if we're interested in handling the event before parsing further /// that way we can decide if we're interested in handling the event before parsing further

View file

@ -1,11 +1,20 @@
use crate::raw_event::RawSubject; use crate::raw_event::RawSubject;
use crate::{SubjectData, SubjectError, SubjectId}; use crate::{SubjectData, SubjectError, SubjectId};
use std::collections::BTreeMap; use ahash::{AHashMap, RandomState};
use std::convert::TryInto; use std::convert::TryInto;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
#[derive(Default)] #[derive(Default)]
pub struct SubjectMap<T = ()>(BTreeMap<SubjectId, (SubjectData, T)>); pub struct SubjectMap<T = ()>(AHashMap<SubjectId, (SubjectData, T)>);
impl<T> SubjectMap<T> {
pub fn with_capacity(cap: usize) -> Self {
SubjectMap(AHashMap::with_capacity_and_hasher(
cap,
RandomState::default(),
))
}
}
impl<T> Index<SubjectId> for SubjectMap<T> { impl<T> Index<SubjectId> for SubjectMap<T> {
type Output = (SubjectData, T); type Output = (SubjectData, T);
@ -63,7 +72,7 @@ impl<T> IntoIterator for SubjectMap<T> {
} }
pub struct SubjectMapIter<T> { pub struct SubjectMapIter<T> {
iter: std::collections::btree_map::IntoIter<SubjectId, (SubjectData, T)>, iter: std::collections::hash_map::IntoIter<SubjectId, (SubjectData, T)>,
} }
impl<T> Iterator for SubjectMapIter<T> { impl<T> Iterator for SubjectMapIter<T> {