<commit_before>// Copyright 2015 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use solver::fd::event::*;
use solver::event::*;
use solver::variable::Variable;
use interval::ncollections::ops::*;
use interval::ops::*;

use std::fmt::{Formatter, Display, Error};

#[derive(Copy, PartialEq, Eq, Debug, Clone)]
pub struct FDVar<Domain> {
  idx: usize,
  dom: Domain
}

impl<Domain: Display> Display for FDVar<Domain> {
  fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
    formatter.write_fmt(format_args!("({}, {})", self.idx, self.dom))
  }
}

impl<Domain> Variable for FDVar<Domain> where
  Domain: Cardinality
{
  type Domain = Domain;
  type Event = FDEvent;

  fn new(idx: usize, dom: Domain) -> FDVar<Domain> {
    assert!(!dom.is_empty());
    FDVar {
      idx: idx,
      dom: dom
    }
  }
}

pub trait VarIndex
{
  fn index(&self) -> usize;
}

impl<Domain> VarIndex for FDVar<Domain>
{
  fn index(&self) -> usize {
    self.idx
  }
}

pub trait Failure
{
  fn is_failed(&self) -> bool;
}

impl<Domain> Failure for FDVar<Domain> where
  Domain: Cardinality
{
  fn is_failed(&self) -> bool {
    self.dom.is_empty()
  }
}

trait VarDomain: Bounded + Cardinality + Subset
{}

impl<R> VarDomain for R where
  R: Bounded + Cardinality + Subset
{}

