Skip to content
Snippets Groups Projects
Commit 4b15a381 authored by Cookiebowser's avatar Cookiebowser
Browse files

btypes lazy iter somewhat working

parent 8f4fbfa6
Branches
No related tags found
1 merge request!28Rust support
......@@ -6,7 +6,7 @@ use crate::bstring::BString;
use crate::bobject::BObject;
use crate::btuple::BTuple;
use crate::orderedhashset::OrderedHashSet as OrdSet;
use crate::lazy_ops::set_ops::setops::{SetOp, SetOpTraits};
use crate::lazy_ops::set_ops::setops::{IterWrapper, SetOp, SetOpTraits};
use crate::lazy_ops::set_ops::union::Union;
use std::any::TypeId;
......@@ -32,7 +32,7 @@ pub trait SetLike: BObject {
fn intersect(&self, other: &Self) -> Self;
}
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
#[derive(Default, Debug, Eq, PartialOrd, Ord, Clone)]
pub struct BSet<T: BObject> {
set: OrdSet<T>,
transformation: Option<Box<dyn SetOp<Item = T>>>,
......@@ -78,13 +78,13 @@ impl<T: 'static + BObject> SetOp for BSet<T> {
}
}
impl<T: 'static + BObject> SetOpTraits for BSet<T> {
impl<T: BObject> SetOpTraits for BSet<T> {
type Item = T;
fn iter_lazy(&self, _lhs: &BSet<Self::Item>) -> Iter<'_, T> {
fn iter_lazy<'a>(&'a self, _lhs: &BSet<Self::Item>) -> IterWrapper<T> {
match &self.transformation {
Some(op) => op.iter_lazy(self),
None => self.iter_directly(),
None => IterWrapper::single(self.iter_directly()),
}
}
......@@ -103,8 +103,9 @@ impl<T: 'static + BObject> SetOpTraits for BSet<T> {
}
fn size_lazy(&self, _lhs: &BSet<Self::Item>) -> usize {
match &self.transformation {
Some(op) => op.size_lazy(self),
let self_clone = self.clone();
match self.transformation {
Some(ref op) => op.size_lazy(&self_clone),
None => self.size_directly(),
}
}
......@@ -114,6 +115,16 @@ impl<I: BObject> Hash for BSet<I> {
fn hash<H: Hasher>(self: &BSet<I>, state: &mut H) { self.set.hash(state); }
}
impl<I: BObject> PartialEq for BSet<I> {
fn eq(&self, other: &BSet<I>) -> bool {
if self.size() != other.size() { return false; }
for i in self.iter() {
if !other.contains(i) { return false; }
}
return true;
}
}
impl<T: 'static + BObject> BObject for BSet<T> {}
impl<T: 'static + BObject> TBSet for BSet<T> {
......@@ -127,7 +138,7 @@ impl<T: 'static + BObject> fmt::Display for BSet<T> {
return write!(f, "{}", <BSet<T> as SetOp>::to_string(self, Option::None));
}
}
/*
impl<'a, T: 'static + BObject> IntoIterator for &'a BSet<T>
where
T: 'a + Ord,
......@@ -139,10 +150,20 @@ where
self.iter()
}
}
*/
//TODO: check if replacing cache with mutex works and does not impact permormance too much
unsafe impl<T: BObject> Sync for BSet<T> {}
impl<T: BObject> BSet<T> {
pub fn size(&self) -> usize { self.size_lazy(self) }
pub fn iter(&self) -> impl Iterator<Item = &T> + '_ { self.iter_lazy(self) }
pub fn iter_directly(&self) -> Iter<T> { self.set.iter() }
pub fn contains(&self, o: &T) -> bool { self.contains_lazy(self, o) }
pub fn contains_directly(&self, o: &T) -> bool { return self.set.contains(o); }
pub fn size_directly(&self) -> usize { return self.set.len(); }
pub fn is_empty_directly(&self) -> bool { return self.set.is_empty() }
}
impl<T: 'static + BObject> BSet<T> {
pub fn new(mut args: Vec<T>) -> BSet<T> {
......@@ -160,22 +181,13 @@ impl<T: 'static + BObject> BSet<T> {
return BSet { set: set, transformation: Option::None };
}
pub fn iter(&self) -> Iter<'_, T> { self.iter_lazy(self) }
pub fn iter_directly(&self) -> Iter<'_, T> { self.set.iter() }
pub fn size(&self) -> usize { self.size_lazy(self) }
pub fn size_directly(&self) -> usize {
return self.set.len();
pub fn get_direct_set(&self) -> Self {
return BSet { set: self.set.clone(), transformation: Option::None }
}
pub fn isEmpty(&self) -> bool { return self.is_empty_lazy(self); }
pub fn is_empty_directly(&self) -> bool { return self.set.is_empty() }
pub fn iter_complete<'a>(&'a self) -> IterWrapper<T> { self.iter_lazy(self) }
pub fn contains(&self, o: &T) -> bool { self.contains_lazy(self, o) }
pub fn contains_directly(&self, o: &T) -> bool {
return self.set.contains(o);
}
pub fn isEmpty(&self) -> bool { return self.is_empty_lazy(self); }
pub fn intersect(&self, set: &BSet<T>) -> BSet<T> {
return BSet{ set: self.set.clone().intersection(set.set.clone()), transformation: Option::None };
......@@ -202,11 +214,11 @@ impl<T: 'static + BObject> BSet<T> {
return result;
}
pub fn card(&self) -> BInteger {
pub fn card(&mut self) -> BInteger {
return self._size();
}
pub fn _size(&self) -> BInteger {
pub fn _size(&mut self) -> BInteger {
return BInteger::new(self.size().try_into().unwrap());
}
......@@ -226,11 +238,11 @@ impl<T: 'static + BObject> BSet<T> {
return self.subset(set).not();
}
pub fn strictSubset(&self, set: &BSet<T>) -> BBoolean {
pub fn strictSubset(&mut self, set: &mut BSet<T>) -> BBoolean {
return BBoolean::new(self.size() < set.size() && self.subset(set));
}
pub fn strictNotSubset(&self, set: &BSet<T>) -> BBoolean {
pub fn strictNotSubset(&mut self, set: &mut BSet<T>) -> BBoolean {
return BBoolean::new(self.size() >= set.size() || !self.subset(set));
}
......@@ -278,11 +290,11 @@ impl<T: 'static + BObject> BSet<T> {
}
pub fn equal(&self, other: &BSet<T>) -> BBoolean {
return BBoolean::new(self.set.eq(&other.set));
return BBoolean::new(self.eq(other));
}
pub fn unequal(&self, other: &BSet<T>) -> BBoolean {
return BBoolean::new(!self.set.eq(&other.set));
return BBoolean::new(!self.eq(other));
}
pub fn subsetOfInteger(&self) -> BBoolean {
......
use std::hash::{Hasher};
use std::cmp::Ordering;
use std::fmt::{Debug};
use std::iter::Chain;
use im::ordset::Iter;
use crate::bobject::BObject;
......@@ -92,31 +92,64 @@ pub trait SetOp: SetOpTraits + Debug {
pub trait SetOpTraits {
type Item: BObject;
fn iter_lazy(&self, lhs: &BSet<Self::Item>) -> Box<dyn Iterator<Item=Self::Item> + '_>;
fn iter_lazy<'a>(&'a self, lhs: &'a BSet<Self::Item>) -> IterWrapper<'a, Self::Item>;
fn contains_lazy(&self, lhs: &BSet<Self::Item>, o:&Self::Item) -> bool;
fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool;
fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize;
//fn hash_val(&self) -> u64;
}
/*
struct IterWrapper<T: BObject> {
chain_iter: Option<Chain<Iter<T>, Iter<T>>>,
pub enum IterWrapperE<'a, T: BObject> {
Empty,
Single(Iter<'a, T>),
Chain(Box<IterWrapper<'a, T>>, Box<IterWrapper<'a, T>>),
Filtered(Box<IterWrapper<'a, T>>, BSet<T>),
}
impl<T: BObject> IterWrapper<T> {
pub fn from_chain_iter(iter: Chain<Iter<T>, Iter<T>>) {
IterWrapper { chain_iter: Option::Some(iter) }
pub struct IterWrapper<'a, T: BObject> {
iter: IterWrapperE<'a, T>,
}
impl<'a, T: BObject> IterWrapper<'a, T> {
pub fn empty() -> IterWrapper<'a, T> { IterWrapper { iter: IterWrapperE::Empty }}
pub fn single(iter: Iter<'a, T>) -> IterWrapper<'a, T> { IterWrapper { iter: IterWrapperE::Single(iter)} }
pub fn chain(iter_a: IterWrapper<'a, T>, iter_b: IterWrapper<'a, T>) -> IterWrapper<'a, T> {
IterWrapper { iter: IterWrapperE::Chain(Box::new(iter_a),
Box::new(iter_b))}
}
*/
/*
impl<T> SetOpTraits for T
where T: 'static + SetOp + Clone,
{
fn clone_box<S: BObject>(&self) -> Box<dyn SetOp<Item = S>> {
Box::new(self.clone())
pub fn filtered(iter: IterWrapper<'a, T>, filter: BSet<T>) -> IterWrapper<'a, T> {
IterWrapper { iter: IterWrapperE::Filtered(Box::new(iter), filter)}
}
}
*/
impl<'a, T: BObject> Iterator for IterWrapper<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
match self.iter {
IterWrapperE::Empty => Option::None,
IterWrapperE::Single(ref mut s) => s.next(),
IterWrapperE::Chain(ref mut a, ref mut b) => {
let option_a = a.next();
match option_a {
Some(result) => Some(result),
None => b.next(),
}
},
IterWrapperE::Filtered(ref mut i, ref filter) => {
let mut option = i.next();
while option.is_some() {
let val = option.unwrap();
if !filter.contains(val) { return Option::Some(val); }
option = i.next();
}
return option;
}
}
}
}
impl<T: BObject> Clone for Box<dyn SetOp<Item = T>> {
fn clone(&self) -> Self {
self.clone_box()
......
use std::cell::RefCell;
use std::convert::TryInto;
use crate::bobject::BObject;
use crate::bset::BSet;
use crate::lazy_ops::set_ops::setops::{SetOp, SetOpTraits};
use crate::lazy_ops::set_ops::setops::{IterWrapper, SetOp, SetOpTraits};
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::iter::Chain;
use std::ops::Not;
use im::ordset::Iter;
#[derive(Clone)]
pub struct Union<T: BObject> {
rhs: RefCell<BSet<T>>,
rhs_is_reduced: RefCell<bool>,
rhs: BSet<T>,
rhs_is_reduced: bool,
}
impl<T: BObject> Union<T> {
......@@ -22,49 +19,63 @@ impl<T: BObject> Union<T> {
impl<T: 'static + BObject> Debug for Union<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Union({})", self.rhs.borrow())
write!(f, "Union({})", self.rhs)
}
}
impl<T: BObject> Union<T> {
pub fn new(rhs: BSet<T>) -> Union<T> {
Union {rhs: RefCell::new(rhs), rhs_is_reduced: RefCell::new(false)}
Union {rhs: rhs, rhs_is_reduced: false}
}
}
impl<T: 'static + BObject> Union<T> {
fn check_reduced(&mut self, lhs: &BSet<T>) {
if !self.rhs_is_reduced {
let new_rhs = self.rhs.difference(&lhs.get_direct_set());
self.rhs = new_rhs;
self.rhs_is_reduced = true;
}
}
}
impl<T: 'static + BObject> SetOpTraits for Union<T>{
type Item = T;
fn iter_lazy(&self, lhs: &BSet<Self::Item>) -> Chain<Iter<T>, Iter<T>> {
return lhs.iter_directly().chain(self.rhs.borrow().iter());
fn iter_lazy<'a>(&'a self, lhs: &'a BSet<Self::Item>) -> IterWrapper<'a, T> {
//self.check_reduced(lhs); <-- would need me to make this function take &mut self, which would propagate to BSet::iter, which would break everything...
let iter_a = IterWrapper::single(lhs.iter_directly());
let iter_b = self.rhs.iter_complete();
if self.rhs_is_reduced {
return IterWrapper::chain(iter_a, iter_b);
}
return IterWrapper::chain(iter_a, IterWrapper::filtered(iter_b, lhs.get_direct_set()));
}
fn contains_lazy(&self, lhs: &BSet<Self::Item>, o: &Self::Item) -> bool {
lhs.contains_directly(o) || self.rhs.borrow().contains_directly(o)
lhs.contains_directly(o) || self.rhs.contains(o)
}
fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool {
lhs.is_empty_directly() && self.rhs.borrow().is_empty_directly()
lhs.is_empty_directly() && self.rhs.isEmpty()
}
fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize {
if (*self.rhs_is_reduced.borrow()).not() {
let new_rhs = self.rhs.borrow().difference(lhs);
self.rhs.replace(new_rhs);
self.rhs_is_reduced.replace(true);
if self.rhs_is_reduced {
return lhs.size_directly() + self.rhs.size();
}
return lhs.size_directly() + self.rhs.borrow().size_directly();
return lhs.size_directly() + self.rhs.difference(&lhs.get_direct_set()).size();
}
}
impl<T: 'static + BObject> SetOp for Union<T> {
fn compute(&self, lhs: &BSet<T>) -> BSet<T> {
lhs.real_union(&self.rhs.borrow())
lhs.real_union(&self.rhs)
}
fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> {
Box::new(Union{rhs: RefCell::new(self.rhs.borrow().clone()),
rhs_is_reduced: RefCell::new(*self.rhs_is_reduced.borrow())})
Box::new(Union{rhs: self.rhs.clone(),
rhs_is_reduced: self.rhs_is_reduced})
}
fn get_op_name(&self) -> &str {
......@@ -72,6 +83,6 @@ impl<T: 'static + BObject> SetOp for Union<T> {
}
fn get_rhs(&self) -> Option<Box<dyn SetOp<Item=Self::Item>>> {
return Option::Some(self.rhs.borrow().clone_box());
return Option::Some(self.rhs.clone_box());
}
}
\ No newline at end of file
......@@ -105,7 +105,7 @@ impl<I: BObject> OrderedHashSet<I> {
a.into_iter().fold(Self::new(), Self::union)
}
pub fn iter(&self) -> Iter<'_, I> { self.set.iter() }
pub fn iter<'a>(&'a self) -> Iter<'a, I> { self.set.iter() }
pub fn len(&self) -> usize { self.set.len() }
pub fn is_empty(&self) -> bool { self.set.is_empty() }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment