pub mod serde;
mod projection;
use slab::{Slab,SlabRef,Memo,MemoId,MemoBody,MemoRef,EdgeLink,RelationSlotId};
use subject::*;
use error::*;
use std::mem;
use std::fmt;
use std::slice;
use std::collections::VecDeque;
#[derive(Clone, PartialEq)]
pub enum MemoRefHead {
Null,
Subject{
subject_id: SubjectId,
head: Vec<MemoRef>
},
Anonymous{
head: Vec<MemoRef>
}
}
impl MemoRefHead {
pub fn apply_memoref(&mut self, new: &MemoRef, slab: &Slab ) -> Result<bool,WriteError> {
let head = match *self {
MemoRefHead::Null => {
if let Some(subject_id) = new.subject_id {
*self = MemoRefHead::Subject{
head: vec![new.clone()],
subject_id
};
}else{
*self = MemoRefHead::Anonymous{ head: vec![new.clone()] };
}
return Ok(true);
},
MemoRefHead::Anonymous{ ref mut head } => {
head
},
MemoRefHead::Subject{ ref mut head, ..} => {
head
}
};
let mut new_is_descended = false;
let mut new_descends = false;
let mut applied = false;
let mut replaced = false;
'existing: for i in (0..head.len()).rev() {
let mut remove = false;
{
let ref mut existing = head[i];
if existing == new {
return Ok(false);
} else if existing.descends(&new,&slab)? {
new_is_descended = true;
break 'existing;
} else if new.descends(&existing, &slab)? {
new_descends = true;
applied = true;
if replaced {
remove = true;
}else{
mem::replace( existing, new.clone() );
replaced = true;
}
}
}
if remove {
head.remove(i);
}
}
if !new_descends && !new_is_descended {
head.push(new.clone());
applied = true; }
if applied {
}else{
}
Ok(applied)
}
pub fn apply_memorefs (&mut self, new_memorefs: &Vec<MemoRef>, slab: &Slab) -> Result<(),WriteError> {
for new in new_memorefs.iter(){
self.apply_memoref(new, slab)?;
}
Ok(())
}
pub fn apply (&mut self, other: &MemoRefHead, slab: &Slab) -> Result<bool,WriteError> {
let mut applied = false;
for new in other.iter(){
if self.apply_memoref( new, slab )? {
applied = true;
}
}
Ok(applied)
}
pub fn descends_or_contains (&self, other: &MemoRefHead, slab: &Slab) -> Result<bool,RetrieveError> {
match *self {
MemoRefHead::Null => Ok(false),
MemoRefHead::Subject{ ref head, .. } | MemoRefHead::Anonymous{ ref head, .. } => {
match *other {
MemoRefHead::Null => Ok(false),
MemoRefHead::Subject{ head: ref other_head, .. } | MemoRefHead::Anonymous{ head: ref other_head, .. } => {
if head.len() == 0 || other_head.len() == 0 {
return Ok(false) }
for memoref in head.iter(){
'other: for other_memoref in other_head.iter(){
if memoref == other_memoref {
} else if !memoref.descends(other_memoref, slab)? {
return Ok(false);
}
}
}
Ok(true)
}
}
}
}
}
pub fn memo_ids (&self) -> Vec<MemoId> {
match *self {
MemoRefHead::Null => Vec::new(),
MemoRefHead::Subject{ ref head, .. } | MemoRefHead::Anonymous{ ref head, .. } => head.iter().map(|m| m.id).collect()
}
}
pub fn subject_id (&self) -> Option<SubjectId> {
match *self {
MemoRefHead::Null | MemoRefHead::Anonymous{..} => None,
MemoRefHead::Subject{ subject_id, .. } => Some(subject_id)
}
}
pub fn is_some (&self) -> bool {
match *self {
MemoRefHead::Null => false,
_ => true
}
}
pub fn to_vec (&self) -> Vec<MemoRef> {
match *self {
MemoRefHead::Null => vec![],
MemoRefHead::Anonymous { ref head, .. } => head.clone(),
MemoRefHead::Subject{ ref head, .. } => head.clone()
}
}
pub fn to_vecdeque (&self) -> VecDeque<MemoRef> {
match *self {
MemoRefHead::Null => VecDeque::new(),
MemoRefHead::Anonymous { ref head, .. } => VecDeque::from(head.clone()),
MemoRefHead::Subject{ ref head, .. } => VecDeque::from(head.clone())
}
}
pub fn len (&self) -> usize {
match *self {
MemoRefHead::Null => 0,
MemoRefHead::Anonymous { ref head, .. } => head.len(),
MemoRefHead::Subject{ ref head, .. } => head.len()
}
}
pub fn iter (&self) -> slice::Iter<MemoRef> {
static EMPTY : &'static [MemoRef] = &[];
match *self {
MemoRefHead::Null => EMPTY.iter(), MemoRefHead::Anonymous{ ref head } => head.iter(),
MemoRefHead::Subject{ ref head, .. } => head.iter()
}
}
pub fn causal_memo_iter(&self, slab: &Slab ) -> CausalMemoIter {
CausalMemoIter::from_head( &self, slab )
}
pub fn is_fully_materialized(&self, slab: &Slab ) -> bool {
let head = match *self {
MemoRefHead::Null => {
return true;
},
MemoRefHead::Anonymous { ref head, .. } => head,
MemoRefHead::Subject{ ref head, .. } => head
};
for memoref in head.iter(){
let memo = memoref.get_memo(slab).unwrap();
if let MemoBody::FullyMaterialized { .. } = memo.body {
}else{
return false
}
}
true
}
pub fn clone_for_slab (&self, from_slabref: &SlabRef, to_slab: &Slab, include_memos: bool ) -> Self {
assert!(from_slabref.slab_id != to_slab.id, "slab id should differ");
match *self {
MemoRefHead::Null => MemoRefHead::Null,
MemoRefHead::Anonymous { ref head } => MemoRefHead::Anonymous{
head: head.iter().map(|mr| mr.clone_for_slab(from_slabref, to_slab, include_memos )).collect()
},
MemoRefHead::Subject{ subject_id, ref head } => MemoRefHead::Subject {
subject_id: subject_id,
head: head.iter().map(|mr| mr.clone_for_slab(from_slabref, to_slab, include_memos )).collect()
}
}
}
}
impl fmt::Debug for MemoRefHead{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
MemoRefHead::Null => {
fmt.debug_struct("MemoRefHead::Null").finish()
},
MemoRefHead::Anonymous{ ref head, .. } => {
fmt.debug_struct("MemoRefHead::Anonymous")
.field("memo_refs", head )
.finish()
}
MemoRefHead::Subject{ ref subject_id, ref head } => {
fmt.debug_struct("MemoRefHead::Subject")
.field("subject_id", &subject_id )
.field("memo_refs", head )
.finish()
}
}
}
}
pub struct CausalMemoIter {
queue: VecDeque<MemoRef>,
slab: Slab
}
impl CausalMemoIter {
pub fn from_head ( head: &MemoRefHead, slab: &Slab) -> Self {
CausalMemoIter {
queue: head.to_vecdeque(),
slab: slab.clone()
}
}
pub fn from_memoref (memoref: &MemoRef, slab: &Slab ) -> Self {
let mut q = VecDeque::new();
q.push_front(memoref.clone());
CausalMemoIter {
queue: q,
slab: slab.clone()
}
}
}
impl Iterator for CausalMemoIter {
type Item = Result<Memo,RetrieveError>;
fn next (&mut self) -> Option<Result<Memo,RetrieveError>> {
if let Some(memoref) = self.queue.pop_front() {
match memoref.get_memo( &self.slab ) {
Ok(memo) => {
self.queue.append(&mut memo.get_parent_head().to_vecdeque());
return Some(Ok(memo));
},
Err(e) => return Some(Err(e))
}
}
return None;
}
}