From f22c1a1420d9e9de780f3e6c0ea3880684385e95 Mon Sep 17 00:00:00 2001 From: Lol3rrr Date: Sat, 19 Oct 2024 00:02:16 +0200 Subject: [PATCH] Fix demo sorting and store data in analysis-input instead of always loading it --- backend/src/analysis.rs | 49 +++++++++++++++++++++++--------- backend/src/analysis/base.rs | 5 +--- backend/src/analysis/heatmap.rs | 5 +--- backend/src/analysis/perround.rs | 5 +--- backend/src/api.rs | 19 +++++++++---- backend/src/api/demos.rs | 6 ++-- 6 files changed, 56 insertions(+), 33 deletions(-) diff --git a/backend/src/analysis.rs b/backend/src/analysis.rs index 1511f0c..ec63ec4 100644 --- a/backend/src/analysis.rs +++ b/backend/src/analysis.rs @@ -1,5 +1,3 @@ -use std::path::PathBuf; - use diesel::prelude::*; use diesel_async::RunQueryDsl; @@ -7,6 +5,34 @@ pub mod base; pub mod heatmap; pub mod perround; +#[derive(Debug, Clone)] +pub struct AnalysisInput { + pub steamid: String, + pub demoid: String, + data: std::sync::Arc, +} + +impl AnalysisInput { + pub async fn load( + steamid: String, + demoid: String, + path: impl AsRef, + ) -> Result { + let file = std::fs::File::open(path.as_ref()).unwrap(); + let mmap = unsafe { memmap2::MmapOptions::new().map(&file).unwrap() }; + + Ok(Self { + steamid, + demoid, + data: std::sync::Arc::new(mmap), + }) + } + + pub fn data(&self) -> &[u8] { + &self.data + } +} + pub trait Analysis { fn analyse( &self, @@ -86,13 +112,15 @@ where None => return Ok(None), }; - let input = AnalysisInput { - path: upload_folder + let input = AnalysisInput::load( + task.steam_id.clone(), + task.demo_id.clone(), + upload_folder .join(&task.steam_id) .join(format!("{}.dem", task.demo_id)), - steamid: task.steam_id.clone(), - demoid: task.demo_id.clone(), - }; + ) + .await + .unwrap(); let tmp = action(input, &mut *conn); tmp.await.map_err(|e| TaskError::RunningAction(e))?; @@ -121,10 +149,3 @@ where }; } } - -#[derive(Debug, Clone)] -pub struct AnalysisInput { - pub steamid: String, - pub demoid: String, - pub path: PathBuf, -} diff --git a/backend/src/analysis/base.rs b/backend/src/analysis/base.rs index ee494cb..7928def 100644 --- a/backend/src/analysis/base.rs +++ b/backend/src/analysis/base.rs @@ -59,10 +59,7 @@ impl Analysis for BaseAnalysis { > { tracing::info!("Performing Base analysis"); - let file = std::fs::File::open(&input.path).unwrap(); - let mmap = unsafe { memmap2::MmapOptions::new().map(&file).unwrap() }; - - let result = analysis::endofgame::parse(&mmap).unwrap(); + let result = analysis::endofgame::parse(input.data()).unwrap(); let base_result = BaseInfo { map: result.map, diff --git a/backend/src/analysis/heatmap.rs b/backend/src/analysis/heatmap.rs index 3d3677e..cf36c99 100644 --- a/backend/src/analysis/heatmap.rs +++ b/backend/src/analysis/heatmap.rs @@ -29,11 +29,8 @@ impl Analysis for HeatmapAnalysis { > { tracing::info!("Generating HEATMAPs"); - let file = std::fs::File::open(&input.path).unwrap(); - let mmap = unsafe { memmap2::MmapOptions::new().map(&file).unwrap() }; - let config = analysis::heatmap::Config { cell_size: 5.0 }; - let result = analysis::heatmap::parse(&config, &mmap).unwrap(); + let result = analysis::heatmap::parse(&config, input.data()).unwrap(); tracing::info!("Got {} Entity-Heatmaps", result.player_heatmaps.len()); let heatmap_result: Vec<_> = result diff --git a/backend/src/analysis/perround.rs b/backend/src/analysis/perround.rs index 755ce3e..c5e408f 100644 --- a/backend/src/analysis/perround.rs +++ b/backend/src/analysis/perround.rs @@ -27,10 +27,7 @@ impl Analysis for PerRoundAnalysis { >, (), > { - let file = std::fs::File::open(&input.path).unwrap(); - let mmap = unsafe { memmap2::MmapOptions::new().map(&file).unwrap() }; - - let result = analysis::perround::parse(&mmap).unwrap(); + let result = analysis::perround::parse(input.data()).unwrap(); let values: Vec = result .rounds diff --git a/backend/src/api.rs b/backend/src/api.rs index 55a5676..7101f15 100644 --- a/backend/src/api.rs +++ b/backend/src/api.rs @@ -171,18 +171,22 @@ pub fn router(config: RouterConfig) -> axum::Router { } // Save a `Stream` to a file -async fn stream_to_file(path: impl Into, stream: S) -> Result<(), (axum::http::StatusCode, String)> +async fn stream_to_file( + path: impl Into, + stream: S, +) -> Result<(), (axum::http::StatusCode, String)> where S: futures::Stream>, E: Into>, { use futures::{Stream, TryStreamExt}; - + let path: std::path::PathBuf = path.into(); async { // Convert the stream into an `AsyncRead`. - let body_with_io_error = stream.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err)); + let body_with_io_error = + stream.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err)); let body_reader = tokio_util::io::StreamReader::new(body_with_io_error); futures::pin_mut!(body_reader); @@ -192,8 +196,13 @@ where // Copy the body into the file. tokio::io::copy(&mut body_reader, &mut file).await?; - Ok::<_,std::io::Error>(()) + Ok::<_, std::io::Error>(()) } .await - .map_err(|err| (axum::http::StatusCode::INTERNAL_SERVER_ERROR, err.to_string())) + .map_err(|err| { + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + err.to_string(), + ) + }) } diff --git a/backend/src/api/demos.rs b/backend/src/api/demos.rs index 67ec9a2..68f3695 100644 --- a/backend/src/api/demos.rs +++ b/backend/src/api/demos.rs @@ -84,7 +84,7 @@ async fn list( // Sort this let mut output = demos.into_values().collect::>(); - output.sort_unstable_by_key(|d| d.uploaded_at); + output.sort_unstable_by_key(|d| std::cmp::Reverse(d.uploaded_at)); Ok(axum::response::Json(output)) } @@ -130,7 +130,9 @@ async fn upload( let demo_file_path = user_folder.join(format!("{}.dem", demo_id)); - super::stream_to_file(demo_file_path, file_field).await.unwrap(); + super::stream_to_file(demo_file_path, file_field) + .await + .unwrap(); let mut db_con = crate::db_connection().await;