pub trait EventUpdate<Item>
{
  fn event_update(&mut self, value: Item,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventUpdate<Domain> for FDVar<Domain> where
  Domain: VarDomain
{
  fn event_update(&mut self, dom: Domain,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    assert!(dom.is_subset(&self.dom), "Domain update must be monotonic.");
    if dom.is_empty() { false } // Failure
    else {
      if let Some(event) = FDEvent::new(&dom, &self.dom) {
        events.push((self.idx, event));
        self.dom = dom;
      }
      true
    }
  }
}

impl<Domain> Bounded for FDVar<Domain> where
  Domain: Bounded
{
  type Bound = Domain::Bound;

  fn lower(&self) -> Domain::Bound {
    self.dom.lower()
  }

  fn upper(&self) -> Domain::Bound {
    self.dom.upper()
  }
}

impl<Domain> Disjoint for FDVar<Domain> where
  Domain: Disjoint
{
  fn is_disjoint(&self, other: &FDVar<Domain>) -> bool {
    self.dom.is_disjoint(&other.dom)
  }
}

impl<Domain> Contains<Domain::Bound> for FDVar<Domain> where
  Domain: Bounded + Contains<<Domain as Bounded>::Bound>
{
  fn contains(&self, value: &Domain::Bound) -> bool {
    self.dom.contains(value)
  }
}

pub trait EventShrinkLeft<Bound>
{
  fn event_shrink_left(&mut self, lb: Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventShrinkLeft<Domain::Bound> for FDVar<Domain> where
  Domain: VarDomain + ShrinkLeft<<Domain as Bounded>::Bound> + Clone
{
  fn event_shrink_left(&mut self, lb: Domain::Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.clone().shrink_left(lb);
    self.event_update(new, events)
  }
}

pub trait EventShrinkRight<Bound>
{
  fn event_shrink_right(&mut self, ub: Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventShrinkRight<Domain::Bound> for FDVar<Domain> where
  Domain: VarDomain + ShrinkRight<<Domain as Bounded>::Bound> + Clone
{
  fn event_shrink_right(&mut self, ub: Domain::Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.clone().shrink_right(ub);
    self.event_update(new, events)
  }
}

pub trait EventRemove<Item>
{
  fn event_remove(&mut self, value: Item,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventRemove<Domain::Bound> for FDVar<Domain> where
  Domain: VarDomain + Difference<<Domain as Bounded>::Bound, Output=Domain> + Clone
{
  fn event_remove(&mut self, value: Domain::Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.clone().difference(value);
    self.event_update(new, events)
  }
}

pub trait EventIntersection<RHS = Self>
{
  fn event_intersection(&mut self, other: &mut RHS,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventIntersection for FDVar<Domain> where
  Domain: VarDomain + Intersection<Output=Domain> + Clone
{
  fn event_intersection(&mut self, other: &mut FDVar<Domain>,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.clone().intersection(other.dom.clone());
    self.event_update(new.clone(), events) &&
    other.event_update(new, events)
  }
}

#[cfg(test)]
mod test {
  use super::*;
  use solver::fd::event::*;
  use solver::fd::event::FDEvent::*;
  use solver::variable::Variable;
  use interval::interval::*;
  use interval::ncollections::ops::*;

  #[test]
  fn var_update_test() {
    let dom0_10 = (0,10).to_interval();
    let dom0_9 = (0,5).to_interval();
    let dom1_10 = (5,10).to_interval();
    let dom1_9 = (1,9).to_interval();
    let dom0_0 = (0,0).to_interval();
    let empty = Interval::empty();
    let var0_10 = Variable::new(0, dom0_10);

    var_update_test_one(var0_10, dom0_10, vec![], true);
    var_update_test_one(var0_10, empty, vec![], false);
    var_update_test_one(var0_10, dom0_0, vec![Assignment], true);
    var_update_test_one(var0_10, dom1_10, vec![Bound], true);
    var_update_test_one(var0_10, dom0_9, vec![Bound], true);
    var_update_test_one(var0_10, dom1_9, vec![Bound], true);
  }

  fn var_update_test_one(mut var: FDVar<Interval<i32>>, dom: Interval<i32>, expect: Vec<FDEvent>, expect_success: bool) {
    let mut events = vec![];
    assert_eq!(var.event_update(dom, &mut events), expect_success);
    if expect_success {
      assert_eq_events(events, expect);
      assert_eq!(var.dom, dom);
    }
  }

  fn assert_eq_events(events: Vec<(usize, FDEvent)>, expect: Vec<FDEvent>) {
    for ((_,ev), expect) in events.into_iter().zip(expect.into_iter()) {
      assert_eq!(ev, expect);
    }
  }

  #[test]
  fn var_update_bound() {
    let dom0_10 = (0,10).to_interval();
    let var0_10 = Variable::new(0, dom0_10);

    var_update_lb_test_one(var0_10, 0, vec![], true);
    var_update_lb_test_one(var0_10, 10, vec![Assignment], true);
    var_update_lb_test_one(var0_10, 1, vec![Bound], true);
    var_update_lb_test_one(var0_10, 11, vec![], false);

    var_update_ub_test_one(var0_10, 10, vec![], true);
    var_update_ub_test_one(var0_10, 0, vec![Assignment], true);
    var_update_ub_test_one(var0_10, 1, vec![Bound], true);
    var_update_ub_test_one(var0_10, -1, vec![], false);
  }

  fn var_update_lb_test_one(mut var: FDVar<Interval<i32>>, lb: i32, expect: Vec<FDEvent>, expect_success: bool) {
    let ub = var.upper();
    let mut events = vec![];
    assert_eq!(var.event_shrink_left(lb, &mut events), expect_success);
    if expect_success {
      assert_eq_events(events, expect);
      assert_eq!(var.dom, (lb,ub).to_interval());
    }
  }

  fn var_update_ub_test_one(mut var: FDVar<Interval<i32>>, ub: i32, expect: Vec<FDEvent>, expect_success: bool) {
    let lb = var.lower();
    let mut events = vec![];
    assert_eq!(var.event_shrink_right(ub, &mut events), expect_success);
    if expect_success {
      assert_eq_events(events, expect);
      assert_eq!(var.dom, (lb,ub).to_interval());
    }
  }

  #[test]
  fn var_intersection_test() {
    let var0_10 = Variable::new(1, (0,10).to_interval());
    let var10_20 = Variable::new(2, (10,20).to_interval());
    let var11_20 = Variable::new(3, (11,20).to_interval());
    let var1_9 = Variable::new(4, (1,9).to_interval());

    var_intersection_test_one(var0_10, var10_20, Some(vec![(1, Assignment), (2, Assignment)]));
    var_intersection_test_one(var0_10, var1_9, Some(vec![(1, Bound)]));
    var_intersection_test_one(var1_9, var0_10, Some(vec![(1, Bound)]));
    var_intersection_test_one(var0_10, var11_20, None);
  }

  fn var_intersection_test_one(mut v1: FDVar<Interval<i32>>, mut v2: FDVar<Interval<i32>>, events: Option<Vec<(usize, FDEvent)>>) {
    let mut ev = vec![];
    let res =
      if v1.event_intersection(&mut v2, &mut ev) {
        Some(ev)
      }
      else {
        None
      };
    assert_eq!(res, events);
  }

  #[test]
  #[should_panic]
  fn var_non_monotonic_update_singleton() {
    let dom0_10 = (0,10).to_interval();
    let mut var0_10: FDVar<Interval<i32>> = Variable::new(0, dom0_10);
    let dom11_11 = 11.to_interval();

    var0_10.event_update(dom11_11, &mut vec![]);
  }

  #[test]
  #[should_panic]
  fn var_non_monotonic_update_widen() {
    let dom0_10 = (0,10).to_interval();
    let mut var0_10: FDVar<Interval<i32>> = Variable::new(0, dom0_10);
    let domm5_15 = (-5, 15).to_interval();

    var0_10.event_update(domm5_15, &mut vec![]);
  }
}<commit_msg>Remove some clone operation due to a change in Interval interface.<commit_after>// Copyright 2015 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use solver::fd::event::*;
use solver::event::*;
use solver::variable::Variable;
use interval::ncollections::ops::*;
use interval::ops::*;

use std::fmt::{Formatter, Display, Error};

#[derive(Copy, PartialEq, Eq, Debug, Clone)]
pub struct FDVar<Domain> {
  idx: usize,
  dom: Domain
}

impl<Domain: Display> Display for FDVar<Domain> {
  fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
    formatter.write_fmt(format_args!("({}, {})", self.idx, self.dom))
  }
}

impl<Domain> Variable for FDVar<Domain> where
  Domain: Cardinality
{
  type Domain = Domain;
  type Event = FDEvent;

  fn new(idx: usize, dom: Domain) -> FDVar<Domain> {
    assert!(!dom.is_empty());
    FDVar {
      idx: idx,
      dom: dom
    }
  }
}

pub trait VarIndex
{
  fn index(&self) -> usize;
}

impl<Domain> VarIndex for FDVar<Domain>
{
  fn index(&self) -> usize {
    self.idx
  }
}

pub trait Failure
{
  fn is_failed(&self) -> bool;
}

impl<Domain> Failure for FDVar<Domain> where
  Domain: Cardinality
{
  fn is_failed(&self) -> bool {
    self.dom.is_empty()
  }
}

trait VarDomain: Bounded + Cardinality + Subset
{}

impl<R> VarDomain for R where
  R: Bounded + Cardinality + Subset
{}

pub trait EventUpdate<Item>
{
  fn event_update(&mut self, value: Item,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventUpdate<Domain> for FDVar<Domain> where
  Domain: VarDomain
{
  fn event_update(&mut self, dom: Domain,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    assert!(dom.is_subset(&self.dom), "Domain update must be monotonic.");
    if dom.is_empty() { false } // Failure
    else {
      if let Some(event) = FDEvent::new(&dom, &self.dom) {
        events.push((self.idx, event));
        self.dom = dom;
      }
      true
    }
  }
}

impl<Domain> Bounded for FDVar<Domain> where
  Domain: Bounded
{
  type Bound = Domain::Bound;

  fn lower(&self) -> Domain::Bound {
    self.dom.lower()
  }

  fn upper(&self) -> Domain::Bound {
    self.dom.upper()
  }
}

impl<Domain> Disjoint for FDVar<Domain> where
  Domain: Disjoint
{
  fn is_disjoint(&self, other: &FDVar<Domain>) -> bool {
    self.dom.is_disjoint(&other.dom)
  }
}

impl<Domain> Contains<Domain::Bound> for FDVar<Domain> where
  Domain: Bounded + Contains<<Domain as Bounded>::Bound>
{
  fn contains(&self, value: &Domain::Bound) -> bool {
    self.dom.contains(value)
  }
}

pub trait EventShrinkLeft<Bound>
{
  fn event_shrink_left(&mut self, lb: Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventShrinkLeft<Domain::Bound> for FDVar<Domain> where
  Domain: VarDomain + ShrinkLeft<<Domain as Bounded>::Bound>
{
  fn event_shrink_left(&mut self, lb: Domain::Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.shrink_left(lb);
    self.event_update(new, events)
  }
}

pub trait EventShrinkRight<Bound>
{
  fn event_shrink_right(&mut self, ub: Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventShrinkRight<Domain::Bound> for FDVar<Domain> where
  Domain: VarDomain + ShrinkRight<<Domain as Bounded>::Bound>
{
  fn event_shrink_right(&mut self, ub: Domain::Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.shrink_right(ub);
    self.event_update(new, events)
  }
}

pub trait EventRemove<Item>
{
  fn event_remove(&mut self, value: Item,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventRemove<Domain::Bound> for FDVar<Domain> where
  Domain: VarDomain + Difference<<Domain as Bounded>::Bound, Output=Domain>
{
  fn event_remove(&mut self, value: Domain::Bound,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.difference(&value);
    self.event_update(new, events)
  }
}

pub trait EventIntersection<RHS = Self>
{
  fn event_intersection(&mut self, other: &mut RHS,
    events: &mut Vec<(usize, FDEvent)>) -> bool;
}

impl<Domain> EventIntersection for FDVar<Domain> where
  Domain: VarDomain + Intersection<Output=Domain> + Clone
{
  fn event_intersection(&mut self, other: &mut FDVar<Domain>,
    events: &mut Vec<(usize, FDEvent)>) -> bool
  {
    let new = self.dom.intersection(&other.dom);
    self.event_update(new.clone(), events) &&
    other.event_update(new, events)
  }
}

#[cfg(test)]
mod test {
  use super::*;
  use solver::fd::event::*;
  use solver::fd::event::FDEvent::*;
  use solver::variable::Variable;
  use interval::interval::*;
  use interval::ncollections::ops::*;

  #[test]
  fn var_update_test() {
    let dom0_10 = (0,10).to_interval();
    let dom0_9 = (0,5).to_interval();
    let dom1_10 = (5,10).to_interval();
    let dom1_9 = (1,9).to_interval();
    let dom0_0 = (0,0).to_interval();
    let empty = Interval::empty();
    let var0_10 = Variable::new(0, dom0_10);

    var_update_test_one(var0_10, dom0_10, vec![], true);
    var_update_test_one(var0_10, empty, vec![], false);
    var_update_test_one(var0_10, dom0_0, vec![Assignment], true);
    var_update_test_one(var0_10, dom1_10, vec![Bound], true);
    var_update_test_one(var0_10, dom0_9, vec![Bound], true);
    var_update_test_one(var0_10, dom1_9, vec![Bound], true);
  }

  fn var_update_test_one(mut var: FDVar<Interval<i32>>, dom: Interval<i32>, expect: Vec<FDEvent>, expect_success: bool) {
    let mut events = vec![];
    assert_eq!(var.event_update(dom, &mut events), expect_success);
    if expect_success {
      assert_eq_events(events, expect);
      assert_eq!(var.dom, dom);
    }
  }

  fn assert_eq_events(events: Vec<(usize, FDEvent)>, expect: Vec<FDEvent>) {
    for ((_,ev), expect) in events.into_iter().zip(expect.into_iter()) {
      assert_eq!(ev, expect);
    }
  }

  #[test]
  fn var_update_bound() {
    let dom0_10 = (0,10).to_interval();
    let var0_10 = Variable::new(0, dom0_10);

    var_update_lb_test_one(var0_10, 0, vec![], true);
    var_update_lb_test_one(var0_10, 10, vec![Assignment], true);
    var_update_lb_test_one(var0_10, 1, vec![Bound], true);
    var_update_lb_test_one(var0_10, 11, vec![], false);

    var_update_ub_test_one(var0_10, 10, vec![], true);
    var_update_ub_test_one(var0_10, 0, vec![Assignment], true);
    var_update_ub_test_one(var0_10, 1, vec![Bound], true);
    var_update_ub_test_one(var0_10, -1, vec![], false);
  }

  fn var_update_lb_test_one(mut var: FDVar<Interval<i32>>, lb: i32, expect: Vec<FDEvent>, expect_success: bool) {
    let ub = var.upper();
    let mut events = vec![];
    assert_eq!(var.event_shrink_left(lb, &mut events), expect_success);
    if expect_success {
      assert_eq_events(events, expect);
      assert_eq!(var.dom, (lb,ub).to_interval());
    }
  }

  fn var_update_ub_test_one(mut var: FDVar<Interval<i32>>, ub: i32, expect: Vec<FDEvent>, expect_success: bool) {
    let lb = var.lower();
    let mut events = vec![];
    assert_eq!(var.event_shrink_right(ub, &mut events), expect_success);
    if expect_success {
      assert_eq_events(events, expect);
      assert_eq!(var.dom, (lb,ub).to_interval());
    }
  }

  #[test]
  fn var_intersection_test() {
    let var0_10 = Variable::new(1, (0,10).to_interval());
    let var10_20 = Variable::new(2, (10,20).to_interval());
    let var11_20 = Variable::new(3, (11,20).to_interval());
    let var1_9 = Variable::new(4, (1,9).to_interval());

    var_intersection_test_one(var0_10, var10_20, Some(vec![(1, Assignment), (2, Assignment)]));
    var_intersection_test_one(var0_10, var1_9, Some(vec![(1, Bound)]));
    var_intersection_test_one(var1_9, var0_10, Some(vec![(1, Bound)]));
    var_intersection_test_one(var0_10, var11_20, None);
  }

  fn var_intersection_test_one(mut v1: FDVar<Interval<i32>>, mut v2: FDVar<Interval<i32>>, events: Option<Vec<(usize, FDEvent)>>) {
    let mut ev = vec![];
    let res =
      if v1.event_intersection(&mut v2, &mut ev) {
        Some(ev)
      }
      else {
        None
      };
    assert_eq!(res, events);
  }

  #[test]
  #[should_panic]
  fn var_non_monotonic_update_singleton() {
    let dom0_10 = (0,10).to_interval();
    let mut var0_10: FDVar<Interval<i32>> = Variable::new(0, dom0_10);
    let dom11_11 = 11.to_interval();

    var0_10.event_update(dom11_11, &mut vec![]);
  }

  #[test]
  #[should_panic]
  fn var_non_monotonic_update_widen() {
    let dom0_10 = (0,10).to_interval();
    let mut var0_10: FDVar<Interval<i32>> = Variable::new(0, dom0_10);
    let domm5_15 = (-5, 15).to_interval();

    var0_10.event_update(domm5_15, &mut vec![]);
  }
}<|endoftext|>


<commit_before>use index::lsmtree::placement::sm::client::SMClient as PlacementClient;
use index::lsmtree::placement::sm::{Placement as PlacementMeta, QueryError};
use index::lsmtree::service::{AsyncServiceClient, LSMTreeSvrError};
use index::trees::{EntryKey, KEY_SIZE};
use linked_hash_map::LinkedHashMap;
use parking_lot::RwLock;
use ram::types::Id;
use server::NebServer;
use std::collections::btree_map::BTreeMap;
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use std::sync::Arc;
use futures::prelude::*;
use index::lsmtree::split::placement_client;
use index::lsmtree::placement;
use index::builder::Feature;
use byteorder::{BigEndian, WriteBytesExt};
use index::lsmtree::tree::LSMTreeResult;

pub struct IndexEntry {
    id: Id,
    val: u64,
}

pub struct Cursor {
    buffer: Vec<IndexEntry>,
    at_end: bool,
    pos: usize,
}

pub struct Placement {
    meta: PlacementMeta,
    client: Arc<AsyncServiceClient>,
}

pub struct LSMTreeClient {
    counter: AtomicUsize,
    placements: RwLock<BTreeMap<Vec<u8>, Placement>>,
    cursors: LinkedHashMap<usize, Cursor>,
    placement_client: PlacementClient,
    neb: Arc<NebServer>,
}

pub struct SubTree {
    client: Arc<AsyncServiceClient>,
    epoch: u64,
    tree_id: Id,
    starts: Vec<u8>
}

impl SubTree {
    pub fn new(tree_id: Id, client: Arc<AsyncServiceClient>, epoch: u64, starts: &Vec<u8>) -> Self {
        Self {
            tree_id, client, epoch, starts: starts.clone()
        }
    }
}

impl LSMTreeClient {
    fn update_placement(&self, sub_tree: &SubTree) {
        match self.placement_client.get(&sub_tree.tree_id).wait().unwrap() {
            Ok(placement) => {
                let mut placements = self.placements.write();
                let rpc_client = placement_client(&placement.id, &self.neb).wait().unwrap();
                placements.remove(&sub_tree.starts);
                placements.insert(placement.starts.clone(), Placement {
                    meta: placement,
                    client: rpc_client
                });
            },
            Err(QueryError::PlacementNotFound) => panic!("cannot find a suitable placement"),
            Err(e) => panic!("{:?}", e)
        }
    }

    fn get_sub_tree(&self, key: &Vec<u8>) -> SubTree {
        // Stage one, early exit if placement founded. Read lock only
        {
            let placements = self.placements.read();
            let candidate = placements.range::<Vec<u8>, _>(key..).next();
            if let Some((_, candidate_placement)) = candidate {
                if &candidate_placement.meta.ends >= key {
                    // in range, return
                    return SubTree::new(
                        candidate_placement.meta.id,
                        candidate_placement.client.clone(),
                        candidate_placement.meta.epoch,
                        &candidate_placement.meta.starts
                    );
                }
            }
        }

        // Stage two, write lock. Also check for placement availability. If not, insert it to the cache.
        {
            let mut placements = self.placements.write();
            let candidate = placements.range::<Vec<u8>, _>(key..).next();
            if let Some((_, candidate_placement)) = candidate {
                if &candidate_placement.meta.ends >= key {
                    // in range, return
                    return SubTree::new(
                        candidate_placement.meta.id,
                        candidate_placement.client.clone(),
                        candidate_placement.meta.epoch,
                        &candidate_placement.meta.starts
                    );
                }
            }
            let placement: PlacementMeta = self.placement_client.locate(&Vec::from(key.as_slice()))
                .wait().unwrap().unwrap();
            let rpc_client = placement_client(&placement.id, &self.neb)
                .wait().unwrap();
            let sub_tree = SubTree::new(
                placement.id,
                rpc_client.clone(),
                placement.epoch,
                &placement.starts
            );
            placements.insert(placement.starts.clone(), Placement {
                meta: placement,
                client: rpc_client
            });
            sub_tree
        }
    }

    fn essential_key_components(schema_id: u32, field_id: &u64) -> Vec<u8> {
        let mut key = Vec::with_capacity(KEY_SIZE);
        let mut schema_id_fut = [0u8; 4];
        let mut field_id_fut = [0u8; 8];
        (&mut schema_id_fut as &mut [u8]).write_u32::<BigEndian>(schema_id).unwrap();
        (&mut field_id_fut as &mut [u8]).write_u64::<BigEndian>(*field_id).unwrap();
        key.extend_from_slice(&schema_id_fut);  // 4 bytes
        key.extend_from_slice(&field_id_fut);   // 8 bytes
        key
    }

    pub fn insert(&self,schema_id: u32, field_id: &u64, cell_id: &Id, feature: &Feature) -> bool {
        let mut key = Self::essential_key_components(schema_id, field_id);
        key.extend_from_slice(feature); // 8 bytes
        key.extend_from_slice(&cell_id.to_binary()); // ID SIZE
        loop {
            let sub_tree = self.get_sub_tree(&key);
            let tree_client = &sub_tree.client;
            let insertion_result = tree_client
                    .insert(sub_tree.tree_id, key.clone(), sub_tree.epoch)
                    .wait().unwrap();
            match insertion_result {
                Ok(LSMTreeResult::Ok(insert_res)) => {
                    return insert_res;
                },
                Ok(LSMTreeResult::EpochMismatch(_, _)) | Err(LSMTreeSvrError::TreeNotFound) => {
                    self.update_placement(&sub_tree);
                },
                Err(_) => {
                    panic!("Error occurred on distributed LSM-tree insertion");
                }
            }
        }
    }
}
<commit_msg>tree initialization<commit_after>use index::lsmtree::placement::sm::client::SMClient as PlacementClient;
use index::lsmtree::placement::sm::{Placement as PlacementMeta, QueryError};
use index::lsmtree::service::{AsyncServiceClient, LSMTreeSvrError};
use index::trees::{EntryKey, KEY_SIZE};
use linked_hash_map::LinkedHashMap;
use parking_lot::{RwLock, Mutex};
use ram::types::Id;
use server::NebServer;
use std::collections::btree_map::BTreeMap;
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use std::sync::Arc;
use futures::prelude::*;
use index::lsmtree::split::placement_client;
use index::lsmtree::placement;
use index::builder::Feature;
use byteorder::{BigEndian, WriteBytesExt};
use index::lsmtree::tree::LSMTreeResult;
use bifrost::conshash::ConsistentHashing;
use index::lsmtree;
use bifrost::raft::client::RaftClient;

pub struct IndexEntry {
    id: Id,
    val: u64,
}

pub struct Cursor {
    buffer: Vec<IndexEntry>,
    at_end: bool,
    pos: usize,
}

pub struct Placement {
    meta: PlacementMeta,
    client: Arc<AsyncServiceClient>,
}

pub struct LSMTreeClient {
    counter: AtomicUsize,
    placements: RwLock<BTreeMap<Vec<u8>, Placement>>,
    cursors: RwLock<LinkedHashMap<usize, Mutex<Cursor>>>,
    placement_client: PlacementClient,
    neb: Arc<NebServer>,
}

pub struct SubTree {
    client: Arc<AsyncServiceClient>,
    epoch: u64,
    tree_id: Id,
    starts: Vec<u8>
}

impl SubTree {
    pub fn new(tree_id: Id, client: Arc<AsyncServiceClient>, epoch: u64, starts: &Vec<u8>) -> Self {
        Self {
            tree_id, client, epoch, starts: starts.clone()
        }
    }
}

impl LSMTreeClient {

    pub fn new(neb: &Arc<NebServer>, raft_client: &Arc<RaftClient>,) -> Self {
        Self {
            counter: AtomicUsize::new(0),
            placements: RwLock::new(BTreeMap::new()),
            cursors: RwLock::new(LinkedHashMap::new()),
            placement_client: PlacementClient::new(
                lsmtree::placement::sm::SM_ID,
                raft_client
            ),
            neb: neb.clone()
        }
    }

    fn update_placement(&self, sub_tree: &SubTree) {
        match self.placement_client.get(&sub_tree.tree_id).wait().unwrap() {
            Ok(placement) => {
                let mut placements = self.placements.write();
                let rpc_client = placement_client(&placement.id, &self.neb).wait().unwrap();
                placements.remove(&sub_tree.starts);
                placements.insert(placement.starts.clone(), Placement {
                    meta: placement,
                    client: rpc_client
                });
            },
            Err(QueryError::PlacementNotFound) => panic!("cannot find a suitable placement"),
            Err(e) => panic!("{:?}", e)
        }
    }

    fn get_sub_tree(&self, key: &Vec<u8>) -> SubTree {
        // Stage one, early exit if placement founded. Read lock only
        {
            let placements = self.placements.read();
            let candidate = placements.range::<Vec<u8>, _>(key..).next();
            if let Some((_, candidate_placement)) = candidate {
                if &candidate_placement.meta.ends >= key {
                    // in range, return
                    return SubTree::new(
                        candidate_placement.meta.id,
                        candidate_placement.client.clone(),
                        candidate_placement.meta.epoch,
                        &candidate_placement.meta.starts
                    );
                }
            }
        }

        // Stage two, write lock. Also check for placement availability. If not, insert it to the cache.
        {
            let mut placements = self.placements.write();
            let candidate = placements.range::<Vec<u8>, _>(key..).next();
            if let Some((_, candidate_placement)) = candidate {
                if &candidate_placement.meta.ends >= key {
                    // in range, return
                    return SubTree::new(
                        candidate_placement.meta.id,
                        candidate_placement.client.clone(),
                        candidate_placement.meta.epoch,
                        &candidate_placement.meta.starts
                    );
                }
            }
            let placement: PlacementMeta = self.placement_client.locate(&Vec::from(key.as_slice()))
                .wait().unwrap().unwrap();
            let rpc_client = placement_client(&placement.id, &self.neb)
                .wait().unwrap();
            let sub_tree = SubTree::new(
                placement.id,
                rpc_client.clone(),
                placement.epoch,
                &placement.starts
            );
            placements.insert(placement.starts.clone(), Placement {
                meta: placement,
                client: rpc_client
            });
            sub_tree
        }
    }

    fn essential_key_components(schema_id: u32, field_id: &u64) -> Vec<u8> {
        let mut key = Vec::with_capacity(KEY_SIZE);
        let mut schema_id_fut = [0u8; 4];
        let mut field_id_fut = [0u8; 8];
        (&mut schema_id_fut as &mut [u8]).write_u32::<BigEndian>(schema_id).unwrap();
        (&mut field_id_fut as &mut [u8]).write_u64::<BigEndian>(*field_id).unwrap();
        key.extend_from_slice(&schema_id_fut);  // 4 bytes
        key.extend_from_slice(&field_id_fut);   // 8 bytes
        key
    }

    pub fn insert(&self,schema_id: u32, field_id: &u64, cell_id: &Id, feature: &Feature) -> bool {
        let mut key = Self::essential_key_components(schema_id, field_id);
        key.extend_from_slice(feature); // 8 bytes
        key.extend_from_slice(&cell_id.to_binary()); // ID SIZE
        loop {
            let sub_tree = self.get_sub_tree(&key);
            let tree_client = &sub_tree.client;
            let insertion_result = tree_client
                    .insert(sub_tree.tree_id, key.clone(), sub_tree.epoch)
                    .wait().unwrap();
            match insertion_result {
                Ok(LSMTreeResult::Ok(insert_res)) => {
                    return insert_res;
                },
                Ok(LSMTreeResult::EpochMismatch(_, _)) | Err(LSMTreeSvrError::TreeNotFound) => {
                    self.update_placement(&sub_tree);
                },
                Err(_) => {
                    panic!("Error occurred on distributed LSM-tree insertion");
                }
            }
        }
    }

}
<|endoftext|>


<commit_before>#![feature(proc_macro_hygiene)]
#![allow(unused_imports)]

extern crate dynasmrt;
extern crate dynasm;

use dynasm::dynasm;
use dynasmrt::DynasmApi;

// basic dynamic register usage
#[test]
fn bugreport_1() {
    let mut ops = dynasmrt::x64::Assembler::new().unwrap();
    dynasm!(ops
       ; int 3
       ; mov Rq(8), rdi
       ; add Rq(8), 1
       ; mov rax, Rq(8)
       ; ret
    );
    let buf = ops.finalize().unwrap();
    let hex: Vec<String> = buf.iter().map(|x| format!("0x{:02X}", *x)).collect();
    let hex: String = hex.join(", ");
    assert_eq!(hex, "0xCD, 0x03, 0x49, 0x89, 0xF8, 0x49, 0x83, 0xC0, 0x01, 0x4C, 0x89, 0xC0, 0xC3", "bugreport_1");
}

// ensure RBP/RSP can be used as dynamic base register by always emitting the full SIB byte and a displacement
#[test]
fn bugreport_2() {
    let mut ops = dynasmrt::x64::Assembler::new().unwrap();
    dynasm!(ops
       ; inc [rsp]
       ; inc [Rq(4)]
       ; inc [Rq(4) + 1]
       ; inc [4 * rdx + Rq(4) + 1]
       ; inc [rbp]
       ; inc [Rq(5)]
       ; inc [Rq(5) + 1]
       ; inc [4 * rdx + Rq(5) + 1]
       ; inc [r12]
       ; inc [Rq(12)]
       ; inc [Rq(12) + 1]
       ; inc [4 * rdx + Rq(12) + 1]
       ; inc [r13]
       ; inc [Rq(13)]
       ; inc [Rq(13) + 1]
       ; inc [4 * rdx + Rq(13) + 1]
       ; inc [rcx]
       ; inc [Rq(1)]
       ; inc [Rq(1) + 1]
       ; inc [4 * rdx + Rq(1) + 1]
    );
    let buf = ops.finalize().unwrap();
    let hex: Vec<String> = buf.iter().map(|x| format!("0x{:02X}", *x)).collect();
    let hex: String = hex.join(", ");
    assert_eq!(hex, "0xFE, 0x04, 0x24, 0x40, 0xFE, 0x44, 0x24, 0x00, 0x40, 0xFE, 0x44, 0x24, 0x01, 0x40, 0xFE, 0x44, 0x94, 0x01, 0xFE, 0x45, 0x00, 0x40, 0xFE, 0x44, 0x25, 0x00, 0x40, 0xFE, 0x44, 0x25, 0x01, 0x40, 0xFE, 0x44, 0x95, 0x01, 0x41, 0xFE, 0x04, 0x24, 0x41, 0xFE, 0x44, 0x24, 0x00, 0x41, 0xFE, 0x44, 0x24, 0x01, 0x41, 0xFE, 0x44, 0x94, 0x01, 0x41, 0xFE, 0x45, 0x00, 0x41, 0xFE, 0x44, 0x25, 0x00, 0x41, 0xFE, 0x44, 0x25, 0x01, 0x41, 0xFE, 0x44, 0x95, 0x01, 0xFE, 0x01, 0x40, 0xFE, 0x44, 0x21, 0x00, 0x40, 0xFE, 0x44, 0x21, 0x01, 0x40, 0xFE, 0x44, 0x91, 0x01", "bugreport_2");
}

// ensure dynamic registers work correctly with VEX ops
#[test]
fn bugreport_3() {
    let mut ops = dynasmrt::x64::Assembler::new().unwrap();
    dynasm!(ops
       ; vaddsd Rx(1), Rx(2), Rx(3)
       ; vaddsd Rx(10), Rx(9), Rx(11)
    );
    let buf = ops.finalize().unwrap();
    let hex: Vec<String> = buf.iter().map(|x| format!("0x{:02X}", *x)).collect();
    let hex: String = hex.join(", ");
    assert_eq!(hex, "0xC4, 0xE1, 0x6B, 0x58, 0xCB, 0xC4, 0x41, 0x33, 0x58, 0xD3", "bugreport_3");
}
<commit_msg>That also goes for bug reports<commit_after>#![feature(proc_macro_hygiene)]
#![allow(unused_imports)]

extern crate dynasmrt;
extern crate dynasm;

use dynasm::dynasm;
use dynasmrt::DynasmApi;

// basic dynamic register usage
#[test]
fn bugreport_1() {
    let mut ops = dynasmrt::x64::Assembler::new().unwrap();
    dynasm!(ops
       ; .arch x64
       ; int 3
       ; mov Rq(8), rdi
       ; add Rq(8), 1
       ; mov rax, Rq(8)
       ; ret
    );
    let buf = ops.finalize().unwrap();
    let hex: Vec<String> = buf.iter().map(|x| format!("0x{:02X}", *x)).collect();
    let hex: String = hex.join(", ");
    assert_eq!(hex, "0xCD, 0x03, 0x49, 0x89, 0xF8, 0x49, 0x83, 0xC0, 0x01, 0x4C, 0x89, 0xC0, 0xC3", "bugreport_1");
}

// ensure RBP/RSP can be used as dynamic base register by always emitting the full SIB byte and a displacement
#[test]
fn bugreport_2() {
    let mut ops = dynasmrt::x64::Assembler::new().unwrap();
    dynasm!(ops
       ; .arch x64
       ; inc [rsp]
       ; inc [Rq(4)]
       ; inc [Rq(4) + 1]
       ; inc [4 * rdx + Rq(4) + 1]
       ; inc [rbp]
       ; inc [Rq(5)]
       ; inc [Rq(5) + 1]
       ; inc [4 * rdx + Rq(5) + 1]
       ; inc [r12]
       ; inc [Rq(12)]
       ; inc [Rq(12) + 1]
       ; inc [4 * rdx + Rq(12) + 1]
       ; inc [r13]
       ; inc [Rq(13)]
       ; inc [Rq(13) + 1]
       ; inc [4 * rdx + Rq(13) + 1]
       ; inc [rcx]
       ; inc [Rq(1)]
       ; inc [Rq(1) + 1]
       ; inc [4 * rdx + Rq(1) + 1]
    );
    let buf = ops.finalize().unwrap();
    let hex: Vec<String> = buf.iter().map(|x| format!("0x{:02X}", *x)).collect();
    let hex: String = hex.join(", ");
    assert_eq!(hex, "0xFE, 0x04, 0x24, 0x40, 0xFE, 0x44, 0x24, 0x00, 0x40, 0xFE, 0x44, 0x24, 0x01, 0x40, 0xFE, 0x44, 0x94, 0x01, 0xFE, 0x45, 0x00, 0x40, 0xFE, 0x44, 0x25, 0x00, 0x40, 0xFE, 0x44, 0x25, 0x01, 0x40, 0xFE, 0x44, 0x95, 0x01, 0x41, 0xFE, 0x04, 0x24, 0x41, 0xFE, 0x44, 0x24, 0x00, 0x41, 0xFE, 0x44, 0x24, 0x01, 0x41, 0xFE, 0x44, 0x94, 0x01, 0x41, 0xFE, 0x45, 0x00, 0x41, 0xFE, 0x44, 0x25, 0x00, 0x41, 0xFE, 0x44, 0x25, 0x01, 0x41, 0xFE, 0x44, 0x95, 0x01, 0xFE, 0x01, 0x40, 0xFE, 0x44, 0x21, 0x00, 0x40, 0xFE, 0x44, 0x21, 0x01, 0x40, 0xFE, 0x44, 0x91, 0x01", "bugreport_2");
}

// ensure dynamic registers work correctly with VEX ops
#[test]
fn bugreport_3() {
    let mut ops = dynasmrt::x64::Assembler::new().unwrap();
    dynasm!(ops
       ; .arch x64
       ; vaddsd Rx(1), Rx(2), Rx(3)
       ; vaddsd Rx(10), Rx(9), Rx(11)
    );
    let buf = ops.finalize().unwrap();
    let hex: Vec<String> = buf.iter().map(|x| format!("0x{:02X}", *x)).collect();
    let hex: String = hex.join(", ");
    assert_eq!(hex, "0xC4, 0xE1, 0x6B, 0x58, 0xCB, 0xC4, 0x41, 0x33, 0x58, 0xD3", "bugreport_3");
}
<|endoftext|>


<commit_before>use ffi;
use libc;

use std::io::Cursor;
use std::io::Read;
use std::io::Error as IoError;
use std::mem;
use std::ptr;

use AsMutLua;

use LuaRead;
use LuaError;
use PushGuard;

///
pub struct LuaFunction<L> {
    variable: L,
}

struct ReadData<R> {
    reader: R,
    buffer: [u8; 128],
    triggered_error: Option<IoError>,
}

extern "C" fn reader<R>(_: *mut ffi::lua_State,
                        data_raw: *mut libc::c_void,
                        size: *mut libc::size_t)
                        -> *const libc::c_char
    where R: Read
{
    let data: &mut ReadData<R> = unsafe { mem::transmute(data_raw) };

    if data.triggered_error.is_some() {
        unsafe { (*size) = 0 }
        return data.buffer.as_ptr() as *const libc::c_char;
    }

    match data.reader.read(&mut data.buffer) {
        Ok(len) => unsafe { (*size) = len as libc::size_t },
        Err(e) => {
            unsafe { (*size) = 0 }
            data.triggered_error = Some(e)
        }
    };

    data.buffer.as_ptr() as *const libc::c_char
}

impl<'lua, L> LuaFunction<L>
    where L: AsMutLua<'lua>
{
    /// Calls the `LuaFunction`.
    #[inline]
    pub fn call<'a, V>(&'a mut self) -> Result<V, LuaError>
        where V: LuaRead<PushGuard<&'a mut L>>
    {
        // calling pcall pops the parameters and pushes output
        let (pcall_return_value, pushed_value) = unsafe {
            // lua_pcall pops the function, so we have to make a copy of it
            ffi::lua_pushvalue(self.variable.as_mut_lua().0, -1);
            let pcall_return_value = ffi::lua_pcall(self.variable.as_mut_lua().0, 0, 1, 0);     // TODO: arguments
            let raw_lua = self.variable.as_lua();
            (pcall_return_value,
             PushGuard {
                 lua: &mut self.variable,
                 size: 1,
                 raw_lua: raw_lua,
             })
        };

        // if pcall succeeded, returning
        if pcall_return_value == 0 {
            return match LuaRead::lua_read(pushed_value) {
                Err(_) => Err(LuaError::WrongType),
                Ok(x) => Ok(x),
            };
        }

        // an error occured during execution
        if pcall_return_value == ffi::LUA_ERRMEM {
            panic!("lua_pcall returned LUA_ERRMEM");
        }

        if pcall_return_value == ffi::LUA_ERRRUN {
            let error_msg: String = LuaRead::lua_read(pushed_value)
                .ok()
                .expect("can't find error message at the top of the Lua stack");
            return Err(LuaError::ExecutionError(error_msg));
        }

        panic!("Unknown error code returned by lua_pcall: {}", pcall_return_value)
    }

    /// Builds a new `LuaFunction` from the code of a reader.
    #[inline]
    pub fn load_from_reader<R>(mut lua: L, code: R) -> Result<LuaFunction<PushGuard<L>>, LuaError>
        where R: Read
    {
        let readdata = ReadData {
            reader: code,
            buffer: unsafe { ::std::mem::uninitialized() },
            triggered_error: None,
        };

        let (load_return_value, pushed_value) = unsafe {
            let code = ffi::lua_load(lua.as_mut_lua().0,
                                     reader::<R>,
                                     mem::transmute(&readdata),
                                     b"chunk\0".as_ptr() as *const _,
                                     ptr::null());
            let raw_lua = lua.as_lua();
            (code,
             PushGuard {
                 lua: lua,
                 size: 1,
                 raw_lua: raw_lua,
             })
        };

        if readdata.triggered_error.is_some() {
            let error = readdata.triggered_error.unwrap();
            return Err(LuaError::ReadError(error));
        }

        if load_return_value == 0 {
            return Ok(LuaFunction { variable: pushed_value });
        }

        let error_msg: String = LuaRead::lua_read(pushed_value)
            .ok()
            .expect("can't find error message at the top of the Lua stack");

        if load_return_value == ffi::LUA_ERRMEM {
            panic!("LUA_ERRMEM");
        }

        if load_return_value == ffi::LUA_ERRSYNTAX {
            return Err(LuaError::SyntaxError(error_msg));
        }

        panic!("Unknown error while calling lua_load");
    }

    /// Builds a new `LuaFunction` from a raw string.
    #[inline]
    pub fn load(lua: L, code: &str) -> Result<LuaFunction<PushGuard<L>>, LuaError> {
        let reader = Cursor::new(code.as_bytes());
        LuaFunction::load_from_reader(lua, reader)
    }
}

// TODO: return Result<Ret, ExecutionError> instead
// impl<'a, 'lua, Ret: CopyRead> ::std::ops::FnMut<(), Ret> for LuaFunction<'a,'lua> {
// fn call_mut(&mut self, _: ()) -> Ret {
// self.call().unwrap()
// }
// }

impl<'lua, L> LuaRead<L> for LuaFunction<L>
    where L: AsMutLua<'lua>
{
    #[inline]
    fn lua_read_at_position(mut lua: L, index: i32) -> Result<LuaFunction<L>, L> {
        assert!(index == -1);   // FIXME:
        if unsafe { ffi::lua_isfunction(lua.as_mut_lua().0, -1) } {
            Ok(LuaFunction { variable: lua })
        } else {
            Err(lua)
        }
    }
}
<commit_msg>Add LuaCode and LuaCodeFromReader that are pushable<commit_after>use ffi;
use libc;

use std::io::Cursor;
use std::io::Read;
use std::io::Error as IoError;
use std::mem;
use std::ptr;

use AsMutLua;

use LuaRead;
use LuaError;
use Push;
use PushGuard;

pub struct LuaCode<'a>(&'a str);

impl<'lua, 'c, L> Push<L> for LuaCode<'c> where L: AsMutLua<'lua> {
    #[inline]
    fn push_to_lua(self, lua: L) -> PushGuard<L> {
        LuaCodeFromReader(Cursor::new(self.0.as_bytes())).push_to_lua(lua)
    }
}

pub struct LuaCodeFromReader<R>(R);

impl<'lua, L, R> Push<L> for LuaCodeFromReader<R>
    where L: AsMutLua<'lua>,
          R: Read
{
    #[inline]
    fn push_to_lua(self, mut lua: L) -> PushGuard<L> {
        struct ReadData<R> {
            reader: R,
            buffer: [u8; 128],
            triggered_error: Option<IoError>,
        }

        extern "C" fn reader<R>(_: *mut ffi::lua_State,
                                data_raw: *mut libc::c_void,
                                size: *mut libc::size_t)
                                -> *const libc::c_char
            where R: Read
        {
            let data: &mut ReadData<R> = unsafe { mem::transmute(data_raw) };

            if data.triggered_error.is_some() {
                unsafe { (*size) = 0 }
                return data.buffer.as_ptr() as *const libc::c_char;
            }

            match data.reader.read(&mut data.buffer) {
                Ok(len) => unsafe { (*size) = len as libc::size_t },
                Err(e) => {
                    unsafe { (*size) = 0 }
                    data.triggered_error = Some(e)
                }
            };

            data.buffer.as_ptr() as *const libc::c_char
        }

        let readdata = ReadData {
            reader: self.0,
            buffer: unsafe { ::std::mem::uninitialized() },
            triggered_error: None,
        };

        let (load_return_value, pushed_value) = unsafe {
            let code = ffi::lua_load(lua.as_mut_lua().0,
                                     reader::<R>,
                                     mem::transmute(&readdata),
                                     b"chunk\0".as_ptr() as *const _,
                                     ptr::null());
            let raw_lua = lua.as_lua();
            (code,
             PushGuard {
                 lua: lua,
                 size: 1,
                 raw_lua: raw_lua,
             })
        };

        if readdata.triggered_error.is_some() {
            let error = readdata.triggered_error.unwrap();
            panic!()    // TODO: return Err(LuaError::ReadError(error));
        }

        if load_return_value == 0 {
            return pushed_value;
        }

        let error_msg: String = LuaRead::lua_read(pushed_value)
            .ok()
            .expect("can't find error message at the top of the Lua stack");

        if load_return_value == ffi::LUA_ERRMEM {
            panic!("LUA_ERRMEM");
        }

        if load_return_value == ffi::LUA_ERRSYNTAX {
            panic!() // TODO: return Err(LuaError::SyntaxError(error_msg));
        }

        panic!("Unknown error while calling lua_load");
    }
}

///
pub struct LuaFunction<L> {
    variable: L,
}

impl<'lua, L> LuaFunction<L>
    where L: AsMutLua<'lua>
{
    /// Calls the `LuaFunction`.
    #[inline]
    pub fn call<'a, V>(&'a mut self) -> Result<V, LuaError>
        where V: LuaRead<PushGuard<&'a mut L>>
    {
        // calling pcall pops the parameters and pushes output
        let (pcall_return_value, pushed_value) = unsafe {
            // lua_pcall pops the function, so we have to make a copy of it
            ffi::lua_pushvalue(self.variable.as_mut_lua().0, -1);
            let pcall_return_value = ffi::lua_pcall(self.variable.as_mut_lua().0, 0, 1, 0);     // TODO: arguments
            let raw_lua = self.variable.as_lua();
            (pcall_return_value,
             PushGuard {
                 lua: &mut self.variable,
                 size: 1,
                 raw_lua: raw_lua,
             })
        };

        // if pcall succeeded, returning
        if pcall_return_value == 0 {
            return match LuaRead::lua_read(pushed_value) {
                Err(_) => Err(LuaError::WrongType),
                Ok(x) => Ok(x),
            };
        }

        // an error occured during execution
        if pcall_return_value == ffi::LUA_ERRMEM {
            panic!("lua_pcall returned LUA_ERRMEM");
        }

        if pcall_return_value == ffi::LUA_ERRRUN {
            let error_msg: String = LuaRead::lua_read(pushed_value)
                .ok()
                .expect("can't find error message at the top of the Lua stack");
            return Err(LuaError::ExecutionError(error_msg));
        }

        panic!("Unknown error code returned by lua_pcall: {}", pcall_return_value)
    }

    /// Builds a new `LuaFunction` from the code of a reader.
    #[inline]
    pub fn load_from_reader<R>(lua: L, code: R) -> Result<LuaFunction<PushGuard<L>>, LuaError>
        where R: Read
    {
        let pushed = LuaCodeFromReader(code).push_to_lua(lua);
        Ok(LuaFunction { variable: pushed })
    }

    /// Builds a new `LuaFunction` from a raw string.
    #[inline]
    pub fn load(lua: L, code: &str) -> Result<LuaFunction<PushGuard<L>>, LuaError> {
        let reader = Cursor::new(code.as_bytes());
        LuaFunction::load_from_reader(lua, reader)
    }
}

// TODO: return Result<Ret, ExecutionError> instead
// impl<'a, 'lua, Ret: CopyRead> ::std::ops::FnMut<(), Ret> for LuaFunction<'a,'lua> {
// fn call_mut(&mut self, _: ()) -> Ret {
// self.call().unwrap()
// }
// }

impl<'lua, L> LuaRead<L> for LuaFunction<L>
    where L: AsMutLua<'lua>
{
    #[inline]
    fn lua_read_at_position(mut lua: L, index: i32) -> Result<LuaFunction<L>, L> {
        assert!(index == -1);   // FIXME:
        if unsafe { ffi::lua_isfunction(lua.as_mut_lua().0, -1) } {
            Ok(LuaFunction { variable: lua })
        } else {
            Err(lua)
        }
    }
}
<|endoftext|>


<commit_before>#![allow(non_snake_case)]
extern crate graphene;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;

use graphene::implementations::adjacency_list::*;
use graphene::graph::*;

//Helper functions
fn create_adjListGraph(vertices: Vec<usize>) -> Option<AdjListGraph<usize>>{
	let v_count  = vertices.len();

	//Create all edges
	let mut edges = Vec::new();
	for i in 0..v_count{
		edges.push((i, vertices[i]%v_count));
	}

	//Create graph
	AdjListGraph::new(vertices, edges)
}

//Property functions
fn created_adjListGraph_has_correct_vertex_count(vertices: Vec<usize>) -> bool{
	let v_count = vertices.len();

	match create_adjListGraph(vertices){
		Some(g) => {
			g.vertex_count() == v_count
		}
		None => false,
	}
}

fn create_adjListGraph_has_correct_edge_count(vertices: Vec<usize>) -> bool{
	let v_count = vertices.len();

	match create_adjListGraph(vertices){
		Some(g) => {
			g.edge_count() == v_count
		}
		None => false,
	}
}

//Test runners
quickcheck!{
	fn prop_created_adjListGraph_has_correct_vertex_count(vertices: Vec<usize>) -> bool{
		create_adjListGraph_has_correct_vertex_count(vertices)
	}

	fn prop_created_adjListGraph_has_correct_edge_count(vertices: Vec<usize>) -> bool{
		created_adjListGraph_has_correct_vertex_count(vertices)
	}
}<commit_msg>Created ArbitraryGraphDescription. Implemented quickcheck.Arbitrary for ArbitraryGraphDescription. Reimplemented AdjListGraph tests.<commit_after>#![allow(non_snake_case)]
extern crate graphene;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;

use graphene::implementations::adjacency_list::*;
use graphene::graph::*;
use quickcheck::{Arbitrary,Gen};

#[derive(Clone,Debug)]
struct ArbitraryGraphDescription<V> where V: Arbitrary{
	pub vertex_values: Vec<V>,
	pub edges: Vec<(usize,usize)>,
}

impl Arbitrary for ArbitraryGraphDescription<u32>{
	fn arbitrary<G: Gen>(g: &mut G) -> Self {
		let MAX_VALUES = 10;
		let mut vertex_values = Vec::new();
		let mut edges = Vec::new();
		//Decide the amount of vertices
		let vertex_count = g.gen_range(0,MAX_VALUES);

		if vertex_count > 0 {
			//Decide the amount of edges
			let edge_count = g.gen_range(0, MAX_VALUES);

			//Create vertex values
			let mut next_value = g.gen_range(0, MAX_VALUES);
			for _ in 0..vertex_count {
				//Make sure the values are unique
				while vertex_values.contains(&next_value) {
					next_value = g.gen_range(0, MAX_VALUES);
				}
				vertex_values.push(next_value);
			}

			//Create edges

			let mut t_source;
			let mut t_sink;
			for _ in 0..edge_count {
				t_source = g.next_u32() % vertex_count;
				t_sink = g.next_u32() % vertex_count;

				edges.push((t_source as usize, t_sink as usize))
			}
		}
		ArbitraryGraphDescription{vertex_values, edges}
	}

	fn shrink(&self) -> Box<Iterator<Item=Self>> {

		//Base case
		if self.vertex_values.len() == 0 {
			return Box::new(Vec::new().into_iter());
		}

		let mut result = Vec::new();

		//Shrink by reducing a vertex value
		let mut new_values;
		for (i,&val) in self.vertex_values.iter().enumerate(){
			if val > 0 {
				new_values = self.vertex_values.clone();
				new_values[i] = val - 1;
				result.push(ArbitraryGraphDescription { vertex_values: new_values, edges: self.edges.clone() });
			}
		}

		//Shrink by removing an edge
		let mut new_edges;
		for (i, _ ) in self.edges.iter().enumerate(){
			new_edges = self.edges.clone();
			new_edges.remove(i);
			result.push(ArbitraryGraphDescription {
				vertex_values: self.vertex_values.clone(),
				edges: new_edges });
		}

		let mut t_edge;
		//Shrink by removing a vertex (v)
		for (i,_) in self.vertex_values.iter().enumerate(){
			new_values = self.vertex_values.clone();
			new_edges = Vec::new();

			//For all edges
			for &e in self.edges.iter(){
				//Remove any pointing to or from v
				if e.0 != i && e.1 != i {
					t_edge = e;

					//Any pointing to or from the last edge
					//now point to v
					if e.0 == self.vertex_values.len() {
						t_edge.0 = i;
					}
					if e.1 == self.vertex_values.len() {
						t_edge.1 = i;
					}
					new_edges.push(t_edge);
				}
			}

			//Replace v with the last vertex
			new_values.swap_remove(i);

			result.push(ArbitraryGraphDescription{vertex_values: new_values, edges: new_edges});
		}

		Box::new(result.into_iter())
	}
}
/*
quickcheck! {
	fn test_arbitrary_graph(Ag: ArbitraryGraphDescription<u32>) -> bool{
		println!("Original: {:?}", Ag);

		for a in Ag.shrink(){
			println!("Shrunk: {:?}", a);
		}
		true
	}
}
*/
//Helper functions
fn create_adjListGraph(vertices: Vec<usize>) -> Option<AdjListGraph<usize>>{
	let v_count  = vertices.len();

	//Create all edges
	let mut edges = Vec::new();
	for i in 0..v_count{
		edges.push((i, vertices[i]%v_count));
	}

	//Create graph
	AdjListGraph::new(vertices, edges)
}

//Property functions
fn created_adjListGraph_has_correct_vertex_count(g: ArbitraryGraphDescription<u32>) -> bool{
	let v_count = g.vertex_values.len();

	match AdjListGraph::new(g.vertex_values, g.edges){
		Some(g) => {
			g.vertex_count() == v_count
		}
		None => false,
	}
}

fn created_adjListGraph_has_correct_edge_count(g: ArbitraryGraphDescription<u32>) -> bool{
	let e_count = g.edges.len();

	match AdjListGraph::new(g.vertex_values, g.edges){
		Some(g) => {
			g.edge_count() == e_count
		}
		None => false,
	}
}

//Test runners
quickcheck!{

	fn prop_created_adjListGraph_has_correct_vertex_count(g: ArbitraryGraphDescription<u32>) -> bool{
		created_adjListGraph_has_correct_vertex_count(g)
	}

	fn prop_created_adjListGraph_has_correct_edge_count(g: ArbitraryGraphDescription<u32>) -> bool{
		created_adjListGraph_has_correct_edge_count(g)
	}
}<|endoftext|>


<commit_before>/* kernel::sgash.rs */
#[allow(unused_imports)];
use core::*;
use core::str::*;
use core::option::{Some, Option, None};
use core::mem::volatile_store;
use core::iter::Iterator;
use kernel::*;
use kernel::cstr::cstr;
use super::super::platform::*;
use super::super::platform::cpu::uart;
use kernel::memory::Allocator;

static PROMPT: &'static str = &"sgash> ";
static UNRECOGNIZED: &'static str = &"Err: Unrecognized command\n";
static PROMPT_COLOR: u32 = 0xFFAF00;
static mut count: uint = 0;

static mut buffer: cstr = cstr {
    p: 0 as *mut u8,
    p_cstr_i: 0,
    size: 0,
};

/* Thanks to https://github.com/jvns/puddle/blob/master/src/stdio.rs */
pub fn putnum(x: uint, max: uint) {
    let mut i = max;
    if i == 0 {
        i = 1000000;
    }
    while(i > 0) {
        // Get the offset from each decimal point up to a certain value
        putchar(((((x / i) % 10) as u8) + ('0' as u8)) as char);
        i /= 10;
    }
    putchar(' ');
}

pub fn putkeycode(x: u8) {
    putnum(x as uint, 100);
}

pub fn putchar(key: char) {
    unsafe {
        volatile_store(uart::UART0_DR, key);
    }
}

pub unsafe fn showstr(msg: &str) {
    putstr(msg);
    drawstr(msg);
}

pub fn putstr(msg: &str) {
    for c in slice::iter(as_bytes(msg)) {
        putchar(*c as char);
    }
}

pub unsafe fn drawstr(msg: &str) {
    for c in slice::iter(as_bytes(msg)) {
        drawchar(*c as char);
    }
}

unsafe fn drawchar(x: char) {
    io::restore();
    if ((x as u8) as uint) == 10 || x == '\n' {
        io::CURSOR_Y += io::CURSOR_HEIGHT;
        io::CURSOR_X = 0u32;
    } else {
        if (((x as u8) as uint) >= 32 && ((x as u8) as uint) <= 125) {
            io::draw_char(x);
            io::CURSOR_X += io::CURSOR_WIDTH;
        }
    }
    io::backup();
    io::draw_cursor();
}

unsafe fn backspace() {
    io::restore();
    if (io::CURSOR_X >= io::CURSOR_WIDTH) {
        io::CURSOR_X -= io::CURSOR_WIDTH;
        io::draw_char(' ');
    }
    io::backup();
    io::draw_cursor();
}

pub unsafe fn parsekey(x: char) {
    let x = x as u8;
    // Set this to false to learn the keycodes of various keys!
    // Key codes are printed backwards because life is hard

    match x {
        13 =>  {
            parse_buffer();
            prompt();
            buffer.reset();
        }
        127 =>  {
            putchar('');
            putchar(' ');
            putchar('');
            buffer.delete_char();
            backspace();
        }
        _ =>  {
            if io::CURSOR_X < io::SCREEN_WIDTH-io::CURSOR_WIDTH {
                putchar(x as char);
                drawchar(x as char);
                buffer.add_u8(x);
            }
        }
    }
}

pub unsafe fn from_keyboard(x: u8) {
    match kbd::parse_kmi_key(x) {
        Some(y) => parsekey(y as char),
        None    => ()
    }
}

pub unsafe fn parse_buffer() {
    showstr(&"\n");
    buffer.map(putchar);
    buffer.map(drawchar);
    showstr(&"\n");
    let (command, args) = buffer.split(' ');
    if command.streq(&"echo") {
        args.map(drawchar);
        args.map(putchar);
        showstr(&"\n");
    }
    else if command.streq(&"cat") { }
    else if command.streq(&"cd") { }
    else if command.streq(&"rm") { }
    else if command.streq(&"ls") { }
    else if command.streq(&"mkdir") { }
    else if command.streq(&"pwd") { }
    else if command.streq(&"wr") { }
    else {
        showstr(UNRECOGNIZED);
    }
    command.destroy();
    args.destroy();
}

pub unsafe fn screen() {
    putstr(&"\n                                                               ");
    putstr(&"\n                                                               ");
    putstr(&"\n                       7=..~$=..:7                             ");
    putstr(&"\n                  +$: =$$$+$$$?$$$+ ,7?                        ");
    putstr(&"\n                  $$$$$$$$$$$$$$$$$$Z$$                        ");
    putstr(&"\n              7$$$$$$$$$$$$. .Z$$$$$Z$$$$$$                    ");
    putstr(&"\n           ~..7$$Z$$$$$7+7$+.?Z7=7$$Z$$Z$$$..:                 ");
    putstr(&"\n          ~$$$$$$$$7:     :ZZZ,     :7ZZZZ$$$$=                ");
    putstr(&"\n           Z$$$$$?                    .+ZZZZ$$                 ");
    putstr(&"\n       +$ZZ$$$Z7                         7ZZZ$Z$$I.            ");
    putstr(&"\n        $$$$ZZZZZZZZZZZZZZZZZZZZZZZZI,    ,ZZZ$$Z              ");
    putstr(&"\n      :+$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZ=    $ZZ$$+~,           ");
    putstr(&"\n     ?$Z$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZZI   7ZZZ$ZZI           ");
    putstr(&"\n      =Z$$+7Z$$7ZZZZZZZZ$$$$$$$ZZZZZZZZZZ  ~Z$?$ZZ?            ");
    putstr(&"\n    :$Z$Z...$Z  $ZZZZZZZ~       ~ZZZZZZZZ,.ZZ...Z$Z$~          ");
    putstr(&"\n    7ZZZZZI$ZZ  $ZZZZZZZ~       =ZZZZZZZ7..ZZ$?$ZZZZ$          ");
    putstr(&"\n      ZZZZ$:    $ZZZZZZZZZZZZZZZZZZZZZZ=     ~$ZZZ$:           ");
    putstr(&"\n    7Z$ZZ$,     $ZZZZZZZZZZZZZZZZZZZZ7         ZZZ$Z$          ");
    putstr(&"\n   =ZZZZZZ,     $ZZZZZZZZZZZZZZZZZZZZZZ,       ZZZ$ZZ+         ");
    putstr(&"\n     ,ZZZZ,     $ZZZZZZZ:     =ZZZZZZZZZ     ZZZZZ$:           ");
    putstr(&"\n    =$ZZZZ+     ZZZZZZZZ~       ZZZZZZZZ~   =ZZZZZZZI          ");
    putstr(&"\n    $ZZ$ZZZ$$Z$$ZZZZZZZZZ$$$$   IZZZZZZZZZ$ZZZZZZZZZ$          ");
    putstr(&"\n      :ZZZZZZZZZZZZZZZZZZZZZZ   ~ZZZZZZZZZZZZZZZZZ~            ");
    putstr(&"\n     ,Z$$ZZZZZZZZZZZZZZZZZZZZ    ZZZZZZZZZZZZZZZZZZ~           ");
    putstr(&"\n     =$ZZZZZZZZZZZZZZZZZZZZZZ     $ZZZZZZZZZZZZZZZ$+           ");
    putstr(&"\n        IZZZZZ:.                        . ,ZZZZZ$              ");
    putstr(&"\n       ~$ZZZZZZZZZZZ                 ZZZZ$ZZZZZZZ+             ");
    putstr(&"\n           Z$ZZZ. ,Z~               =Z:.,ZZZ$Z                 ");
    putstr(&"\n          ,ZZZZZ..~Z$.             .7Z:..ZZZZZ:                ");
    putstr(&"\n          ~7+:$ZZZZZZZZI=:.   .,=IZZZZZZZ$Z:=7=                ");
    putstr(&"\n              $$ZZZZZZZZZZZZZZZZZZZZZZ$ZZZZ                    ");
    putstr(&"\n              ==..$ZZZ$ZZZZZZZZZZZ$ZZZZ .~+                    ");
    putstr(&"\n                  I$?.?ZZZ$ZZZ$ZZZI =$7                        ");
    putstr(&"\n                       $7..I$7..I$,                            ");
    putstr(&"\n");
    putstr(&"\n _                     _     _                         _  ");
    putstr(&"\n| |                   (_)   | |                       | | ");
    putstr(&"\n| | ____ ___  ____     _____| |_____  ____ ____  _____| | ");
    putstr(&"\n| |/ ___) _ \\|  _ \\   |  _   _) ___ |/ ___)  _ \\| ___ | | ");
    putstr(&"\n| | |  | |_| | | | |  | |  \\ \\| ____| |   | | | | ____| | ");
    putstr(&"\n|_|_|  \\____/|_| |_|  |_|   \\_\\_____)_|   |_| |_|_____)__)\n\n");
}

pub unsafe fn init() {
    buffer = cstr::new();
    screen();
    prompt();
}

pub unsafe fn prompt() {
    putstr(PROMPT);
    let prev_c = super::super::io::FG_COLOR;
    super::super::io::set_fg(PROMPT_COLOR);
    drawstr(PROMPT);
    super::super::io::set_fg(prev_c);
}

<commit_msg>Support backspace in sgash<commit_after>/* kernel::sgash.rs */
#[allow(unused_imports)];
use core::*;
use core::str::*;
use core::option::{Some, Option, None};
use core::mem::volatile_store;
use core::iter::Iterator;
use kernel::*;
use kernel::cstr::cstr;
use super::super::platform::*;
use super::super::platform::cpu::uart;
use kernel::memory::Allocator;

static PROMPT: &'static str = &"sgash> ";
static UNRECOGNIZED: &'static str = &"Err: Unrecognized command\n";
static PROMPT_COLOR: u32 = 0xFFAF00;
static mut count: uint = 0;

static mut buffer: cstr = cstr {
    p: 0 as *mut u8,
    p_cstr_i: 0,
    size: 0,
};

/* Thanks to https://github.com/jvns/puddle/blob/master/src/stdio.rs */
pub fn putnum(x: uint, max: uint) {
    let mut i = max;
    if i == 0 {
        i = 1000000;
    }
    while(i > 0) {
        // Get the offset from each decimal point up to a certain value
        putchar(((((x / i) % 10) as u8) + ('0' as u8)) as char);
        i /= 10;
    }
    putchar(' ');
}

pub fn putkeycode(x: u8) {
    putnum(x as uint, 100);
}

pub fn putchar(key: char) {
    unsafe {
        volatile_store(uart::UART0_DR, key);
    }
}

pub unsafe fn showstr(msg: &str) {
    putstr(msg);
    drawstr(msg);
}

pub fn putstr(msg: &str) {
    for c in slice::iter(as_bytes(msg)) {
        putchar(*c as char);
    }
}

pub unsafe fn drawstr(msg: &str) {
    for c in slice::iter(as_bytes(msg)) {
        drawchar(*c as char);
    }
}

unsafe fn drawchar(x: char) {
    io::restore();
    if ((x as u8) as uint) == 10 || x == '\n' {
        io::CURSOR_Y += io::CURSOR_HEIGHT;
        io::CURSOR_X = 0u32;
    } else {
        if (((x as u8) as uint) >= 32 && ((x as u8) as uint) <= 125) {
            io::draw_char(x);
            io::CURSOR_X += io::CURSOR_WIDTH;
        }
    }
    io::backup();
    io::draw_cursor();
}

unsafe fn backspace() {
    io::restore();
    if (io::CURSOR_X >= io::CURSOR_WIDTH) {
        io::CURSOR_X -= io::CURSOR_WIDTH;
        io::draw_char(' ');
    }
    io::backup();
    io::draw_cursor();
}

pub unsafe fn parsekey(x: char) {
    let x = x as u8;
    // Set this to false to learn the keycodes of various keys!
    // Key codes are printed backwards because life is hard

    match x {
        13 =>  {
            parse_buffer();
            prompt();
            buffer.reset();
        }
        8 | 127 =>  {
            putchar('');
            putchar(' ');
            putchar('');
            buffer.delete_char();
            backspace();
        }
        _ =>  {
            if io::CURSOR_X < io::SCREEN_WIDTH-io::CURSOR_WIDTH {
                putchar(x as char);
                drawchar(x as char);
                buffer.add_u8(x);
            }
        }
    }
}

pub unsafe fn from_keyboard(x: u8) {
    match kbd::parse_kmi_key(x) {
        Some(y) => parsekey(y as char),
        None    => ()
    }
}

pub unsafe fn parse_buffer() {
    showstr(&"\n");
    buffer.map(putchar);
    buffer.map(drawchar);
    showstr(&"\n");
    let (command, args) = buffer.split(' ');
    if command.streq(&"echo") {
        args.map(drawchar);
        args.map(putchar);
        showstr(&"\n");
    }
    else if command.streq(&"cat") { }
    else if command.streq(&"cd") { }
    else if command.streq(&"rm") { }
    else if command.streq(&"ls") { }
    else if command.streq(&"mkdir") { }
    else if command.streq(&"pwd") { }
    else if command.streq(&"wr") { }
    else {
        showstr(UNRECOGNIZED);
    }
    command.destroy();
    args.destroy();
}

pub unsafe fn screen() {
    putstr(&"\n                                                               ");
    putstr(&"\n                                                               ");
    putstr(&"\n                       7=..~$=..:7                             ");
    putstr(&"\n                  +$: =$$$+$$$?$$$+ ,7?                        ");
    putstr(&"\n                  $$$$$$$$$$$$$$$$$$Z$$                        ");
    putstr(&"\n              7$$$$$$$$$$$$. .Z$$$$$Z$$$$$$                    ");
    putstr(&"\n           ~..7$$Z$$$$$7+7$+.?Z7=7$$Z$$Z$$$..:                 ");
    putstr(&"\n          ~$$$$$$$$7:     :ZZZ,     :7ZZZZ$$$$=                ");
    putstr(&"\n           Z$$$$$?                    .+ZZZZ$$                 ");
    putstr(&"\n       +$ZZ$$$Z7                         7ZZZ$Z$$I.            ");
    putstr(&"\n        $$$$ZZZZZZZZZZZZZZZZZZZZZZZZI,    ,ZZZ$$Z              ");
    putstr(&"\n      :+$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZ=    $ZZ$$+~,           ");
    putstr(&"\n     ?$Z$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZZI   7ZZZ$ZZI           ");
    putstr(&"\n      =Z$$+7Z$$7ZZZZZZZZ$$$$$$$ZZZZZZZZZZ  ~Z$?$ZZ?            ");
    putstr(&"\n    :$Z$Z...$Z  $ZZZZZZZ~       ~ZZZZZZZZ,.ZZ...Z$Z$~          ");
    putstr(&"\n    7ZZZZZI$ZZ  $ZZZZZZZ~       =ZZZZZZZ7..ZZ$?$ZZZZ$          ");
    putstr(&"\n      ZZZZ$:    $ZZZZZZZZZZZZZZZZZZZZZZ=     ~$ZZZ$:           ");
    putstr(&"\n    7Z$ZZ$,     $ZZZZZZZZZZZZZZZZZZZZ7         ZZZ$Z$          ");
    putstr(&"\n   =ZZZZZZ,     $ZZZZZZZZZZZZZZZZZZZZZZ,       ZZZ$ZZ+         ");
    putstr(&"\n     ,ZZZZ,     $ZZZZZZZ:     =ZZZZZZZZZ     ZZZZZ$:           ");
    putstr(&"\n    =$ZZZZ+     ZZZZZZZZ~       ZZZZZZZZ~   =ZZZZZZZI          ");
    putstr(&"\n    $ZZ$ZZZ$$Z$$ZZZZZZZZZ$$$$   IZZZZZZZZZ$ZZZZZZZZZ$          ");
    putstr(&"\n      :ZZZZZZZZZZZZZZZZZZZZZZ   ~ZZZZZZZZZZZZZZZZZ~            ");
    putstr(&"\n     ,Z$$ZZZZZZZZZZZZZZZZZZZZ    ZZZZZZZZZZZZZZZZZZ~           ");
    putstr(&"\n     =$ZZZZZZZZZZZZZZZZZZZZZZ     $ZZZZZZZZZZZZZZZ$+           ");
    putstr(&"\n        IZZZZZ:.                        . ,ZZZZZ$              ");
    putstr(&"\n       ~$ZZZZZZZZZZZ                 ZZZZ$ZZZZZZZ+             ");
    putstr(&"\n           Z$ZZZ. ,Z~               =Z:.,ZZZ$Z                 ");
    putstr(&"\n          ,ZZZZZ..~Z$.             .7Z:..ZZZZZ:                ");
    putstr(&"\n          ~7+:$ZZZZZZZZI=:.   .,=IZZZZZZZ$Z:=7=                ");
    putstr(&"\n              $$ZZZZZZZZZZZZZZZZZZZZZZ$ZZZZ                    ");
    putstr(&"\n              ==..$ZZZ$ZZZZZZZZZZZ$ZZZZ .~+                    ");
    putstr(&"\n                  I$?.?ZZZ$ZZZ$ZZZI =$7                        ");
    putstr(&"\n                       $7..I$7..I$,                            ");
    putstr(&"\n");
    putstr(&"\n _                     _     _                         _  ");
    putstr(&"\n| |                   (_)   | |                       | | ");
    putstr(&"\n| | ____ ___  ____     _____| |_____  ____ ____  _____| | ");
    putstr(&"\n| |/ ___) _ \\|  _ \\   |  _   _) ___ |/ ___)  _ \\| ___ | | ");
    putstr(&"\n| | |  | |_| | | | |  | |  \\ \\| ____| |   | | | | ____| | ");
    putstr(&"\n|_|_|  \\____/|_| |_|  |_|   \\_\\_____)_|   |_| |_|_____)__)\n\n");
}

pub unsafe fn init() {
    buffer = cstr::new();
    screen();
    prompt();
}

pub unsafe fn prompt() {
    putstr(PROMPT);
    let prev_c = super::super::io::FG_COLOR;
    super::super::io::set_fg(PROMPT_COLOR);
    drawstr(PROMPT);
    super::super::io::set_fg(prev_c);
}

<|endoftext|>


<commit_before>// automatically generated by rust-bindgen
use libc::size_t;
#[link(name = "R")]
extern {
    pub fn vmaxget() -> *mut ::libc::c_void;
    pub fn vmaxset(arg1: *const ::libc::c_void) -> ();
    pub fn R_gc() -> ();
    pub fn R_gc_running() -> ::libc::c_int;
    pub fn R_alloc(arg1: size_t, arg2: ::libc::c_int) -> *mut ::libc::c_char;
    pub fn S_alloc(arg1: ::libc::c_long, arg2: ::libc::c_int) -> *mut ::libc::c_char;
    pub fn S_realloc(arg1: *mut ::libc::c_char,
                     arg2: ::libc::c_long,
                     arg3: ::libc::c_long,
                     arg4: ::libc::c_int)
                     -> *mut ::libc::c_char;
}
<commit_msg>Add R_allocLD in ext/memory for R 3.2<commit_after>// automatically generated by rust-bindgen
use libc::size_t;

#[link(name = "R")]
extern {
    pub fn vmaxget() -> *mut ::libc::c_void;
    pub fn vmaxset(arg1: *const ::libc::c_void) -> ();
    pub fn R_gc() -> ();
    pub fn R_gc_running() -> ::libc::c_int;
    pub fn R_alloc(arg1: size_t, arg2: ::libc::c_int) -> *mut ::libc::c_char;
    pub fn R_allocLD(nelem: size_t) -> *mut ::libc::c_double;
    pub fn S_alloc(arg1: ::libc::c_long, arg2: ::libc::c_int) -> *mut ::libc::c_char;
    pub fn S_realloc(arg1: *mut ::libc::c_char,
                     arg2: ::libc::c_long,
                     arg3: ::libc::c_long,
                     arg4: ::libc::c_int)
                     -> *mut ::libc::c_char;
}
<|endoftext|>


<commit_before>use std::io::{Read, Cursor, Seek, SeekFrom, Write};
use blockchain::{block::*, index::*};
use std::collections::HashMap;
use std::cell::RefCell;
use std::path::Path;
use std::sync::Arc;
use std::fs::File;
use crc32c::*;

pub struct BlockStore {
    indexer: Arc<Indexer>,

    height: u64,
    blocks: HashMap<u64, Arc<SignedBlock>>,
    genesis_block: Option<Arc<SignedBlock>>,

    file: RefCell<File>,
    byte_pos_tail: u64
}

impl BlockStore {

    pub fn new(path: &Path, indexer: Arc<Indexer>) -> BlockStore {
        let (file, tail) = if !path.is_file() {
            (File::create(path).unwrap(), 0u64)
        } else {
            let f = File::open(path).unwrap();
            let m = f.metadata().unwrap();
            (File::open(path).unwrap(), m.len())
        };

        let height = indexer.get_chain_height();
        let mut store = BlockStore {
            indexer,

            height,
            blocks: HashMap::new(),
            genesis_block: None,

            file: RefCell::new(file),
            byte_pos_tail: tail
        };
        store.genesis_block = store.get(0);

        { // Initialize the cache
            let min = if height <= 100 { height } else { height - 100 };
            let max = min + 100;
            for height in min..max {
                if let Some(block) = store.get_from_disk(height) {
                    store.blocks.insert(height, Arc::new(block));
                } else {
                    break;
                }
            }
        }

        store
    }

    #[inline(always)]
    pub fn get_chain_height(&self) -> u64 {
        self.height
    }

    pub fn get(&self, height: u64) -> Option<Arc<SignedBlock>> {
        if height > self.height {
            return None
        } else if height == 0 {
            if let Some(ref block) = self.genesis_block {
                return Some(Arc::clone(block))
            }
        }
        if let Some(block) = self.blocks.get(&height) {
            Some(Arc::clone(block))
        } else {
            Some(Arc::new(self.get_from_disk(height)?))
        }
    }

    fn get_from_disk(&self, height: u64) -> Option<SignedBlock> {
        if height > self.height { return None }

        let pos = self.indexer.get_block_byte_pos(height)?;
        let mut f = self.file.borrow_mut();
        f.seek(SeekFrom::Start(pos)).unwrap();

        let (block_len, crc) = {
            let mut meta = [0u8; 8];
            f.read_exact(&mut meta).unwrap();
            let len = u32_from_buf!(meta, 0) as usize;
            let crc = u32_from_buf!(meta, 4);
            (len, crc)
        };

        let block_vec = {
            let mut buf = Vec::with_capacity(block_len);
            unsafe { buf.set_len(block_len); }
            f.read_exact(&mut buf).unwrap();
            assert_eq!(crc, crc32c(&buf));
            buf
        };

        let mut cursor = Cursor::<&[u8]>::new(&block_vec);
        let block = SignedBlock::decode_with_tx(&mut cursor).unwrap();
        Some(block)
    }

    pub fn insert(&mut self, block: SignedBlock) {
        assert_eq!(self.height + 1, block.height, "invalid block height");
        self.insert_raw(block);
    }

    pub fn insert_genesis(&mut self, block: SignedBlock) {
        assert_eq!(block.height, 0, "expected to be 0");
        assert!(self.genesis_block.is_none(), "expected genesis block to not exist");
        self.insert_raw(block.clone());
        self.genesis_block = Some(Arc::new(block));
    }

    fn insert_raw(&mut self, block: SignedBlock) {
        { // Write to disk
            let vec = &mut Vec::with_capacity(1048576);
            block.encode_with_tx(vec);
            let len = vec.len() as u32;
            let crc = crc32c(vec);

            let mut f = self.file.borrow_mut();
            {
                let mut buf = [0u8; 8];
                buf[0] = (len >> 24) as u8;
                buf[1] = (len >> 16) as u8;
                buf[2] = (len >> 8) as u8;
                buf[3] = len as u8;

                buf[4] = (crc >> 24) as u8;
                buf[5] = (crc >> 16) as u8;
                buf[6] = (crc >> 8) as u8;
                buf[7] = crc as u8;

                f.write_all(&buf).unwrap();
            }

            f.write_all(vec).unwrap();
            f.flush().unwrap();

            self.byte_pos_tail += (len as u64) + 8;
        }

        { // Update internal cache
            let height = block.height;
            self.height = height;
            let opt = self.blocks.insert(height, Arc::new(block));
            if self.blocks.len() > 100 {
                let b = self.blocks.remove(&(height - 100));
                debug_assert!(b.is_some(), "nothing removed from cache");
            }
            debug_assert!(opt.is_none(), "block already in the chain");
        }
    }
}
<commit_msg>Use open options to open block log<commit_after>use std::io::{Read, Cursor, Seek, SeekFrom, Write};
use std::fs::{OpenOptions, File};
use std::collections::HashMap;
use std::cell::RefCell;
use std::path::Path;
use std::sync::Arc;
use crc32c::*;

use blockchain::{block::*, index::*};

pub struct BlockStore {
    indexer: Arc<Indexer>,

    height: u64,
    blocks: HashMap<u64, Arc<SignedBlock>>,
    genesis_block: Option<Arc<SignedBlock>>,

    file: RefCell<File>,
    byte_pos_tail: u64
}

impl BlockStore {

    pub fn new(path: &Path, indexer: Arc<Indexer>) -> BlockStore {
        let (file, tail) = {
            let f = OpenOptions::new()
                                .create(true)
                                .read(true)
                                .append(true)
                                .open(path).unwrap();
            let m = f.metadata().unwrap();
            (f, m.len())
        };

        let height = indexer.get_chain_height();
        let mut store = BlockStore {
            indexer,

            height,
            blocks: HashMap::new(),
            genesis_block: None,

            file: RefCell::new(file),
            byte_pos_tail: tail
        };
        store.genesis_block = store.get(0);

        { // Initialize the cache
            let min = if height <= 100 { height } else { height - 100 };
            let max = min + 100;
            for height in min..max {
                if let Some(block) = store.get_from_disk(height) {
                    store.blocks.insert(height, Arc::new(block));
                } else {
                    break;
                }
            }
        }

        store
    }

    #[inline(always)]
    pub fn get_chain_height(&self) -> u64 {
        self.height
    }

    pub fn get(&self, height: u64) -> Option<Arc<SignedBlock>> {
        if height > self.height {
            return None
        } else if height == 0 {
            if let Some(ref block) = self.genesis_block {
                return Some(Arc::clone(block))
            }
        }
        if let Some(block) = self.blocks.get(&height) {
            Some(Arc::clone(block))
        } else {
            Some(Arc::new(self.get_from_disk(height)?))
        }
    }

    fn get_from_disk(&self, height: u64) -> Option<SignedBlock> {
        if height > self.height { return None }

        let pos = self.indexer.get_block_byte_pos(height)?;
        let mut f = self.file.borrow_mut();
        f.seek(SeekFrom::Start(pos)).unwrap();

        let (block_len, crc) = {
            let mut meta = [0u8; 8];
            f.read_exact(&mut meta).unwrap();
            let len = u32_from_buf!(meta, 0) as usize;
            let crc = u32_from_buf!(meta, 4);
            (len, crc)
        };

        let block_vec = {
            let mut buf = Vec::with_capacity(block_len);
            unsafe { buf.set_len(block_len); }
            f.read_exact(&mut buf).unwrap();
            assert_eq!(crc, crc32c(&buf));
            buf
        };

        let mut cursor = Cursor::<&[u8]>::new(&block_vec);
        let block = SignedBlock::decode_with_tx(&mut cursor).unwrap();
        Some(block)
    }

    pub fn insert(&mut self, block: SignedBlock) {
        assert_eq!(self.height + 1, block.height, "invalid block height");
        self.insert_raw(block);
    }

    pub fn insert_genesis(&mut self, block: SignedBlock) {
        assert_eq!(block.height, 0, "expected to be 0");
        assert!(self.genesis_block.is_none(), "expected genesis block to not exist");
        self.insert_raw(block.clone());
        self.genesis_block = Some(Arc::new(block));
    }

    fn insert_raw(&mut self, block: SignedBlock) {
        { // Write to disk
            let vec = &mut Vec::with_capacity(1048576);
            block.encode_with_tx(vec);
            let len = vec.len() as u32;
            let crc = crc32c(vec);

            let mut f = self.file.borrow_mut();
            {
                let mut buf = [0u8; 8];
                buf[0] = (len >> 24) as u8;
                buf[1] = (len >> 16) as u8;
                buf[2] = (len >> 8) as u8;
                buf[3] = len as u8;

                buf[4] = (crc >> 24) as u8;
                buf[5] = (crc >> 16) as u8;
                buf[6] = (crc >> 8) as u8;
                buf[7] = crc as u8;

                f.write_all(&buf).unwrap();
            }

            f.write_all(vec).unwrap();
            f.flush().unwrap();

            self.byte_pos_tail += (len as u64) + 8;
        }

        { // Update internal cache
            let height = block.height;
            self.height = height;
            let opt = self.blocks.insert(height, Arc::new(block));
            if self.blocks.len() > 100 {
                let b = self.blocks.remove(&(height - 100));
                debug_assert!(b.is_some(), "nothing removed from cache");
            }
            debug_assert!(opt.is_none(), "block already in the chain");
        }
    }
}
<|endoftext|>


<commit_before>use crate::HashStableContext;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::AtomicRef;
use rustc_index::vec::Idx;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decoder, Encoder};
use std::borrow::Borrow;
use std::fmt;

rustc_index::newtype_index! {
    pub struct CrateId {
        ENCODABLE = custom
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CrateNum {
    /// A special `CrateNum` that we use for the `tcx.rcache` when decoding from
    /// the incr. comp. cache.
    ReservedForIncrCompCache,
    Index(CrateId),
}

/// Item definitions in the currently-compiled crate would have the `CrateNum`
/// `LOCAL_CRATE` in their `DefId`.
pub const LOCAL_CRATE: CrateNum = CrateNum::Index(CrateId::from_u32(0));

impl Idx for CrateNum {
    #[inline]
    fn new(value: usize) -> Self {
        CrateNum::Index(Idx::new(value))
    }

    #[inline]
    fn index(self) -> usize {
        match self {
            CrateNum::Index(idx) => Idx::index(idx),
            _ => panic!("Tried to get crate index of {:?}", self),
        }
    }
}

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        CrateNum::from_usize(x)
    }

    pub fn from_usize(x: usize) -> CrateNum {
        CrateNum::Index(CrateId::from_usize(x))
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum::Index(CrateId::from_u32(x))
    }

    pub fn as_usize(self) -> usize {
        match self {
            CrateNum::Index(id) => id.as_usize(),
            _ => panic!("tried to get index of non-standard crate {:?}", self),
        }
    }

    pub fn as_u32(self) -> u32 {
        match self {
            CrateNum::Index(id) => id.as_u32(),
            _ => panic!("tried to get index of non-standard crate {:?}", self),
        }
    }

    pub fn as_def_id(&self) -> DefId {
        DefId { krate: *self, index: CRATE_DEF_INDEX }
    }
}

impl fmt::Display for CrateNum {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
            CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
        }
    }
}

/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
/// Therefore, make sure to include the context when encode a `CrateNum`.
impl rustc_serialize::UseSpecializedEncodable for CrateNum {
    fn default_encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
        e.emit_u32(self.as_u32())
    }
}
impl rustc_serialize::UseSpecializedDecodable for CrateNum {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
        Ok(CrateNum::from_u32(d.read_u32()?))
    }
}

impl ::std::fmt::Debug for CrateNum {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
            CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
        }
    }
}

#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable_Generic)]
pub struct DefPathHash(pub Fingerprint);

impl Borrow<Fingerprint> for DefPathHash {
    #[inline]
    fn borrow(&self) -> &Fingerprint {
        &self.0
    }
}

rustc_index::newtype_index! {
    /// A DefIndex is an index into the hir-map for a crate, identifying a
    /// particular definition. It should really be considered an interned
    /// shorthand for a particular DefPath.
    pub struct DefIndex {
        DEBUG_FORMAT = "DefIndex({})",

        /// The crate root is always assigned index 0 by the AST Map code,
        /// thanks to `NodeCollector::new`.
        const CRATE_DEF_INDEX = 0,
    }
}

impl rustc_serialize::UseSpecializedEncodable for DefIndex {}
impl rustc_serialize::UseSpecializedDecodable for DefIndex {}

/// A `DefId` identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl DefId {
    /// Makes a local `DefId` from the given `DefIndex`.
    #[inline]
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index }
    }

    #[inline]
    pub fn is_local(self) -> bool {
        self.krate == LOCAL_CRATE
    }

    #[inline]
    pub fn as_local(self) -> Option<LocalDefId> {
        if self.is_local() { Some(LocalDefId { local_def_index: self.index }) } else { None }
    }

    #[inline]
    pub fn expect_local(self) -> LocalDefId {
        self.as_local().unwrap_or_else(|| panic!("DefId::expect_local: `{:?}` isn't local", self))
    }

    pub fn is_top_level_module(self) -> bool {
        self.is_local() && self.index == CRATE_DEF_INDEX
    }
}

impl rustc_serialize::UseSpecializedEncodable for DefId {
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        let krate = u64::from(self.krate.as_u32());
        let index = u64::from(self.index.as_u32());
        s.emit_u64((krate << 32) | index)
    }
}
impl rustc_serialize::UseSpecializedDecodable for DefId {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<DefId, D::Error> {
        let def_id = d.read_u64()?;
        let krate = CrateNum::from_u32((def_id >> 32) as u32);
        let index = DefIndex::from_u32((def_id & 0xffffffff) as u32);
        Ok(DefId { krate, index })
    }
}

pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
}

pub static DEF_ID_DEBUG: AtomicRef<fn(DefId, &mut fmt::Formatter<'_>) -> fmt::Result> =
    AtomicRef::new(&(default_def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        (*DEF_ID_DEBUG)(*self, f)
    }
}

rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefId);

/// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since
/// we encode this information in the type, we can ensure at compile time that
/// no DefIds from upstream crates get thrown into the mix. There are quite a
/// few cases where we know that only DefIds from the local crate are expected
/// and a DefId from a different crate would signify a bug somewhere. This
/// is when LocalDefId comes in handy.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LocalDefId {
    pub local_def_index: DefIndex,
}

impl Idx for LocalDefId {
    #[inline]
    fn new(idx: usize) -> Self {
        LocalDefId { local_def_index: Idx::new(idx) }
    }
    #[inline]
    fn index(self) -> usize {
        self.local_def_index.index()
    }
}

impl LocalDefId {
    #[inline]
    pub fn to_def_id(self) -> DefId {
        DefId { krate: LOCAL_CRATE, index: self.local_def_index }
    }

