Better query code
This commit is contained in:
1 parent
89aa1abc13
commit
70aff6ed18
1 file changed
+111
-45
+111
-45
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user