Fix demo sorting and store data in analysis-input instead of always loading it

This commit is contained in:
Lol3rrr
2024-10-19 00:02:16 +02:00
parent 966bd4f413
commit f22c1a1420
6 changed files with 56 additions and 33 deletions

View File

@@ -1,5 +1,3 @@
use std::path::PathBuf;
use diesel::prelude::*; use diesel::prelude::*;
use diesel_async::RunQueryDsl; use diesel_async::RunQueryDsl;
@@ -7,6 +5,34 @@ pub mod base;
pub mod heatmap; pub mod heatmap;
pub mod perround; pub mod perround;
#[derive(Debug, Clone)]
pub struct AnalysisInput {
pub steamid: String,
pub demoid: String,
data: std::sync::Arc<memmap2::Mmap>,
}
impl AnalysisInput {
pub async fn load(
steamid: String,
demoid: String,
path: impl AsRef<std::path::Path>,
) -> Result<Self, ()> {
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 { pub trait Analysis {
fn analyse( fn analyse(
&self, &self,
@@ -86,13 +112,15 @@ where
None => return Ok(None), None => return Ok(None),
}; };
let input = AnalysisInput { let input = AnalysisInput::load(
path: upload_folder task.steam_id.clone(),
task.demo_id.clone(),
upload_folder
.join(&task.steam_id) .join(&task.steam_id)
.join(format!("{}.dem", task.demo_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); let tmp = action(input, &mut *conn);
tmp.await.map_err(|e| TaskError::RunningAction(e))?; 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,
}

View File

@@ -59,10 +59,7 @@ impl Analysis for BaseAnalysis {
> { > {
tracing::info!("Performing Base analysis"); tracing::info!("Performing Base analysis");
let file = std::fs::File::open(&input.path).unwrap(); let result = analysis::endofgame::parse(input.data()).unwrap();
let mmap = unsafe { memmap2::MmapOptions::new().map(&file).unwrap() };
let result = analysis::endofgame::parse(&mmap).unwrap();
let base_result = BaseInfo { let base_result = BaseInfo {
map: result.map, map: result.map,

View File

@@ -29,11 +29,8 @@ impl Analysis for HeatmapAnalysis {
> { > {
tracing::info!("Generating HEATMAPs"); 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 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()); tracing::info!("Got {} Entity-Heatmaps", result.player_heatmaps.len());
let heatmap_result: Vec<_> = result let heatmap_result: Vec<_> = result

View File

@@ -27,10 +27,7 @@ impl Analysis for PerRoundAnalysis {
>, >,
(), (),
> { > {
let file = std::fs::File::open(&input.path).unwrap(); let result = analysis::perround::parse(input.data()).unwrap();
let mmap = unsafe { memmap2::MmapOptions::new().map(&file).unwrap() };
let result = analysis::perround::parse(&mmap).unwrap();
let values: Vec<crate::models::DemoRound> = result let values: Vec<crate::models::DemoRound> = result
.rounds .rounds

View File

@@ -171,18 +171,22 @@ pub fn router(config: RouterConfig) -> axum::Router {
} }
// Save a `Stream` to a file // Save a `Stream` to a file
async fn stream_to_file<S, E>(path: impl Into<std::path::PathBuf>, stream: S) -> Result<(), (axum::http::StatusCode, String)> async fn stream_to_file<S, E>(
path: impl Into<std::path::PathBuf>,
stream: S,
) -> Result<(), (axum::http::StatusCode, String)>
where where
S: futures::Stream<Item = Result<axum::body::Bytes, E>>, S: futures::Stream<Item = Result<axum::body::Bytes, E>>,
E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>, E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
{ {
use futures::{Stream, TryStreamExt}; use futures::{Stream, TryStreamExt};
let path: std::path::PathBuf = path.into(); let path: std::path::PathBuf = path.into();
async { async {
// Convert the stream into an `AsyncRead`. // 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); let body_reader = tokio_util::io::StreamReader::new(body_with_io_error);
futures::pin_mut!(body_reader); futures::pin_mut!(body_reader);
@@ -192,8 +196,13 @@ where
// Copy the body into the file. // Copy the body into the file.
tokio::io::copy(&mut body_reader, &mut file).await?; tokio::io::copy(&mut body_reader, &mut file).await?;
Ok::<_,std::io::Error>(()) Ok::<_, std::io::Error>(())
} }
.await .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(),
)
})
} }

View File

@@ -84,7 +84,7 @@ async fn list(
// Sort this // Sort this
let mut output = demos.into_values().collect::<Vec<_>>(); let mut output = demos.into_values().collect::<Vec<_>>();
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)) Ok(axum::response::Json(output))
} }
@@ -130,7 +130,9 @@ async fn upload(
let demo_file_path = user_folder.join(format!("{}.dem", demo_id)); 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; let mut db_con = crate::db_connection().await;