    #[inline]
    pub fn is_top_level_module(self) -> bool {
        self.local_def_index == CRATE_DEF_INDEX
    }
}

impl fmt::Debug for LocalDefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.to_def_id().fmt(f)
    }
}

impl rustc_serialize::UseSpecializedEncodable for LocalDefId {}
impl rustc_serialize::UseSpecializedDecodable for LocalDefId {}

impl<CTX: HashStableContext> HashStable<CTX> for DefId {
    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
        hcx.hash_def_id(*self, hasher)
    }
}
<commit_msg>Add comment about LocalDefId -> DefId<commit_after>use crate::HashStableContext;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::AtomicRef;
use rustc_index::vec::Idx;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decoder, Encoder};
use std::borrow::Borrow;
use std::fmt;

rustc_index::newtype_index! {
    pub struct CrateId {
        ENCODABLE = custom
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CrateNum {
    /// A special `CrateNum` that we use for the `tcx.rcache` when decoding from
    /// the incr. comp. cache.
    ReservedForIncrCompCache,
    Index(CrateId),
}

/// Item definitions in the currently-compiled crate would have the `CrateNum`
/// `LOCAL_CRATE` in their `DefId`.
pub const LOCAL_CRATE: CrateNum = CrateNum::Index(CrateId::from_u32(0));

impl Idx for CrateNum {
    #[inline]
    fn new(value: usize) -> Self {
        CrateNum::Index(Idx::new(value))
    }

    #[inline]
    fn index(self) -> usize {
        match self {
            CrateNum::Index(idx) => Idx::index(idx),
            _ => panic!("Tried to get crate index of {:?}", self),
        }
    }
}

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        CrateNum::from_usize(x)
    }

    pub fn from_usize(x: usize) -> CrateNum {
        CrateNum::Index(CrateId::from_usize(x))
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum::Index(CrateId::from_u32(x))
    }

    pub fn as_usize(self) -> usize {
        match self {
            CrateNum::Index(id) => id.as_usize(),
            _ => panic!("tried to get index of non-standard crate {:?}", self),
        }
    }

    pub fn as_u32(self) -> u32 {
        match self {
            CrateNum::Index(id) => id.as_u32(),
            _ => panic!("tried to get index of non-standard crate {:?}", self),
        }
    }

    pub fn as_def_id(&self) -> DefId {
        DefId { krate: *self, index: CRATE_DEF_INDEX }
    }
}

