mirror of
https://codeberg.org/icewind/tf-log-parser.git
synced 2026-06-03 18:24:09 +02:00
ahash
This commit is contained in:
parent
7bd667004b
commit
a27d1a8f6b
9 changed files with 25 additions and 22 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
14
src/lib.rs
14
src/lib.rs
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue