Skip to content

Commit

Permalink
Small fixes to use new seq logic
Browse files Browse the repository at this point in the history
  • Loading branch information
uselessgoddess committed Jul 4, 2022
1 parent 0fd44f4 commit 7756b62
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 29 deletions.
5 changes: 3 additions & 2 deletions rust/doublets/src/data/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,17 +259,18 @@ pub trait Doublets<T: LinkType> {
self.count_by(query) != zero()
}

fn find(&self, query: impl ToQuery<T>) -> Option<T> {
fn find(&self, query: impl ToQuery<T>) -> Option<Link<T>> {
let mut result = None;
self.each_by(query, |link| {
result = Some(link.index);
result = Some(link);
Flow::Break
});
result
}

fn search(&self, source: T, target: T) -> Option<T> {
self.find([self.constants().any, source, target])
.map(|link| link.index)
}

fn single(&self, query: impl ToQuery<T>) -> Option<Link<T>> {
Expand Down
98 changes: 71 additions & 27 deletions rust/doublets/src/mem/unit/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,50 @@ impl<T: LinkType, M: RawMem<LinkPart<T>>, TS: UnitTree<T>, TT: UnitTree<T>, TU:
Self::mut_from_mem(self.mem_ptr, index.as_()).expect("Data part should be in data memory")
}

unsafe fn mut_source_root(&mut self) -> *mut T {
&mut self.mut_header().root_as_source
}

unsafe fn mut_target_root(&mut self) -> *mut T {
&mut self.mut_header().root_as_target
}

unsafe fn detach_source_unchecked(&mut self, root: *mut T, index: T) {
self.sources.detach(&mut *root, index)
}

unsafe fn detach_target_unchecked(&mut self, root: *mut T, index: T) {
self.targets.detach(&mut *root, index)
}

unsafe fn attach_source_unchecked(&mut self, root: *mut T, index: T) {
self.sources.attach(&mut *root, index)
}

unsafe fn attach_target_unchecked(&mut self, root: *mut T, index: T) {
self.targets.attach(&mut *root, index)
}

unsafe fn detach_source(&mut self, index: T) {
let root = self.mut_source_root();
self.detach_source_unchecked(root, index);
}

unsafe fn detach_target(&mut self, index: T) {
let root = self.mut_target_root();
self.detach_target_unchecked(root, index);
}

unsafe fn attach_source(&mut self, index: T) {
let root = self.mut_source_root();
self.attach_source_unchecked(root, index);
}

unsafe fn attach_target(&mut self, index: T) {
let root = self.mut_target_root();
self.attach_target_unchecked(root, index);
}

fn get_total(&self) -> T {
let header = self.get_header();
header.allocated - header.free
Expand Down Expand Up @@ -483,39 +527,39 @@ impl<T: LinkType, M: RawMem<LinkPart<T>>, TS: UnitTree<T>, TT: UnitTree<T>, TU:
let old_source = source;
let old_target = target;

let constants = self.constants();
let null = constants.null;
let link = self.try_get_link(index)?;

let link = self.get_link_part(index).clone();
if link.source != null {
let temp = &mut self.mut_header().root_as_source as *mut T;
unsafe { self.sources.detach(&mut *temp, index) };
if link.source != zero() {
// SAFETY: Here index detach from sources
// by default source is zero
unsafe {
self.detach_source(index);
}
}

let link = self.get_link_part(index).clone();
if link.target != null {
let temp = &mut self.mut_header().root_as_target as *mut T;
unsafe { self.targets.detach(&mut *temp, index) };
if link.target != zero() {
// SAFETY: Here index detach from targets
// by default target is zero
unsafe {
self.detach_target(index);
}
}

let link = self.mut_link_part(index);
if link.source != source {
link.source = source;
}
if link.target != target {
link.target = target;
}
let place = self.mut_link_part(index);
place.source = source;
place.target = target;
let place = place.clone();

let link = self.mut_link_part(index).clone();
if link.source != null {
let temp = &mut self.mut_header().root_as_source as *mut T;
unsafe { self.sources.attach(&mut *temp, index) };
if place.source != zero() {
// SAFETY: Here index attach to sources
unsafe {
self.attach_source(index);
}
}

let link = self.mut_link_part(index).clone();
if link.target != null {
let temp = &mut self.mut_header().root_as_target as *mut T;
unsafe { self.targets.attach(&mut *temp, index) };
if place.target != zero() {
// SAFETY: Here index attach to targets
unsafe {
self.attach_target(index);
}
}

Ok(handler(
Expand Down
77 changes: 77 additions & 0 deletions rust/doublets/tests/seq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use doublets::{
data::{
Flow::{Break, Continue},
ToQuery,
},
mem::GlobalMem,
num::LinkType,
unit, Doublets, Error as LinksError, Link,
};
use num_traits::zero;
use std::error::Error;

fn write_seq<T: LinkType>(store: &mut impl Doublets<T>, seq: &[T]) -> Result<T, LinksError<T>> {
let mut aliases = vec![store.create()?];

for id in seq {
let link = store.create()?;
aliases.push(store.update(link, link, *id)?)
}

for (i, cur) in aliases.iter().enumerate() {
if let Some(next) = aliases.get(i + 1) {
store.create_link(*cur, *next)?;
}
}
Ok(*aliases.first().unwrap_or(&zero()))
}

fn custom_single<T: LinkType>(store: &impl Doublets<T>, query: impl ToQuery<T>) -> Option<Link<T>> {
// todo:
// store.each_iter(query).filter(Link::is_partial);

let mut single = None;
store.each_by(query, |link| {
if single.is_none() && link.index != link.source {
single = Some(link);
Continue
} else if link.index != link.source {
single = None;
Break
} else {
Continue
}
});
single
}

fn read_seq<T: LinkType>(store: &impl Doublets<T>, root: T) -> Result<Vec<T>, LinksError<T>> {
let any = store.constants().any;
let mut seq = vec![];
let mut cur = root;
while let Some(link) = custom_single(store, [any, cur, any]) {
cur = link.target;
let alias = store.try_get_link(link.target)?;
seq.push(alias.target);
}
Ok(seq)
}

#[test]
fn seq() -> Result<(), Box<dyn Error>> {
let mut store = unit::Store::<usize, _>::new(GlobalMem::new())?;

// Simulate non-empty storage
store.create_point()?;
store.create_point()?;
store.create_point()?;
store.create_point()?;
store.create_point()?;

let root = write_seq(&mut store, &[1, 2, 3, 4])?;

let seq = read_seq(&store, root)?;
println!("{seq:?}");

Ok(())
}

0 comments on commit 7756b62

Please sign in to comment.