impl fmt::Display for CrateNum {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
            CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
        }
    }
}

/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
/// Therefore, make sure to include the context when encode a `CrateNum`.
impl rustc_serialize::UseSpecializedEncodable for CrateNum {
    fn default_encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
        e.emit_u32(self.as_u32())
    }
}
impl rustc_serialize::UseSpecializedDecodable for CrateNum {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
        Ok(CrateNum::from_u32(d.read_u32()?))
    }
}

impl ::std::fmt::Debug for CrateNum {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
            CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
        }
    }
}

#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable_Generic)]
pub struct DefPathHash(pub Fingerprint);

impl Borrow<Fingerprint> for DefPathHash {
    #[inline]
    fn borrow(&self) -> &Fingerprint {
        &self.0
    }
}

rustc_index::newtype_index! {
    /// A DefIndex is an index into the hir-map for a crate, identifying a
    /// particular definition. It should really be considered an interned
    /// shorthand for a particular DefPath.
    pub struct DefIndex {
        DEBUG_FORMAT = "DefIndex({})",

        /// The crate root is always assigned index 0 by the AST Map code,
        /// thanks to `NodeCollector::new`.
        const CRATE_DEF_INDEX = 0,
    }
}

impl rustc_serialize::UseSpecializedEncodable for DefIndex {}
impl rustc_serialize::UseSpecializedDecodable for DefIndex {}

