Better query code

This commit is contained in:
micialware committed 2026-08-27 14:51:35 +03:00
1 parent 89aa1abc13
commit 70aff6ed18
1 file changed
+111 -45
+111 -45
View File
@@ -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<T, D>
@@ -22,7 +24,6 @@ where
fn delete(&mut self, handle: EntityHandle<T>) -> MaybeError;
fn init(&mut self) -> MaybeError;
fn reload(&mut self) -> MaybeError;
fn query(&mut self, rule: fn(&T) -> bool) -> Query<T, Self, D> where Self: Sized;
}
struct QueryManger<T, R, D>
@@ -35,18 +36,33 @@ where
pub struct Query<T, R, D>
where
R: Repository<T, D>, D: DbLayer<T>
R: Repository<T, D>,
D: DbLayer<T>,
{
cache: Vec<EntityHandle<T>>,
rule: fn(&T) -> bool,
repo: Arc<R>,
_marker: PhantomData<D>,
rule: Box<dyn Fn(&T) -> bool>,
_marker: PhantomData<(R, D)>,
}
impl<T, R: Repository<T, D>, D: DbLayer<T>> Query<T, R, D>
{
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<T, R: Repository<T, D>, D: DbLayer<T>> Query<T, R, D> {
pub fn iter<'a>(&mut self, data_repository_inner: &'a R) -> impl Iterator<Item = &'a T>
where
T: 'a,
{
self.cache
.iter_mut()
.filter_map(move |e| data_repository_inner.get_ref(e))
}
pub fn for_each_mut<F>(&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<T: std::clone::Clone + EntityData, D: DbLayer<T>>
next_temporal: u32,
connection: Arc<Mutex<Connection>>,
data_layer: D,
query_manger: QueryManger<T, Self, D>
query_manger: QueryManger<T, Self, D>,
}
impl<T: std::clone::Clone + EntityData, D: DbLayer<T>> Deref for DataRepository<T, D> {
@@ -96,6 +112,90 @@ impl<T: std::clone::Clone + EntityData, D: DbLayer<T>> Deref for DataRepository<
}
}
impl<T: EntityData + Clone, D: DbLayer<T>> DataRepository<T, D> {
pub fn query_par(
&self,
rule: Box<dyn Fn(&T) -> bool + Send + Sync>,
) -> Query<T, DataRepositoryInner<T, D>, D>
where
T: Send + Sync,
{
let inner = self.inner.read();
let mut cache: Vec<EntityHandle<T>> = 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::<Vec<_>>());
Query {
cache,
rule,
_marker: PhantomData,
}
}
pub fn query(
&self,
rule: Box<dyn Fn(&T) -> bool>,
) -> Query<T, DataRepositoryInner<T, D>, D>
where
T: Send + Sync,
{
let inner = self.inner.read();
let mut cache: Vec<EntityHandle<T>> = 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::<Vec<_>>());
Query {
cache,
rule,
_marker: PhantomData,
}
}
}
impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryInner<T, D> {
fn get(&self, handle: &mut EntityHandle<T>) -> Option<T> {
let slice = if handle.real {
@@ -136,36 +236,6 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
}
}
// fn get_static(&self, mut handle: EntityHandle<T>) -> 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].clone())
// }
//
// fn get_ref_static(&self, mut handle: EntityHandle<T>) -> 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<T>) -> 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<T> {
let next_temporal = self.next_temporal;
self.next_temporal += 1;
@@ -225,10 +295,6 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
self.init()?;
Ok(())
}
fn query(&mut self, rule: fn(&T) -> bool) -> Query<T, Self, D> {
todo!()
}
}
impl<T: EntityData + Clone, D: BatchedDbLayer<T> + DbLayer<T>> BatchedRepository<T, D>
for DataRepositoryInner<T, D>