Compress EntityHandle
This commit is contained in:
1 parent
d8e3a5b6db
commit
2c1163fc3b
3 files changed
+120
-111
No files matched your search
+28
-6
@@ -182,8 +182,7 @@ impl CardStatistics {
|
||||
#[derive(Copy)]
|
||||
pub struct EntityHandle<E> {
|
||||
pub(crate) id: Id,
|
||||
pub(crate) real: bool,
|
||||
pub(crate) index: u32,
|
||||
index: i32,
|
||||
pub(crate) _phantom: PhantomData<E>,
|
||||
|
||||
}
|
||||
@@ -192,17 +191,40 @@ impl<T> Clone for EntityHandle<T> {
|
||||
fn clone(&self) -> Self {
|
||||
EntityHandle{
|
||||
id: self.id,
|
||||
real: self.real,
|
||||
index: self.index,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T> EntityHandle<T> {
|
||||
pub fn new(id: Id, index: usize, real: bool) -> Self {
|
||||
Self {
|
||||
id,
|
||||
index : index as i32 | (!real as i32) << 31,
|
||||
_phantom: Default::default()
|
||||
}
|
||||
}
|
||||
pub fn index(&self) -> usize {
|
||||
(self.index << 1 >> 1) as usize
|
||||
}
|
||||
|
||||
pub fn set_index(&mut self, index: usize) {
|
||||
self.index = self.index >> 31 << 31 | index as i32;
|
||||
}
|
||||
|
||||
pub fn real(&self) -> bool {
|
||||
(self.index >> 31) == 0
|
||||
}
|
||||
|
||||
pub fn set_real(&mut self, value: bool) {
|
||||
self.index = self.index << 1 >> 1 | (!value as i32) << 31;
|
||||
}
|
||||
}
|
||||
impl<T> Eq for EntityHandle<T> {}
|
||||
|
||||
impl<T> PartialEq<Self> for EntityHandle<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.real == other.real && self.id == other.id
|
||||
self.real() == other.real() && self.id == other.id
|
||||
}
|
||||
}
|
||||
impl<T> PartialOrd<Self> for EntityHandle<T> {
|
||||
@@ -213,11 +235,11 @@ impl<T> PartialOrd<Self> for EntityHandle<T> {
|
||||
|
||||
impl<T> Ord for EntityHandle<T> {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
if self.real && !other.real {
|
||||
if self.real() && !other.real() {
|
||||
return Ordering::Less
|
||||
}
|
||||
|
||||
if !self.real && other.real{
|
||||
if !self.real() && other.real(){
|
||||
return Ordering::Greater
|
||||
}
|
||||
|
||||
|
||||
+37
-81
@@ -43,7 +43,7 @@ where
|
||||
T: EntityData,
|
||||
{
|
||||
pub(crate) fn handle_save(&self, old: EntityHandle<T>, new: &mut EntityHandle<T>, data: &T) {
|
||||
if old.real && new.real {
|
||||
if old.real() && new.real() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ where
|
||||
let mut query = self.queries[q].lock();
|
||||
let index = query.cache.binary_search(&old).unwrap();
|
||||
query.cache.remove(index);
|
||||
let real_end = query.cache.iter().rposition(|r| r.real).unwrap() + 1;
|
||||
let real_end = query.cache.iter().rposition(|r| r.real()).unwrap() + 1;
|
||||
query.cache.insert(real_end, new.clone());
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,6 @@ where
|
||||
for q in &self.queries {
|
||||
let mut query = q.lock();
|
||||
query.cache.clear();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,7 +121,10 @@ impl<T: EntityData + Clone, R: Repository<T, D>, D: DbLayer<T>> Query<T, R, D> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(&mut self, data_repository: &DataRepositoryInner<T, D>) where T : Send + Sync {
|
||||
pub fn load(&mut self, data_repository: &DataRepositoryInner<T, D>)
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
self.cache.clear();
|
||||
if self.parallel {
|
||||
self.cache = data_repository
|
||||
@@ -130,28 +132,15 @@ impl<T: EntityData + Clone, R: Repository<T, D>, D: DbLayer<T>> Query<T, R, D> {
|
||||
.par_iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entity)| (self.rule)(entity))
|
||||
.map(|(i, entity)| EntityHandle {
|
||||
id: entity.id(),
|
||||
real: true,
|
||||
index: i as u32,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, true))
|
||||
.collect();
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.cache = data_repository
|
||||
.cache
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entity)| (self.rule)(entity))
|
||||
.map(|(i, entity)| EntityHandle {
|
||||
id: entity.id(),
|
||||
real: true,
|
||||
index: i as u32,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, true))
|
||||
.collect();
|
||||
}
|
||||
|
||||
@@ -161,12 +150,7 @@ impl<T: EntityData + Clone, R: Repository<T, D>, D: DbLayer<T>> Query<T, R, D> {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entity)| (self.rule)(entity))
|
||||
.map(|(i, entity)| EntityHandle {
|
||||
id: entity.id(),
|
||||
real: false,
|
||||
index: i as u32,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, false))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
@@ -208,6 +192,7 @@ pub struct DataRepositoryInner<T: std::clone::Clone + EntityData, D: DbLayer<T>>
|
||||
connection: Arc<Mutex<Connection>>,
|
||||
data_layer: D,
|
||||
query_manger: QueryManger<T, Self, D>,
|
||||
version: u16
|
||||
}
|
||||
|
||||
impl<T: std::clone::Clone + EntityData, D: DbLayer<T>> Deref for DataRepository<T, D> {
|
||||
@@ -233,12 +218,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepository<T, D> {
|
||||
.par_iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entity)| rule(entity))
|
||||
.map(|(i, entity)| EntityHandle {
|
||||
id: entity.id(),
|
||||
real: true,
|
||||
index: i as u32,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, true))
|
||||
.collect();
|
||||
|
||||
cache.extend(
|
||||
@@ -247,12 +227,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepository<T, D> {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entity)| rule(entity))
|
||||
.map(|(i, entity)| EntityHandle {
|
||||
id: entity.id(),
|
||||
real: false,
|
||||
index: i as u32,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, false))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
@@ -264,7 +239,10 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepository<T, D> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query(&self, rule: Box<dyn Fn(&T) -> bool + Send + Sync>) -> Query<T, DataRepositoryInner<T, D>, D>
|
||||
pub fn query(
|
||||
&self,
|
||||
rule: Box<dyn Fn(&T) -> bool + Send + Sync>,
|
||||
) -> Query<T, DataRepositoryInner<T, D>, D>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
@@ -275,12 +253,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepository<T, D> {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entity)| rule(entity))
|
||||
.map(|(i, entity)| EntityHandle {
|
||||
id: entity.id(),
|
||||
real: true,
|
||||
index: i as u32,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, true))
|
||||
.collect();
|
||||
|
||||
cache.extend(
|
||||
@@ -289,12 +262,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepository<T, D> {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entity)| rule(entity))
|
||||
.map(|(i, entity)| EntityHandle {
|
||||
id: entity.id(),
|
||||
real: false,
|
||||
index: i as u32,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, false))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
@@ -309,7 +277,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepository<T, D> {
|
||||
|
||||
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 {
|
||||
let slice = if handle.real() {
|
||||
self.cache.as_slice()
|
||||
} else {
|
||||
self.temporal.as_slice()
|
||||
@@ -319,7 +287,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
}
|
||||
|
||||
fn get_ref(&self, handle: &mut EntityHandle<T>) -> Option<&T> {
|
||||
let slice = if handle.real {
|
||||
let slice = if handle.real() {
|
||||
self.cache.as_slice()
|
||||
} else {
|
||||
self.temporal.as_slice()
|
||||
@@ -329,7 +297,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, handle: &mut EntityHandle<T>) -> Option<&mut T> {
|
||||
let slice = if handle.real {
|
||||
let slice = if handle.real() {
|
||||
self.cache.as_mut_slice()
|
||||
} else {
|
||||
self.temporal.as_mut_slice()
|
||||
@@ -339,23 +307,13 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
}
|
||||
|
||||
fn handle_by_id(&self, id: Id) -> EntityHandle<T> {
|
||||
EntityHandle {
|
||||
_phantom: Default::default(),
|
||||
id,
|
||||
real: true,
|
||||
index: id.0,
|
||||
}
|
||||
EntityHandle::new(id, id.0 as usize, false)
|
||||
}
|
||||
|
||||
fn create(&mut self, mut new: T) -> EntityHandle<T> {
|
||||
let next_temporal = self.next_temporal;
|
||||
self.next_temporal += 1;
|
||||
let entity = EntityHandle {
|
||||
id: next_temporal.into(),
|
||||
real: false,
|
||||
index: self.temporal.len() as u32,
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
let entity = EntityHandle::new(next_temporal.into(), self.temporal.len(), false);
|
||||
new.set_id(entity.id);
|
||||
self.temporal.push(new);
|
||||
entity
|
||||
@@ -363,7 +321,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
|
||||
fn save(&mut self, entity: &mut EntityHandle<T>) -> MaybeError {
|
||||
let original_state = entity.clone();
|
||||
if entity.real {
|
||||
if entity.real() {
|
||||
let data = self.get_ref(entity).unwrap();
|
||||
self.data_layer
|
||||
.write_entity(data, &self.connection.lock())?;
|
||||
@@ -372,9 +330,9 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
let mut data = self.temporal.remove(index);
|
||||
self.data_layer
|
||||
.add_entity(&mut data, &self.connection.lock())?;
|
||||
entity.real = true;
|
||||
entity.set_real(true);
|
||||
entity.id = data.id();
|
||||
entity.index = self.cache.len() as u32;
|
||||
entity.set_index(self.cache.len());
|
||||
self.query_manger.handle_save(original_state, entity, &data);
|
||||
|
||||
self.cache.push(data);
|
||||
@@ -384,7 +342,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
}
|
||||
|
||||
fn delete(&mut self, mut handle: EntityHandle<T>) -> MaybeError {
|
||||
let vec = if handle.real {
|
||||
let vec = if handle.real() {
|
||||
self.data_layer
|
||||
.delete_entity(handle.id, &self.connection.lock())?;
|
||||
&mut self.cache
|
||||
@@ -404,6 +362,7 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
fn init(&mut self) -> MaybeError {
|
||||
self.data_layer
|
||||
.load_all(&mut self.cache, &self.connection.lock())?;
|
||||
self.version += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -411,7 +370,6 @@ impl<T: EntityData + Clone, D: DbLayer<T>> Repository<T, D> for DataRepositoryIn
|
||||
self.cache.clear();
|
||||
self.temporal.clear();
|
||||
self.init()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -423,7 +381,7 @@ impl<T: EntityData + Clone, D: BatchedDbLayer<T> + DbLayer<T>> BatchedRepository
|
||||
let mut cached = Vec::with_capacity(handles.len() / 2);
|
||||
handles.sort_by_key(|a| a.id);
|
||||
handles.iter_mut().for_each(|handle| {
|
||||
if handle.real {
|
||||
if handle.real() {
|
||||
cached.push(handle)
|
||||
} else {
|
||||
temp.push(handle)
|
||||
@@ -455,15 +413,13 @@ impl<T: EntityData + Clone, D: BatchedDbLayer<T> + DbLayer<T>> BatchedRepository
|
||||
let old = handle.clone();
|
||||
let h = handle;
|
||||
h.id = self.cache[start + i].id();
|
||||
h.index = (start + i) as u32;
|
||||
h.real = true;
|
||||
h.set_index(start + i);
|
||||
h.set_real(true);
|
||||
self.query_manger.handle_save(old, h, data);
|
||||
}
|
||||
|
||||
self.cache.extend(values);
|
||||
|
||||
|
||||
|
||||
for handle in cached.into_iter() {
|
||||
let h = handle;
|
||||
let idx = fast_position_of(self.cache.as_slice(), h).unwrap();
|
||||
@@ -519,7 +475,7 @@ where
|
||||
let mut cached = Vec::with_capacity(handles.len() / 2);
|
||||
handles.sort_by(|a, b| a.id.cmp(&b.id));
|
||||
handles.iter().for_each(|handle| {
|
||||
if handle.real {
|
||||
if handle.real() {
|
||||
cached.push(getter(handle))
|
||||
} else {
|
||||
temp.push(getter(handle))
|
||||
@@ -537,11 +493,11 @@ pub fn fast_position_of<E: EntityData>(
|
||||
}
|
||||
|
||||
let max_idx = storage.len() - 1;
|
||||
let upper = (handle.index as usize).min(max_idx);
|
||||
let upper = (handle.index()).min(max_idx);
|
||||
let peek = storage[upper].id();
|
||||
|
||||
if peek == handle.id {
|
||||
handle.index = upper as u32;
|
||||
handle.set_index(upper);
|
||||
return Some(upper);
|
||||
}
|
||||
|
||||
@@ -556,7 +512,7 @@ pub fn fast_position_of<E: EntityData>(
|
||||
let new_index = (upper as i64 - delta).max(0) as usize;
|
||||
|
||||
if storage[new_index].id() == handle.id {
|
||||
handle.index = new_index as u32;
|
||||
handle.set_index(new_index);
|
||||
return Some(new_index);
|
||||
}
|
||||
|
||||
@@ -569,6 +525,6 @@ pub fn fast_position_of<E: EntityData>(
|
||||
.ok()?
|
||||
+ new_index;
|
||||
|
||||
handle.index = index as u32;
|
||||
handle.set_index(index);
|
||||
Some(index)
|
||||
}
|
||||
Reference in new issue
Block a user