/// A `DefId` identifies a particular *definition*, by combining a crate
/// index and a def index.
///
/// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl DefId {
    /// Makes a local `DefId` from the given `DefIndex`.
    #[inline]
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index }
    }

    #[inline]
    pub fn is_local(self) -> bool {
        self.krate == LOCAL_CRATE
    }

    #[inline]
    pub fn as_local(self) -> Option<LocalDefId> {
        if self.is_local() { Some(LocalDefId { local_def_index: self.index }) } else { None }
    }

    #[inline]
    pub fn expect_local(self) -> LocalDefId {
        self.as_local().unwrap_or_else(|| panic!("DefId::expect_local: `{:?}` isn't local", self))
    }

    pub fn is_top_level_module(self) -> bool {
        self.is_local() && self.index == CRATE_DEF_INDEX
    }
}

impl rustc_serialize::UseSpecializedEncodable for DefId {
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        let krate = u64::from(self.krate.as_u32());
        let index = u64::from(self.index.as_u32());
        s.emit_u64((krate << 32) | index)
    }
}
impl rustc_serialize::UseSpecializedDecodable for DefId {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<DefId, D::Error> {
        let def_id = d.read_u64()?;
        let krate = CrateNum::from_u32((def_id >> 32) as u32);
        let index = DefIndex::from_u32((def_id & 0xffffffff) as u32);
        Ok(DefId { krate, index })
    }
}

pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
}

pub static DEF_ID_DEBUG: AtomicRef<fn(DefId, &mut fmt::Formatter<'_>) -> fmt::Result> =
    AtomicRef::new(&(default_def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        (*DEF_ID_DEBUG)(*self, f)
    }
}

rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefId);

/// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since
/// we encode this information in the type, we can ensure at compile time that
/// no DefIds from upstream crates get thrown into the mix. There are quite a
/// few cases where we know that only DefIds from the local crate are expected
/// and a DefId from a different crate would signify a bug somewhere. This
/// is when LocalDefId comes in handy.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LocalDefId {
    pub local_def_index: DefIndex,
}

impl Idx for LocalDefId {
    #[inline]
    fn new(idx: usize) -> Self {
        LocalDefId { local_def_index: Idx::new(idx) }
    }
    #[inline]
    fn index(self) -> usize {
        self.local_def_index.index()
    }
}

impl LocalDefId {
    #[inline]
    pub fn to_def_id(self) -> DefId {
        DefId { krate: LOCAL_CRATE, index: self.local_def_index }
    }

    #[inline]
    pub fn is_top_level_module(self) -> bool {
        self.local_def_index == CRATE_DEF_INDEX
    }
}

impl fmt::Debug for LocalDefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.to_def_id().fmt(f)
    }
}

