use std::{cmp,env,mem,ops,iter,marker,collections,hash,slice,ptr};
use hadean::{Sender,Receiver,Connection,Process,ChannelType,Channel,pid,spawn,ProcessSendable};
use list::{Leaf,LeafIndex};
use hashmap;
pub struct Vec<'a,T> where T: ProcessSendable {
list: OwnedOrBorrowed<'a,Leaf<u8>>,
start: LeafIndex,
end: LeafIndex,
phantom: marker::PhantomData<T>
}
enum OwnedOrBorrowed<'a,T> where T: 'a {
Owned(Box<T>),
Borrowed(&'a mut T)
}
impl<'a,T> OwnedOrBorrowed<'a,T> {
fn list(&self) -> &T {
match self {
&OwnedOrBorrowed::Owned(ref list) => &*list,
&OwnedOrBorrowed::Borrowed(ref list) => *list
}
}
fn list_mut(&mut self) -> &mut T {
match self {
&mut OwnedOrBorrowed::Owned(ref mut list) => &mut *list,
&mut OwnedOrBorrowed::Borrowed(ref mut list) => *list
}
}
}
impl<'a,T> Vec<'a,T> where T: ProcessSendable {
pub fn new() -> Vec<'a,T> {
let mut leaf: Box<Leaf<u8>> = box unsafe{mem::uninitialized()};
let (start, end) = Leaf::init(&mut leaf);
Vec{list:OwnedOrBorrowed::Owned(leaf),start:start,end:end,phantom:marker::PhantomData}
}
pub fn with_list(list: &'a mut Leaf<u8>, start: LeafIndex, end: LeafIndex) -> Vec<'a,T> {
assert!(start == end && list.len(&start, &end) == 0);
Vec{list:OwnedOrBorrowed::Borrowed(list),start:start,end:end,phantom:marker::PhantomData}
}
pub fn push_front(&mut self, val: T) {
val.processsendable_write(&mut |buf,len| {
let mut start = self.start.clone_right();
let mut start2 = start.clone_right();
self.list.list_mut().replace(&mut start, &mut start2, unsafe{slice::from_raw_parts(buf, len)}.iter().map(|&x|x));
});
}
pub fn push(&mut self, val: T) {
val.processsendable_write(&mut |buf,len| {
let mut end = self.end.clone_left();
let mut end2 = end.clone_right();
self.list.list_mut().replace(&mut end, &mut end2, unsafe{slice::from_raw_parts(buf, len)}.iter().map(|&x|x));
});
}
pub fn map<F,T1>(mut self, f: F) -> Vec<'a,T1> where F: Fn(T) -> T1 + ProcessSendable, T1: ProcessSendable {
let mut iter = self.start.clone_right();
while iter != self.end {
let mut start = iter.clone_left();
let mut res: T = unsafe{mem::uninitialized()};
res.processsendable_read(&mut |buf,len| {
let start2 = iter.clone_left();
for _ in 0..len {
self.list.list_mut().increment(&mut iter);
}
let res = self.list.list_mut().read(&start2, &iter);
unsafe{ptr::copy_nonoverlapping(res.as_ptr(), buf, len)};
});
let res = f(res);
self.list.list_mut().replace(&mut start, &mut iter, iter::empty());
res.processsendable_write(&mut |buf,len| {
let mut start = iter.clone_left();
self.list.list_mut().replace(&mut start, &mut iter, unsafe{slice::from_raw_parts(buf, len)}.iter().map(|&x|x));
});
}
Vec{list:self.list,start:self.start,end:self.end,phantom:marker::PhantomData}
}
pub fn filter<F>(&mut self, f: F) where F: Fn(&T) -> bool + ProcessSendable {
let mut iter = self.start.clone_right();
while iter != self.end {
let mut start = iter.clone_left();
let mut res: T = unsafe{mem::uninitialized()};
res.processsendable_read(&mut |buf,len| {
let start2 = iter.clone_left();
for _ in 0..len {
self.list.list_mut().increment(&mut iter);
}
let res = self.list.list_mut().read(&start2, &iter);
unsafe{ptr::copy_nonoverlapping(res.as_ptr(), buf, len)};
});
if !f(&res) {
self.list.list_mut().replace(&mut start, &mut iter, iter::empty());
}
}
}
pub fn reduce<F,T1>(&mut self, initial: T1, f: F) -> T1 where F: Fn(T1, &T) -> T1 + ProcessSendable, T1: ProcessSendable {
let mut acc = initial;
let mut iter = self.start.clone_right();
while iter != self.end {
let mut res: T = unsafe{mem::uninitialized()};
res.processsendable_read(&mut |buf,len| {
let start2 = iter.clone_left();
for _ in 0..len {
self.list.list_mut().increment(&mut iter);
}
let res = self.list.list_mut().read(&start2, &iter);
unsafe{ptr::copy_nonoverlapping(res.as_ptr(), buf, len)};
});
acc = f(acc, &res);
}
acc
}
pub fn iter<'b>(&'b mut self) -> VecIter<'a,'b,T> {
let iter = self.start.clone_right();
VecIter{list:self,iter:iter}
}
}
pub struct VecIter<'a,'b,T> where T: 'a + ProcessSendable, 'a:'b {
list: &'b mut Vec<'a,T>,
iter: LeafIndex
}
impl<'a,'b,T> iter::Iterator for VecIter<'a,'b,T> where T: ProcessSendable {
type Item = T; fn next(&mut self) -> Option<Self::Item> {
if self.iter == self.list.end {
None
} else {
let mut res: T = unsafe{mem::uninitialized()};
res.processsendable_read(&mut |buf,len| {
let iter = self.iter.clone_left();
for _ in 0..len {
self.list.list.list_mut().increment(&mut self.iter);
}
let res = self.list.list.list_mut().read(&iter, &self.iter);
unsafe{ptr::copy_nonoverlapping(res.as_ptr(), buf, len)};
});
Some(res)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn dataframe() {
let mut data_frame: Vec<String> = Vec::new();
data_frame.push(String::from("http://google.com"));
data_frame.push(String::from("http://bbc.co.uk"));
data_frame.push(String::from("http://hadean.com"));
let mut data_frame: Vec<String> = data_frame.map(|mut val|{val.push_str("/xyz");val});
data_frame.filter(|val|val.len() > 20);
for string in data_frame.iter() {
println!("{}", string);
}
let total_length = data_frame.reduce(0u64, |acc, val| acc + val.len() as u64);
println!("{}", total_length);
}
}