first work on modifing lodstore

This commit is contained in:
Marcel Märtens 2019-10-24 14:56:00 +02:00
parent 73e130c097
commit 7a1d04f320
5 changed files with 194 additions and 18 deletions

View File

@ -52,12 +52,23 @@ pub struct HashIter<'a, C: DetailStore> {
pub( super ) wanted: LodPos,
pub( super ) layer_lod: LodPos, //LodPos aligned to layer::LEVEL
}
pub struct HashIterMut<'a, C: DetailStore> {
pub( super ) layer: &'a mut C,
pub( super ) wanted: LodPos,
pub( super ) layer_lod: LodPos, //LodPos aligned to layer::LEVEL
}
pub struct VecIter<'a, C: DetailStore> {
pub( super ) layer: &'a C,
pub( super ) wanted: LodPos,
pub( super ) layer_lod: LodPos, //LodPos aligned to layer::LEVEL
pub( super ) layer_key: usize,
}
pub struct VecIterMut<'a, C: DetailStore> {
pub( super ) layer: &'a mut C,
pub( super ) wanted: LodPos,
pub( super ) layer_lod: LodPos, //LodPos aligned to layer::LEVEL
pub( super ) layer_key: usize,
}
impl<C: DetailStore, T, I: ToOptionUsize, const L: u8> IndexStore for VecNestLayer<C, T, I, { L }> {
type INDEX = I;
@ -136,6 +147,7 @@ pub mod tests {
use crate::lodstore::data::*;
use test::Bencher;
use std::{u16, u32};
use crate::lodstore::traversable::Traversable;
#[rustfmt::skip]
pub type ExampleData =
@ -240,6 +252,36 @@ pub mod tests {
assert_eq!(*x.trav(LodPos::xyz(0, 2, 0)).get().get().get().mat(), 0_i8);
}
#[test]
fn mut_simple_elements() {
let mut x = gen_simple_example();
assert_eq!(*x.trav(LodPos::xyz(0, 0, 0)).get().get().get().mat(), 7_i8);
assert_eq!(*x.trav(LodPos::xyz(0, 0, 1)).get().get().get().mat(), 6_i8);
x.trav_mut(LodPos::xyz(0, 0, 0)).get().get().get().store(123);
assert_eq!(*x.trav(LodPos::xyz(0, 0, 0)).get().get().get().mat(), 123_i8);
}
#[test]
fn mut2_simple_elements() {
let mut x = gen_simple_example();
assert_eq!(*x.trav(LodPos::xyz(0, 0, 0)).get().get().get().mat(), 7_i8);
let c = *x.trav(LodPos::xyz(0, 0, 0)).get().get().get().mat();
x.trav_mut(LodPos::xyz(0, 0, 0)).get().get().get().store(111 + c);
assert_eq!(*x.trav(LodPos::xyz(0, 0, 0)).get().get().get().mat(), 118_i8);
}
/* allow this once we guarante get to be consistent even on Hash Lookups!
TODO: shuldnt this already ne the case ?
#[test]
fn mut3_simple_elements() {
let mut x = gen_simple_example();
let a = x.trav_mut(LodPos::xyz(0, 0, 0)).get().get().get();
assert_eq!(*a.mat(), 7_i8);
a.store(123);
assert_eq!(*a.mat(), 123_i8);
assert_eq!(*x.trav(LodPos::xyz(0, 0, 0)).get().get().get().mat(), 123_i8);
}*/
#[bench]
fn bench_access_trav(b: &mut Bencher) {
let x = gen_simple_example();

View File

@ -1,13 +1,15 @@
use super::index::ToOptionUsize;
use super::lodpos::LodPos;
use super::data::{HashNestLayer, DetailStore, HashIter};
use super::data::{HashNestLayer, DetailStore, HashIter, HashIterMut};
use super::delta::{VecNestDelta, Delta, VecDataIter, DataWriterIter, DeltaWriter};
use super::traversable::Traversable;
use std::marker::PhantomData;
pub trait EntryLayer<'a> {
type TRAV: Traversable;
type TRAV_MUT: Traversable;
fn trav(&'a self, pos: LodPos) -> Self::TRAV;
fn trav_mut(&'a mut self, pos: LodPos) -> Self::TRAV_MUT;
}
///////////////// data types
@ -16,10 +18,20 @@ impl<'a, C: 'a + DetailStore, T: 'a, I: 'a + ToOptionUsize, const L: u8> EntryLa
for HashNestLayer<C, T, I, { L }>
{
type TRAV = HashIter<'a, HashNestLayer<C, T, I, { L }>>;
type TRAV_MUT = HashIterMut<'a, HashNestLayer<C, T, I, { L }>>;
//ERROR make the HashIter C: remove the &'a from HashIter coding and implement it here
fn trav(&'a self, pos: LodPos) -> Self::TRAV {
HashIter {
layer: &self,
layer: self,
wanted: pos,
layer_lod: pos.align_to_level({ L }),
}
}
fn trav_mut(&'a mut self, pos: LodPos) -> Self::TRAV_MUT {
HashIterMut {
layer: self,
wanted: pos,
layer_lod: pos.align_to_level({ L }),
}
@ -30,9 +42,13 @@ for HashNestLayer<C, T, I, { L }>
impl<'a, D: 'a + Delta, T: 'a, const L: u8> EntryLayer<'a> for VecNestDelta<D, T, { L }> {
type TRAV = VecDataIter<'a, VecNestDelta<D, T, { L }>>;
type TRAV_MUT = VecDataIter<'a, VecNestDelta<D, T, { L }>>;
fn trav(&'a self, _pos: LodPos) -> Self::TRAV {
VecDataIter { layer: &self }
VecDataIter { layer: self }
}
fn trav_mut(&'a mut self, _pos: LodPos) -> Self::TRAV_MUT {
VecDataIter { layer: self }
}
}
@ -43,6 +59,8 @@ for DeltaWriter<'a, C, D>
<<D as EntryLayer<'a>>::TRAV as Traversable>::TRAV_CHILD: Traversable,
{
type TRAV = DataWriterIter<'a, D::TRAV, C::TRAV>;
type TRAV_MUT = DataWriterIter<'a, D::TRAV, C::TRAV>;
fn trav(&'a self, pos: LodPos) -> DataWriterIter<D::TRAV, C::TRAV> {
DataWriterIter {
delta_iter: self.delta.trav(pos),
@ -50,4 +68,12 @@ for DeltaWriter<'a, C, D>
_a: PhantomData::<&'a ()>::default(),
}
}
fn trav_mut(&'a mut self, pos: LodPos) -> DataWriterIter<D::TRAV, C::TRAV> {
DataWriterIter {
delta_iter: self.delta.trav(pos),
data_iter: self.data.trav(pos),
_a: PhantomData::<&'a ()>::default(),
}
}
}

View File

@ -12,6 +12,7 @@ pub trait Layer {
pub trait ParentLayer: Layer {
type CHILD: Layer;
fn child(&self) -> &Self::CHILD;
fn child_mut(&mut self) -> &mut Self::CHILD;
const CHILDS_PER_OWN_TOTAL: usize = two_pow_u(Self::LOG2_OF_CHILDS_PER_OWN_TOTAL) as usize;
const LOG2_OF_CHILDS_PER_OWN_TOTAL: u8 = 3 * ({ Self::LEVEL } - Self::CHILD::LEVEL);
const CHILDS_PER_OWN: Vec3<u32> = Vec3 {
@ -47,6 +48,9 @@ impl<C: DetailStore, T, I: ToOptionUsize, const L: u8> ParentLayer
fn child(&self) -> &Self::CHILD {
&self.child
}
fn child_mut(&mut self) -> &mut Self::CHILD {
&mut self.child
}
}
impl<C: DetailStore, T, I: ToOptionUsize, const L: u8> ParentLayer
for HashNestLayer<C, T, I, { L }>
@ -55,6 +59,9 @@ impl<C: DetailStore, T, I: ToOptionUsize, const L: u8> ParentLayer
fn child(&self) -> &Self::CHILD {
&self.child
}
fn child_mut(&mut self) -> &mut Self::CHILD {
&mut self.child
}
}
///////////////// delta types
@ -73,4 +80,7 @@ impl<D: Delta, T, const L: u8> ParentLayer for VecNestDelta<D, T, { L }> {
fn child(&self) -> &Self::CHILD {
&self.child
}
fn child_mut(&mut self) -> &mut Self::CHILD {
&mut self.child
}
}

View File

@ -1,36 +1,80 @@
use super::lodpos::{LodPos};
use super::data::{DetailStore, HashIter, VecIter};
use super::data::{DetailStore, HashIter, VecIter, HashIterMut, VecIterMut};
use super::delta::DataWriterIter;
pub trait Materializeable {
/*
TODO: how do we want traversable and meterializeable to work?
I e.g. should
let value = lodtree,trav().get().get().mat();
be possibe? should it create a read lock on lodtree?
ideally:
let mut v = lodtree.trav().get().get().get().mutmat()
has a read lock on lottree and a writelock on that specific field, but that wont stop us from taking another get.get.get on lodtree on the same item. mhhh arrgg, this is dificult to do statically. so better not do it ?
VLT multiple types ? for efficient returns?
*/
pub trait Materializeable<'a> {
type MAT_CHILD;
fn mat(self) -> Self::MAT_CHILD;
fn mat(self) -> &'a Self::MAT_CHILD;
fn store(self, mat: Self::MAT_CHILD);
}
///////////////// data types
impl<'a, L: DetailStore<KEY = LodPos>> Materializeable for HashIter<'a, L> {
type MAT_CHILD = &'a L::DETAIL;
impl<'a, L: DetailStore<KEY = LodPos>> Materializeable<'a> for HashIter<'a, L> {
type MAT_CHILD = L::DETAIL;
fn mat(self) -> &'a L::DETAIL {
DetailStore::load(self.layer, self.layer_lod)
}
fn store(self, mat: L::DETAIL) {
//DetailStore::save(self.layer, self.layer_key, mat)
}
}
impl<'a, L: DetailStore<KEY = LodPos>> Materializeable<'a> for HashIterMut<'a, L> {
type MAT_CHILD = L::DETAIL;
fn mat(self) -> &'a L::DETAIL {
DetailStore::load(self.layer, self.layer_lod)
}
fn store(self, mat: L::DETAIL) {
//DetailStore::save(self.layer, self.layer_key, mat)
}
}
impl<'a, L: DetailStore<KEY = usize>> Materializeable for VecIter<'a, L> {
type MAT_CHILD = &'a L::DETAIL;
impl<'a, L: DetailStore<KEY = usize>> Materializeable<'a> for VecIter<'a, L> {
type MAT_CHILD = L::DETAIL;
fn mat(self) -> &'a L::DETAIL {
DetailStore::load(self.layer, self.layer_key)
fn mat(self) -> &'a L::DETAIL { DetailStore::load(self.layer, self.layer_key) }
fn store(self, mat: L::DETAIL) {
//DetailStore::save(self.layer, self.layer_key, mat)
}
}
impl<'a, L: DetailStore<KEY = usize>> Materializeable<'a> for VecIterMut<'a, L> {
type MAT_CHILD = L::DETAIL;
fn mat(self) -> &'a L::DETAIL { DetailStore::load(self.layer, self.layer_key) }
fn store(self, mat: L::DETAIL) {
DetailStore::save(self.layer, self.layer_key, mat)
}
}
///////////////// delta types
impl<'a, DT, CT: Materializeable> Materializeable for DataWriterIter<'a, DT, CT> {
type MAT_CHILD = CT::MAT_CHILD;
impl<'a, DT, CT: Materializeable<'a>> Materializeable<'a> for DataWriterIter<'a, DT, CT> {
type MAT_CHILD = CT::MAT_CHILD;
fn mat(self) -> CT::MAT_CHILD {
self.data_iter.mat()
}
fn mat(self) -> &'a CT::MAT_CHILD {
self.data_iter.mat()
}
fn store(self, mat: CT::MAT_CHILD) {
//self.data_iter.store(mat)
}
}

View File

@ -1,6 +1,6 @@
use super::index::ToOptionUsize;
use super::lodpos::{multily_with_2_pow_n, relative_to_1d, LodPos};
use super::data::{DetailStore, IndexStore, HashIter, VecIter};
use super::data::{DetailStore, IndexStore, HashIter, VecIter, HashIterMut, VecIterMut};
use super::delta::{Delta, VecDataIter, DataWriterIter};
#[allow(unused_imports)] //not unsued, cargo is just to stupud to detect that
use super::layer::{Layer, ParentLayer};
@ -40,6 +40,33 @@ impl<'a, L: DetailStore<KEY = LodPos> + IndexStore> Traversable for HashIter<'a,
}
}
impl<'a, L: DetailStore<KEY = LodPos> + IndexStore> Traversable for HashIterMut<'a, L>
where
L::CHILD: DetailStore,
{
type TRAV_CHILD = VecIterMut<'a, L::CHILD>;
fn get(self) -> VecIterMut<'a, L::CHILD> {
let child_lod = self.wanted.align_to_level(L::CHILD::LEVEL);
let pos_offset = relative_to_1d(
child_lod,
self.layer_lod,
L::CHILD::LEVEL,
L::CHILDS_PER_OWN,
);
let layer_key = (multily_with_2_pow_n(
IndexStore::load(self.layer, self.layer_lod).into_usize(),
L::LOG2_OF_CHILDS_PER_OWN_TOTAL,
)) + pos_offset;
VecIterMut {
layer: self.layer.child_mut(),
wanted: self.wanted,
layer_key,
layer_lod: child_lod,
}
}
}
impl<'a, L: DetailStore<KEY = usize> + IndexStore> Traversable for VecIter<'a, L>
where
L::CHILD: DetailStore,
@ -67,6 +94,33 @@ impl<'a, L: DetailStore<KEY = usize> + IndexStore> Traversable for VecIter<'a, L
}
}
impl<'a, L: DetailStore<KEY = usize> + IndexStore> Traversable for VecIterMut<'a, L>
where
L::CHILD: DetailStore,
{
type TRAV_CHILD = VecIterMut<'a, L::CHILD>;
fn get(self) -> VecIterMut<'a, L::CHILD> {
let child_lod = self.wanted.align_to_level(L::CHILD::LEVEL);
let pos_offset = relative_to_1d(
child_lod,
self.layer_lod,
L::CHILD::LEVEL,
L::CHILDS_PER_OWN,
);
let layer_key = (multily_with_2_pow_n(
IndexStore::load(self.layer, self.layer_key).into_usize(),
L::LOG2_OF_CHILDS_PER_OWN_TOTAL,
)) + pos_offset;
VecIterMut {
layer: self.layer.child_mut(),
wanted: self.wanted,
layer_key,
layer_lod: child_lod,
}
}
}
///////////////// delta types
impl<'a, D: Delta + ParentLayer> Traversable for VecDataIter<'a, D>