impl rustc_serialize::UseSpecializedEncodable for LocalDefId {}
impl rustc_serialize::UseSpecializedDecodable for LocalDefId {}

impl<CTX: HashStableContext> HashStable<CTX> for DefId {
    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
        hcx.hash_def_id(*self, hasher)
    }
}
<|endoftext|>


<commit_before>endogenous	Y, ZGDP, ZI, ZPAI, ZY, I, PAI, R

exogenous EGDP, EI, EPAI, EY

parameters beta_lag, beta_lead, beta_r, gam_lag, gam_y, gyss, lamb_lag,
lamb_lead, lamb_y, rhogdp, rhoi, rhopai, rhoy, vol_tp_1_2, vol_tp_2_1
commit_prob

parameters(vol,2) siggdp, sigi, sigpai, sigy

model(linear)

   Y=beta_lag*Y(-1)+beta_lead*Y(+1)-beta_r*R(-1)+ZY;

   PAI=lamb_lag*PAI(-1)+lamb_lead*PAI(+1)+lamb_y*Y(-1)+ZPAI;

%   // Taylor rule
%   I=gam_lag*I(-1)+(1-gam_lag)*(PAI(+4)+gam_y*Y)+ZI;

   R=I-PAI(+1);

   ZI=rhoi*ZI(-1)+sigi*EI;

   ZPAI=rhopai*ZPAI(-1)+sigpai*EPAI;

   ZY=rhoy*ZY(-1)+sigy*EY;

   ZGDP=(1-rhogdp)*gyss+rhogdp*ZGDP(-1)+siggdp*EGDP;

