optimize subjectid

This commit is contained in:
Robin Appelman 2023-03-04 21:22:20 +01:00
commit 4819e4c105
4 changed files with 31 additions and 18 deletions

View file

@ -1,5 +1,7 @@
use iai::black_box; use iai::black_box;
use tf_log_parser::{parse, LineSplit, RawEvent}; use std::convert::TryFrom;
use tf_log_parser::raw_event::RawSubject;
use tf_log_parser::{parse, LineSplit, RawEvent, SubjectId};
static LOG: &str = include_str!("../test_data/log_2892242.log"); static LOG: &str = include_str!("../test_data/log_2892242.log");
@ -15,5 +17,9 @@ pub fn parse_raw() {
.count(), .count(),
); );
} }
pub fn subject_id() {
let raw = black_box(RawSubject::Player("Kumis<10><[U:1:169048576]><Blue>"));
black_box(SubjectId::try_from(&raw).unwrap());
}
iai::main!(parse_benchmark, parse_raw); iai::main!(parse_benchmark, parse_raw, subject_id);

View file

@ -1,5 +1,7 @@
use crate::raw_event::{split_player_subject, RawSubject}; use crate::raw_event::{split_player_subject, RawSubject};
use crate::{Error, Result};
use enum_iterator::{all, Sequence}; use enum_iterator::{all, Sequence};
use memchr::{memchr, memrchr};
use serde::ser::SerializeMap; use serde::ser::SerializeMap;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use std::cmp::Ordering; use std::cmp::Ordering;
@ -8,7 +10,6 @@ use std::fmt::{Debug, Display, Formatter};
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use std::str::FromStr; use std::str::FromStr;
use steamid_ng::{AccountType, Instance, SteamID, Universe}; use steamid_ng::{AccountType, Instance, SteamID, Universe};
use thiserror::Error;
#[derive(Serialize, Copy, Clone, Eq, PartialEq, Debug, Ord, PartialOrd, Hash)] #[derive(Serialize, Copy, Clone, Eq, PartialEq, Debug, Ord, PartialOrd, Hash)]
pub enum Team { pub enum Team {
@ -204,12 +205,7 @@ impl TryFrom<&RawSubject<'_>> for SubjectId {
fn try_from(raw: &RawSubject) -> Result<Self, Self::Error> { fn try_from(raw: &RawSubject) -> Result<Self, Self::Error> {
Ok(match raw { Ok(match raw {
RawSubject::Player(raw) => { RawSubject::Player(raw) => {
if let Some(raw_account_id) = raw if let Some(raw_account_id) = find_between_end(raw, b':', b']') {
.rsplit_once(":")
.map(|(_, s)| s)
.and_then(|s| s.split_once(']'))
.map(|(s, _)| s)
{
SubjectId::Player( SubjectId::Player(
raw_account_id raw_account_id
.parse() .parse()
@ -253,7 +249,7 @@ impl SubjectData {
} }
} }
#[derive(Debug, Error)] #[derive(Debug, thiserror::Error)]
pub enum SubjectError { pub enum SubjectError {
#[error("Invalid user id")] #[error("Invalid user id")]
InvalidUserId, InvalidUserId,
@ -317,3 +313,20 @@ impl Serialize for SteamId3 {
self.0.steam3().serialize(serializer) self.0.steam3().serialize(serializer)
} }
} }
pub fn split_once(input: &str, delim: u8, offset: usize) -> Result<(&str, &str)> {
let end = memchr(delim, input.as_bytes()).ok_or(Error::Incomplete)?;
Ok((&input[..end], &input[(end + offset)..]))
}
pub fn find_between_end(input: &str, start: u8, end: u8) -> Option<&str> {
let end = memrchr(end, input.as_bytes())?;
let start = memrchr(start, &input.as_bytes()[0..end])?;
Some(&input[(start + 1)..end])
}
#[test]
fn test_find_between_end() {
assert_eq!(Some("foo"), find_between_end("asd[foo]bar", b'[', b']'));
assert_eq!(None, find_between_end("asd]foo[bar", b'[', b']'));
}

View file

@ -21,7 +21,7 @@ mod common;
pub mod event; pub mod event;
#[macro_use] #[macro_use]
pub mod module; pub mod module;
mod raw_event; pub mod raw_event;
mod subjectmap; mod subjectmap;
#[derive(Error, Debug)] #[derive(Error, Debug)]

View file

@ -1,9 +1,8 @@
use crate::common::Team; use crate::common::{split_once, Team};
use crate::{Error, Result}; 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;
@ -136,11 +135,6 @@ pub fn subject_parser(input: &str) -> Result<(&str, RawSubject)> {
} }
} }
fn split_once(input: &str, delim: u8, offset: usize) -> Result<(&str, &str)> {
let end = memchr(delim, input.as_bytes()).ok_or(Error::Incomplete)?;
Ok((&input[..end], &input[(end + offset)..]))
}
#[derive(Copy, Clone, Debug, PartialEq, Logos)] #[derive(Copy, Clone, Debug, PartialEq, Logos)]
pub enum RawEventType { pub enum RawEventType {
#[token(r#"joined"#)] #[token(r#"joined"#)]