From 10bef7df9bb224442b6e7873903ad729e0c83c6b Mon Sep 17 00:00:00 2001 From: Szepesi Tibor Date: Sun, 3 Nov 2024 20:05:35 +0100 Subject: [PATCH] Unify order api and websocket problem sorting (#93) --- src/handlers/problem/order.rs | 26 ++++----------------- src/utils/problems.rs | 43 +++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/handlers/problem/order.rs b/src/handlers/problem/order.rs index 14b7befc..64f6bb7e 100644 --- a/src/handlers/problem/order.rs +++ b/src/handlers/problem/order.rs @@ -2,7 +2,7 @@ use crate::{ error::{self, DatabaseError, Result}, extractors::Json, handlers::socket::Event, - utils::{execute_str, topics}, + utils::{execute_str, sort_linked, topics}, StateTrait, }; use axum::{extract::State, http::StatusCode}; @@ -275,7 +275,7 @@ pub async fn change( } pub async fn get(State(state): State) -> Result>> { - let mut res = problems_order::Entity::find().all(state.db()).await?; + let res = problems_order::Entity::find().all(state.db()).await?; debug!("res: {res:?}"); @@ -283,26 +283,10 @@ pub async fn get(State(state): State) -> Result return Ok(Json(Vec::new())); } - let Some(last_pos) = res.iter().position(|item| item.next.is_none()) else { - panic!("corrupted problem chain"); - }; - - let length = res.len(); - res.swap(last_pos, length - 1); - - let mut last_id = res[length - 1].id; - - for i in (0..(length - 1)).rev() { - for j in 0..i { - if res[j].next == Some(last_id) { - last_id = res[j].id; - res.swap(i, j); - break; - } - } - } + let sorted = sort_linked(res); + let ids = sorted.into_iter().map(|item| item.id).collect(); - Ok(Json(res.into_iter().map(|item| item.id).collect())) + Ok(Json(ids)) } pub(super) async fn delete_problem(txn: &T, id: Uuid) -> Result<()> diff --git a/src/utils/problems.rs b/src/utils/problems.rs index cf23e7e1..cb1585cb 100644 --- a/src/utils/problems.rs +++ b/src/utils/problems.rs @@ -57,7 +57,7 @@ impl Problems { .await .expect("failed to query the problems"); - let problems = Arc::new(RwLock::new(sort_initial_problems(res))); + let problems = Arc::new(RwLock::new(sort_linked(res))); let mut subscription = nats.subscribe(topics::problems()).await.unwrap(); @@ -211,8 +211,37 @@ impl Stream for ProblemStream { } } -fn sort_initial_problems(problems: Vec) -> Vec { - let length = problems.len(); +pub trait Linked { + fn get_id(&self) -> Uuid; + fn get_next(&self) -> Option; +} + +impl Linked for Problem { + #[inline] + fn get_id(&self) -> Uuid { + self.id + } + + #[inline] + fn get_next(&self) -> Option { + self.next + } +} + +impl Linked for problems_order::Model { + #[inline] + fn get_id(&self) -> Uuid { + self.id + } + + #[inline] + fn get_next(&self) -> Option { + self.next + } +} + +pub fn sort_linked(list: Vec) -> Vec { + let length = list.len(); if length == 0 { return Vec::new(); @@ -220,22 +249,22 @@ fn sort_initial_problems(problems: Vec) -> Vec { let mut map = HashMap::new(); - for problem in problems { - map.insert(problem.next, problem); + for item in list { + map.insert(item.get_next(), item); } let mut result = Vec::with_capacity(length); let mut last_id = { let last = map.remove(&None).unwrap(); - let last_id = last.id; + let last_id = last.get_id(); result.push(last); last_id }; while !map.is_empty() { let item = map.remove(&Some(last_id)).unwrap(); - last_id = item.id; + last_id = item.get_id(); result.push(item); }