planner_objective{discount = 0.99,commitment=commit_prob} -.5*(1*PAI^2+.6*Y^2);

parameterization
	gyss   			,0 	   ;
	beta_lag 	    ,0.5000;
	beta_lead		,0.4000;
	beta_r  		,0.9000;
	gam_lag 		,0.6000;
	gam_y   		,0.5000;
	lamb_lag		,0.8000;
	lamb_lead   	,0.1000;
	lamb_y  		,0.3000;
	rhogdp 			,0.5000;
	rhoi   			,0.5000;
	rhopai 			,0.5000;
	rhoy   		 	,0.5000;
    commit_prob 	,0.0000;
    vol_tp_1_2  	,0.1000;
    vol_tp_2_1     	,0.1000;
	siggdp(vol,1) 	,0.5000;
	sigi(vol,1)   	,0.5000;
	sigpai(vol,1) 	,0.5000;
	sigy(vol,1)   	,0.5000;
	siggdp(vol,2) 	,0.5000;
	sigi(vol,2)   	,0.5000;
	sigpai(vol,2) 	,0.5000;
	sigy(vol,2)   	,0.5000;

<commit_msg>update for syntax change<commit_after>endogenous	Y, ZGDP, ZI, ZPAI, ZY, I, PAI, R

exogenous EGDP, EI, EPAI, EY

parameters beta_lag, beta_lead, beta_r, gam_lag, gam_y, gyss, lamb_lag,
lamb_lead, lamb_y, rhogdp, rhoi, rhopai, rhoy, vol_tp_1_2, vol_tp_2_1
commit_prob

parameters(vol,2) siggdp, sigi, sigpai, sigy

model

   Y=beta_lag*Y(-1)+beta_lead*Y(+1)-beta_r*R(-1)+ZY;

   PAI=lamb_lag*PAI(-1)+lamb_lead*PAI(+1)+lamb_y*Y(-1)+ZPAI;

%   // Taylor rule
%   I=gam_lag*I(-1)+(1-gam_lag)*(PAI(+4)+gam_y*Y)+ZI;

   R=I-PAI(+1);

   ZI=rhoi*ZI(-1)+sigi*EI;

   ZPAI=rhopai*ZPAI(-1)+sigpai*EPAI;

   ZY=rhoy*ZY(-1)+sigy*EY;

   ZGDP=(1-rhogdp)*gyss+rhogdp*ZGDP(-1)+siggdp*EGDP;

planner_objective{discount = 0.99,commitment=commit_prob} -.5*(1*PAI^2+.6*Y^2);

parameterization
	gyss   			,0 	   ;
	beta_lag 	    ,0.5000;
	beta_lead		,0.4000;
	beta_r  		,0.9000;
	gam_lag 		,0.6000;
	gam_y   		,0.5000;
	lamb_lag		,0.8000;
	lamb_lead   	,0.1000;
	lamb_y  		,0.3000;
	rhogdp 			,0.5000;
	rhoi   			,0.5000;
	rhopai 			,0.5000;
	rhoy   		 	,0.5000;
    commit_prob 	,0.0000;
    vol_tp_1_2  	,0.1000;
    vol_tp_2_1     	,0.1000;
	siggdp(vol,1) 	,0.5000;
	sigi(vol,1)   	,0.5000;
	sigpai(vol,1) 	,0.5000;
	sigy(vol,1)   	,0.5000;
	siggdp(vol,2) 	,0.5000;
	sigi(vol,2)   	,0.5000;
	sigpai(vol,2) 	,0.5000;
	sigy(vol,2)   	,0.5000;

<|endoftext|>