From 70aff6ed183103d3931521652cc7218e7677afd1 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Thu, 27 Aug 2026 14:51:35 +0300 Subject: [PATCH] Better query code --- src/data/repositories.rs | 156 ++++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 45 deletions(-) diff --git a/src/data/repositories.rs b/src/data/repositories.rs index 3c723ba..24a090a 100644 --- a/src/data/repositories.rs +++ b/src/data/repositories.rs @@ -2,11 +2,13 @@ use crate::data::Id; use crate::data::entities::{EntityData, EntityHandle}; use crate::notification::MaybeError; use parking_lot::{Mutex, RwLock}; +use rayon::iter::IndexedParallelIterator; +use rayon::iter::IntoParallelRefIterator; +use rayon::iter::ParallelIterator; use rusqlite::Connection; use std::marker::PhantomData; use std::ops::Deref; use std::rc::Weak; -use std::slice::Iter; use std::sync::Arc; pub trait Repository @@ -22,7 +24,6 @@ where fn delete(&mut self, handle: EntityHandle) -> MaybeError; fn init(&mut self) -> MaybeError; fn reload(&mut self) -> MaybeError; - fn query(&mut self, rule: fn(&T) -> bool) -> Query where Self: Sized; } struct QueryManger @@ -35,18 +36,33 @@ where pub struct Query where - R: Repository, D: DbLayer + R: Repository, + D: DbLayer, { cache: Vec>, - rule: fn(&T) -> bool, - repo: Arc, - _marker: PhantomData, + rule: Box bool>, + _marker: PhantomData<(R, D)>, } -impl, D: DbLayer> Query -{ - fn iter<'a>(&mut self, data_repository_inner: &'a R) -> Iter<'_, &'a T> { - self.cache.iter_mut().filter_map(|e| data_repository_inner.get_ref(e)) +impl, D: DbLayer> Query { + pub fn iter<'a>(&mut self, data_repository_inner: &'a R) -> impl Iterator + where + T: 'a, + { + self.cache + .iter_mut() + .filter_map(move |e| data_repository_inner.get_ref(e)) + } + + pub fn for_each_mut(&mut self, repo: &mut R, mut f: F) + where + F: FnMut(&mut T), + { + for handle in &mut self.cache { + if let Some(entity) = repo.get_mut(handle) { + f(entity); + } + } } } @@ -85,7 +101,7 @@ pub struct DataRepositoryInner> next_temporal: u32, connection: Arc>, data_layer: D, - query_manger: QueryManger + query_manger: QueryManger, } impl> Deref for DataRepository { @@ -96,6 +112,90 @@ impl> Deref for DataRepository< } } +impl> DataRepository { + pub fn query_par( + &self, + rule: Box bool + Send + Sync>, + ) -> Query, D> + where + T: Send + Sync, + { + let inner = self.inner.read(); + + let mut cache: Vec> = inner + .cache + .par_iter() + .enumerate() + .filter(|(_, entity)| rule(entity)) + .map(|(i, entity)| EntityHandle { + id: entity.id(), + real: true, + index: i as u32, + _phantom: PhantomData, + }) + .collect(); + + cache.extend(inner + .temporal + .iter() + .enumerate() + .filter(|(_, entity)| rule(entity)) + .map(|(i, entity)| EntityHandle { + id: entity.id(), + real: false, + index: i as u32, + _phantom: PhantomData, + }).collect::>()); + + Query { + cache, + rule, + _marker: PhantomData, + } + } + + pub fn query( + &self, + rule: Box bool>, + ) -> Query, D> + where + T: Send + Sync, + { + let inner = self.inner.read(); + + let mut cache: Vec> = inner + .cache + .iter() + .enumerate() + .filter(|(_, entity)| rule(entity)) + .map(|(i, entity)| EntityHandle { + id: entity.id(), + real: true, + index: i as u32, + _phantom: PhantomData, + }) + .collect(); + + cache.extend(inner + .temporal + .iter() + .enumerate() + .filter(|(_, entity)| rule(entity)) + .map(|(i, entity)| EntityHandle { + id: entity.id(), + real: false, + index: i as u32, + _phantom: PhantomData, + }).collect::>()); + + Query { + cache, + rule, + _marker: PhantomData, + } + } +} + impl> Repository for DataRepositoryInner { fn get(&self, handle: &mut EntityHandle) -> Option { let slice = if handle.real { @@ -136,36 +236,6 @@ impl> Repository for DataRepositoryIn } } - // fn get_static(&self, mut handle: EntityHandle) -> Option { - // let slice = if handle.real { - // self.cache.as_slice() - // } else { - // self.temporal.as_slice() - // }; - // let index = fast_position_of(slice, &mut handle)?; - // Some(slice[index].clone()) - // } - // - // fn get_ref_static(&self, mut handle: EntityHandle) -> Option<&T> { - // let slice = if handle.real { - // self.cache.as_slice() - // } else { - // self.temporal.as_slice() - // }; - // let index = fast_position_of(slice, &mut handle)?; - // Some(&slice[index]) - // } - // - // fn get_mut_static(&mut self, mut handle: EntityHandle) -> Option<&mut T> { - // let slice = if handle.real { - // self.cache.as_mut_slice() - // } else { - // self.temporal.as_mut_slice() - // }; - // let index = fast_position_of(slice, &mut handle)?; - // Some(&mut slice[index]) - // } - fn create(&mut self, mut new: T) -> EntityHandle { let next_temporal = self.next_temporal; self.next_temporal += 1; @@ -225,10 +295,6 @@ impl> Repository for DataRepositoryIn self.init()?; Ok(()) } - - fn query(&mut self, rule: fn(&T) -> bool) -> Query { - todo!() - } } impl + DbLayer> BatchedRepository for DataRepositoryInner