<commit_before><commit_msg>Implemented simple_diffusion for new API (but it sometimes panics)<commit_after>// In this example, we're going to make a simple diffusion simulation:
// a two-dimensional grid of cells, each containing some amount of ink.
// Ink diffuses from cells with more ink the cells with less ink.

// All field data types must implement serde::Serialize and serde::Deserialize,
// so we include the features for deriving them.
extern crate serde;
#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate time_steward;

// Imports for the UI
#[macro_use]
extern crate glium;
extern crate docopt;
#[path = "../dev-shared/emscripten_compatibility.rs"] mod emscripten_compatibility;
pub use emscripten_compatibility::canvas_click;

macro_rules! printlnerr(
    ($($arg:tt)*) => { {use std::io::Write;
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

use std::cmp::{min, max};
use time_steward::{DeterministicRandomId};
use time_steward::rowless::api::{self, StewardData, QueryOffset, TypedDataTimelineHandleTrait, ExtendedTime, Basics as BasicsTrait};
use time_steward::rowless::stewards::{simple_flat as steward_module};
use steward_module::{TimeSteward, ConstructibleTimeSteward, IncrementalTimeSteward, Event, DataTimelineHandle, PredictionHandle, Accessor, MomentaryAccessor, EventAccessor, UndoEventAccessor, SnapshotAccessor, simple_timeline};
use simple_timeline::{SimpleTimeline, ConstantTimeline, GetConstant, GetVarying, tracking_query, modify_simple_timeline, unmodify_simple_timeline};

/// i64 makes a good time type:
/// It's big enough to subdivide down to the nanosecond, allowing a smooth simulation,
/// while still representing any reasonable amount of time the simulation could take.
type Time = i64;
const SECOND: Time = 1i64 << 20;

type Steward = steward_module::Steward <Basics>;

/// A type defining simulation constants.
/// This obviously isn't needed for compile-time constants, which can be done normally,
/// but it's useful for things like game settings or commandline parameters.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct Globals {
  size: [i32; 2],

  /// Maximum inaccuracy of transfers in ink-per-time-unit
  max_inaccuracy: i64,

  cells: Vec<CellHandle>,
}
impl StewardData for Globals {}

// Derive all the traits required for field data types.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct Cell {
  coordinates: [i32; 2],

  /// The exact amount of ink present in this cell at the last time we updated it.
  ink_at_last_change: i64,

  /// The rate at which this cell is currently transferring ink to other cells.
  ///
  /// The mathematically accurate transfer function between just 2 cells would be
  /// exponential decay, but it would be quickly complicated by other cells anyway.
  /// Instead, we use a linear approximation, and just update it whenever
  /// it becomes too inaccurate.
  ///
  /// The values here represent the transfer TOWARDS the cells in the POSITIVE
  /// x and y directions. Transfers from the cells in the negative x and y directions
  /// are stored in the data of *those* cells.
  ink_transfers: [i64; 2],

  next_transfer_change: Option <PredictionHandle <TransferChange>>,
}
impl StewardData for Cell {}
type CellHandle = DataTimelineHandle <SimpleTimeline <(), Cell, Basics>>;

fn update_transfer_change_prediction <A: EventAccessor <Steward = Steward>> (accessor: &mut A, globals: & Globals, coordinates: [i32; 2]) {
  if !in_bounds (globals, coordinates) {return;}
  let (my_last_change, mut me) = query_cell (accessor, globals, coordinates).unwrap();
  let my_accumulation_rate: i64 = get_accumulation_rate (accessor, globals, coordinates);

  if let Some (discarded) = me.next_transfer_change.take() {
    accessor.destroy_prediction (&discarded);
  }

  let mut best = None;

  for dimension in 0..2 {
    // This update is only in charge of the transfers to the cells
    // in the positive x and y directions. The other transfers will be handled by
    // the updates for the cells in the negative x and y directions.
    let mut neighbor_coordinates = coordinates;
    neighbor_coordinates [dimension] += 1;
    if neighbor_coordinates [dimension] >= globals.size [dimension] {continue;}
    let neighbor_accumulation_rate = get_accumulation_rate (accessor, globals, neighbor_coordinates);
    let (neighbor_last_change, neighbor) = query_cell (accessor, globals, neighbor_coordinates).unwrap();

    let last_change = max (my_last_change, neighbor_last_change);
    let current_difference =
      (me.ink_at_last_change + my_accumulation_rate*(last_change - my_last_change)) -
      (neighbor.ink_at_last_change + neighbor_accumulation_rate*(last_change - neighbor_last_change));
    let current_difference_change_rate = my_accumulation_rate - neighbor_accumulation_rate;
    let current_transfer_rate = me.ink_transfers [dimension];

    // We choose the target transfer rate to be the amount that would
    // equalize the two cells in one second.
    // That is, the target transfer rate is (my ink - other ink)/(SECOND*2).
    //
    // We need to notice when the target transfer rate goes outside of the range
    // [current transfer rate - maximum inaccuracy, current transfer rate + maximum inaccuracy].
    // After a little algebra...
    let (min_difference, max_difference) = (
      (current_transfer_rate - globals.max_inaccuracy)*(2*SECOND),
      (current_transfer_rate + globals.max_inaccuracy)*(2*SECOND)
    );
    if current_difference < min_difference || current_difference > max_difference {
      printlnerr!( "predict wow! {:?} ! {:?}", me, neighbor);
      best = Some((last_change, dimension));
    }
    else if current_difference_change_rate > 0 {
      //printlnerr!( "predict {}/{}",max_difference-current_difference, current_difference_change_rate);
      let time = last_change + min (SECOND/4, (max_difference-current_difference)/current_difference_change_rate);
      if best.map_or (true, | previous | time <previous.0) {best = Some((time, dimension));}
    }
    else if current_difference_change_rate < 0 {
      //printlnerr!( "predict {}/{}",min_difference-current_difference, current_difference_change_rate);
      let time = last_change + min (SECOND/4, (min_difference-current_difference)/current_difference_change_rate);
      if best.map_or (true, | previous | time <previous.0) {best = Some((time, dimension));}
    }
  }

  let now = accessor.extended_now().clone();

  me.next_transfer_change = best.map (|(time, dimension) | {
    assert!(time >= now.base) ;
    accessor.create_prediction (
        time,
        DeterministicRandomId::new (&(now.id, coordinates)),
        TransferChange {coordinates: coordinates, dimension: dimension}
      )
  });

  modify_cell (accessor, globals, coordinates, me) ;
}

/// A utility function used above. Gets the current rate of change of ink in a cell,
/// by summing up the current transfer rates.
///
/// Since this function doesn't make predictions, it only needs to require trait Accessor,
/// which is a supertrait of EventAccessor. Thus, it could also be used in Events,
/// and with Snapshots, if needed.
fn get_accumulation_rate <A: Accessor <Steward = Steward >> (accessor: &A, globals: & Globals, coordinates: [i32; 2])->i64 {
  let mut result = 0;
  let me: Cell = query_cell (accessor, globals, coordinates).unwrap().1;
  for dimension in 0..2 {
    result -= me.ink_transfers [dimension];

    let mut neighbor_coordinates = coordinates;
    neighbor_coordinates [dimension] -= 1;

    // Adjacent cells might NOT exist (they could be out of bounds).
    // We could also have just done a bounds check on the coordinates, like above.
    if let Some (neighbor) = query_cell (accessor, globals, neighbor_coordinates) {
      result += neighbor.1.ink_transfers [dimension];
    }
  }
  result
}

fn cell_index (globals: & Globals, coordinates: [i32; 2])->usize {
  (coordinates [0]*globals.size[0] + coordinates [1]) as usize
}
fn in_bounds (globals: & Globals, coordinates: [i32; 2])->bool {
  coordinates [0] >= 0 && coordinates [0] < globals.size [0] &&
  coordinates [1] >= 0 && coordinates [1] < globals.size [1]
}
fn query_cell <A: Accessor <Steward = Steward >> (accessor: &A, globals: & Globals, coordinates: [i32; 2])->Option <(Time, Cell)> {
  if in_bounds (globals, coordinates) {
    let result = accessor.query (& globals.cells[cell_index (globals, coordinates)], & GetVarying, QueryOffset::After).expect ("cells should never not exist");
    Some((result.0.base, result.1))
  }
  else { None }
}
fn modify_cell <A: EventAccessor <Steward = Steward >> (accessor: &A, globals: & Globals, coordinates: [i32; 2], value: Cell) {
  modify_simple_timeline (accessor, & globals.cells [cell_index (globals, coordinates)], Some(value));
}

/// The TransferChange event, as used above.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct TransferChange {coordinates: [i32; 2], dimension: usize}
impl StewardData for TransferChange {}
impl Event for TransferChange {
  type Steward = Steward;
  type ExecutionData = ();
  fn execute <Accessor: EventAccessor <Steward = Self::Steward>> (&self, accessor: &mut Accessor) {
    let globals = accessor.query (accessor.global_timeline(), & GetConstant, QueryOffset::After);
    let (my_last_change, mut me) = query_cell (accessor, & globals, self.coordinates).unwrap();
    let mut neighbor_coordinates = self.coordinates;
    neighbor_coordinates [self.dimension] += 1;
    let (neighbor_last_change, mut neighbor) = query_cell (accessor, & globals, neighbor_coordinates).unwrap();

    let my_current_ink = me.ink_at_last_change + get_accumulation_rate (accessor, & globals, self.coordinates)*(accessor.now() - my_last_change);
    let neighbor_current_ink = neighbor.ink_at_last_change + get_accumulation_rate (accessor, & globals, neighbor_coordinates)*(accessor.now() - neighbor_last_change);
    let current_difference = my_current_ink - neighbor_current_ink;

    me.ink_at_last_change = my_current_ink;
    neighbor.ink_at_last_change = neighbor_current_ink;
    me.ink_transfers [self.dimension] = current_difference/(2*SECOND);

    modify_cell (accessor, &globals, self.coordinates, me) ;
    modify_cell (accessor, &globals, neighbor_coordinates, neighbor) ;

    // TODO: some of the ones at the corners don't need to be updated
    for offsx in -1.. (if self.dimension == 0 {2} else {1}) {
      for offsy in -1.. (if self.dimension == 1 {2} else {1}) {
        let coordinates = [self.coordinates [0] + offsx, self.coordinates [1] + offsy];
        update_transfer_change_prediction (accessor, & globals, coordinates) ;
      }
    }

    // TODO: invalidation
  }

  fn undo <Accessor: UndoEventAccessor <Steward = Self::Steward>> (&self, accessor: &mut Accessor, _: ()) {
    unimplemented!()
  }
}

/// In order to get the simulation going, we need two more events:
/// One to be the FiatEvent that initializes the cells to an initial empty state,
/// and one to be the FiatEvent that adds or removes ink in some way at real-time.
///
/// For these simple events, we lazily use the pseudo-closure syntax.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct Initialize {}
impl StewardData for Initialize {}
impl Event for Initialize {
  type Steward = Steward;
  type ExecutionData = ();
  fn execute <Accessor: EventAccessor <Steward = Self::Steward>> (&self, accessor: &mut Accessor) {
    let globals = accessor.query (accessor.global_timeline(), & GetConstant, QueryOffset::After);
    for x in 0..globals.size [0] {
      for y in 0..globals.size [1] {
        modify_cell (accessor, &globals, [x,y], Cell {
          coordinates: [x, y],
          ink_at_last_change: 0,
          ink_transfers: [0, 0],
          next_transfer_change: None,
        });
      }
    }
  }
  fn undo <Accessor: UndoEventAccessor <Steward = Self::Steward>> (&self, accessor: &mut Accessor, _: ()) {
    unimplemented!()
  }
}
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct AddInk {coordinates: [i32; 2], amount: i64}
impl StewardData for AddInk {}
impl Event for AddInk {
  type Steward = Steward;
  type ExecutionData = ();
  fn execute <Accessor: EventAccessor <Steward = Self::Steward>> (&self, accessor: &mut Accessor) {
    let globals = accessor.query (accessor.global_timeline(), & GetConstant, QueryOffset::After);
    let (my_last_change, mut me) = query_cell (accessor, & globals, self.coordinates).unwrap();
    let my_current_ink = me.ink_at_last_change + get_accumulation_rate (accessor, & globals, self.coordinates)*(accessor.now() - my_last_change);
    me.ink_at_last_change = my_current_ink + self.amount;
    modify_cell (accessor, & globals, self.coordinates, me) ;
    // TODO: some of the ones at the corners don't need to be updated
    for offsx in -1..1 {
      for offsy in -1..1 {
        let coordinates = [self.coordinates [0] + offsx, self.coordinates [1] + offsy];
        update_transfer_change_prediction (accessor, & globals, coordinates) ;
      }
    }
  }
  fn undo <Accessor: UndoEventAccessor <Steward = Self::Steward>> (&self, accessor: &mut Accessor, _: ()) {
    unimplemented!()
  }
}

fn make_global_timeline()-> <Basics as BasicsTrait>::GlobalTimeline {
  <Basics as BasicsTrait>::GlobalTimeline::new ({
    let mut cells = Vec::new();
    for index in 0..60*60 {
      cells.push (DataTimelineHandle::new (SimpleTimeline::new (())));
    }
    Globals {
      size: [60, 60],
      max_inaccuracy: 100_00,
      cells: cells,
    }
  })
}

/// Finally, define the Basics type.
#[derive (Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug, Default)]
struct Basics {}
impl BasicsTrait for Basics {
  type Time = Time;
  type GlobalTimeline = ConstantTimeline <Globals, Basics>;
}

// User interface details.
use docopt::Docopt;

const USAGE: &'static str = "
Simple diffusion, a TimeSteward usage example.

Usage:
  simple_diffusion
  simple_diffusion (-l | --listen) <host> <port>
  simple_diffusion (-c | --connect) <host> <port>

Options:
  -l, --listen   Start a synchronized simulation by listening for TCP connections.
  -c, --connect  Start a synchronized simulation by making a TCP connection.
";

#[derive(Debug, Deserialize)]
struct Args {
  flag_listen: bool,
  flag_connect: bool,

  arg_host: Option <String>,
  arg_port: Option <u16>,
}

use std::time::{Instant, Duration};
use glium::{DisplayBuild, Surface};

#[derive(Copy, Clone)]
struct Vertex {
  location: [f32; 2],
  ink: f32,
}
implement_vertex!(Vertex, location, ink);

use std::net::{TcpListener, TcpStream};
use std::io::{BufReader, BufWriter};

fn main() {
  let global_timeline = make_global_timeline();

  // For some reason, docopt checking the arguments caused build_glium() to fail in emscripten.
  /*if !cfg!(target_os = "emscripten") {
    let arguments: Args = Docopt::new(USAGE)
                            .and_then(|d| d.deserialize())
                            .unwrap_or_else(|e| e.exit());

    if arguments.flag_listen {
      let listener = TcpListener::bind ((arguments.arg_host.as_ref().map_or("localhost", | string | string as & str), arguments.arg_port.unwrap())).unwrap();
      let stream = listener.accept().unwrap().0;
      let mut steward: simply_synchronized::Steward<Basics, DefaultSteward <Basics>> = simply_synchronized::Steward::new(DeterministicRandomId::new (& 0u32), 0, SECOND>>3, constants, BufReader::new (stream.try_clone().unwrap()), BufWriter::new (stream));
      steward.insert_fiat_event(0, DeterministicRandomId::new(&0), Initialize::new()).unwrap();
      run (steward, |a,b| (a.settle_before (b)));
      return;
    }
    else if arguments.flag_connect {
      let stream = TcpStream::connect ((arguments.arg_host.as_ref().map_or("localhost", | string | string as & str), arguments.arg_port.unwrap())).unwrap();
      let steward: simply_synchronized::Steward<Basics, DefaultSteward <Basics>> = simply_synchronized::Steward::new(DeterministicRandomId::new (& 1u32), 0, SECOND>>3, constants, BufReader::new (stream.try_clone().unwrap()), BufWriter::new (stream));
      run (steward, |a,b| (a.settle_before (b)));
      return;
    }
  }*/
  {
    let mut steward: Steward = Steward::from_global_timeline(global_timeline);
    steward.insert_fiat_event(0, DeterministicRandomId::new(&0), Initialize{}).unwrap();
    run (steward, |_,_|());
  }
}

fn run <F: Fn (&mut Steward, Time)>(mut stew: Steward, settle:F) {

  let vertex_shader_source = r#"
#version 100
attribute lowp vec2 location;
attribute lowp float ink;
varying lowp float ink_transfer;

void main() {
gl_Position = vec4 (location, 0.0, 1.0);
ink_transfer = ink;
}

"#;

  let fragment_shader_source = r#"
#version 100
varying lowp float ink_transfer;

void main() {
gl_FragColor = vec4 (vec3(0.5 - ink_transfer/100000000000.0), 1.0);
}

"#;

  let mut event_index = 0u64;
  let mut mouse_coordinates = [0,0];

  let display = glium::glutin::WindowBuilder::new()
    .with_dimensions(600, 600)
    .build_glium()
    .expect("failed to create window");
  let program =
    glium::Program::from_source(&display, vertex_shader_source, fragment_shader_source, None)
      .expect("glium program generation failed");
  let parameters = glium::DrawParameters {
    blend: glium::draw_parameters::Blend::alpha_blending(),
    ..Default::default()
  };
  let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

  // take care of the expensive predictions before starting the timer
  stew.snapshot_before(&1);
  let start = Instant::now();

  let frame = || {
    let frame_begin = Instant::now();
    let time = 1 + ((start.elapsed().as_secs() as i64 * 1000000000i64) +
                          start.elapsed().subsec_nanos() as i64) *
                         SECOND / 1000000000i64;
    for ev in display.poll_events() {
      match ev {
        glium::glutin::Event::Closed => return true,
        glium::glutin::Event::MouseMoved (x,y) => {
          mouse_coordinates [0] = (x as i32) * 60 / display.get_window().unwrap().get_inner_size_pixels().unwrap().0 as i32;
          mouse_coordinates [1] = (display.get_window().unwrap().get_inner_size_pixels().unwrap().1 as i32-(y as i32)) * 60 / display.get_window().unwrap().get_inner_size_pixels().unwrap().1 as i32;
        },
        glium::glutin::Event::MouseInput (_,_) => {
          event_index += 1;
          stew.insert_fiat_event (time, DeterministicRandomId::new (& event_index), AddInk {
            coordinates: [mouse_coordinates [0], mouse_coordinates [1]],
            amount: (DeterministicRandomId::new (& event_index).data() [0] & ((1u64<<40)-1)) as i64 - (1<<39)
          }).unwrap();
        },
        _ => (),
      }
    }
    while let Some ((x,y)) = emscripten_compatibility::pop_click() {
      // TODO duplicate code
      mouse_coordinates [0] = (x*60.0) as i32;
      mouse_coordinates [1] = ((1.0-y)*60.0) as i32;
      event_index += 1;
      stew.insert_fiat_event (time, DeterministicRandomId::new (& event_index), AddInk {
            coordinates: [mouse_coordinates [0], mouse_coordinates [1]],
            amount: (DeterministicRandomId::new (& event_index).data() [0] & ((1u64<<40)-1)) as i64 - (1<<39)
          }).unwrap();
    }

    let mut target = display.draw();
    target.clear_color(1.0, 1.0, 1.0, 1.0);
    let mut vertices = Vec::<Vertex>::new();

    let accessor = stew.snapshot_before(& time)
      .expect("steward failed to provide snapshot");
    stew.forget_before (& time);
    settle (&mut stew, time);
    let globals = accessor.query (accessor.global_timeline(), & GetConstant, QueryOffset::After);

    for x in 0.. globals.size [0] {
      for y in 0.. globals.size [1] {
        let (my_last_change, me) = query_cell (& accessor, & globals, [x,y]).unwrap();
        let my_current_ink = (me.ink_at_last_change + get_accumulation_rate (& accessor, & globals, me.coordinates)*(accessor.now() - my_last_change)) as f32;

        vertices.extend(&[Vertex {
                            location: [((x) as f32)/30.0 -1.0,((y) as f32)/30.0 -1.0],
                            ink: my_current_ink,
                          },
                          Vertex {
                            location: [((x + 1) as f32)/30.0 -1.0,((y) as f32)/30.0 -1.0],
                            ink: my_current_ink,
                          },
                          Vertex {
                            location: [((x) as f32)/30.0 -1.0,((y + 1) as f32)/30.0 -1.0],
                            ink: my_current_ink,
                          },
                          Vertex {
                            location: [((x + 1) as f32)/30.0 -1.0,((y + 1) as f32)/30.0 -1.0],
                            ink: my_current_ink,
                          },
                          Vertex {
                            location: [((x + 1) as f32)/30.0 -1.0,((y) as f32)/30.0 -1.0],
                            ink: my_current_ink,
                          },
                          Vertex {
                            location: [((x) as f32)/30.0 -1.0,((y + 1) as f32)/30.0 -1.0],
                            ink: my_current_ink,
                          }]);

      }
    }

    target.draw(&glium::VertexBuffer::new(&display, &vertices)
                .expect("failed to generate glium Vertex buffer"),
              &indices,
              &program,
              &glium::uniforms::EmptyUniforms,
              &parameters)
        .expect("failed target.draw");

    target.finish().expect("failed to finish drawing");

    /*while frame_begin.elapsed() < Duration::from_millis (10) && stew.updated_until_before().map_or (false, | limitation | limitation < time + SECOND) {
        for _ in 0..8 {stew.step();}
    }*/
    false
  };

  emscripten_compatibility::main_loop(frame);
}
<|endoftext|>


<commit_before><commit_msg>Add file descriptor type<commit_after>/// A file descriptor type
pub type Fd = usize;
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------
// Preserve(Ex, S) holds if ToAddr(Ex) will remain valid for the entirety of
// the scope S.
export public_methods;

impl public_methods for borrowck_ctxt {
    fn preserve(cmt: cmt, opt_scope_id: option<ast::node_id>) -> bckres<()> {
        #debug["preserve(%s)", self.cmt_to_repr(cmt)];
        let _i = indenter();

        alt cmt.cat {
          cat_rvalue | cat_special(_) {
            ok(())
          }
          cat_stack_upvar(cmt) {
            self.preserve(cmt, opt_scope_id)
          }
          cat_local(_) {
            // Normally, local variables are lendable, and so this
            // case should never trigged.  However, if we are
            // preserving an expression like a.b where the field `b`
            // has @ type, then it will recurse to ensure that the `a`
            // is stable to try and avoid rooting the value `a.b`.  In
            // this case, opt_scope_id will be none.
            if opt_scope_id.is_some() {
                self.tcx.sess.span_bug(
                    cmt.span,
                    "preserve() called with local and non-none opt_scope_id");
            }
            ok(())
          }
          cat_arg(_) {
            // This can happen as not all args are lendable (e.g., &&
            // modes).  In that case, the caller guarantees stability.
            // This is basically a deref of a region ptr.
            ok(())
          }
          cat_comp(cmt_base, comp_field(*)) |
          cat_comp(cmt_base, comp_index(*)) |
          cat_comp(cmt_base, comp_tuple) |
          cat_comp(cmt_base, comp_res) {
            // Most embedded components: if the base is stable, the
            // type never changes.
            self.preserve(cmt_base, opt_scope_id)
          }
          cat_comp(cmt_base, comp_variant(enum_did)) {
            if ty::enum_is_univariant(self.tcx, enum_did) {
                self.preserve(cmt_base, opt_scope_id)
            } else {
                // If there are multiple variants: overwriting the
                // base could cause the type of this memory to change,
                // so require imm.
                self.require_imm(cmt, cmt_base, opt_scope_id, err_mut_variant)
            }
          }
          cat_deref(cmt_base, _, uniq_ptr) {
            // Overwriting the base could cause this memory to be
            // freed, so require imm.
            self.require_imm(cmt, cmt_base, opt_scope_id, err_mut_uniq)
          }
          cat_deref(_, _, region_ptr) {
            // References are always "stable" by induction (when the
            // reference of type &MT was created, the memory must have
            // been stable)
            ok(())
          }
          cat_deref(_, _, unsafe_ptr) {
            // Unsafe pointers are the user's problem
            ok(())
          }
          cat_deref(base, derefs, gc_ptr) {
            // GC'd pointers of type @MT: if this pointer lives in
            // immutable, stable memory, then everything is fine.  But
            // otherwise we have no guarantee the pointer will stay
            // live, so we must root the pointer (i.e., inc the ref
            // count) for the duration of the loan.
            if base.mutbl == m_imm {
                alt self.preserve(base, none) {
                  ok(()) {ok(())}
                  err(_) {self.attempt_root(cmt, opt_scope_id, base, derefs)}
                }
            } else {
                self.attempt_root(cmt, opt_scope_id, base, derefs)
            }
          }
          cat_discr(base, alt_id) {
            // Subtle: in an alt, we must ensure that each binding
            // variable remains valid for the duration of the arm in
            // which it appears, presuming that this arm is taken.
            // But it is inconvenient in trans to root something just
            // for one arm.  Therefore, we insert a cat_discr(),
            // basically a special kind of category that says "if this
            // value must be dynamically rooted, root it for the scope
            // `alt_id`.
            //
            // As an example, consider this scenario:
            //
            //    let mut x = @some(3);
            //    alt *x { some(y) {...} none {...} }
            //
            // Technically, the value `x` need only be rooted
            // in the `some` arm.  However, we evaluate `x` in trans
            // before we know what arm will be taken, so we just
            // always root it for the duration of the alt.
            //
            // As a second example, consider *this* scenario:
            //
            //    let x = @mut @some(3);
            //    alt x { @@some(y) {...} @@none {...} }
            //
            // Here again, `x` need only be rooted in the `some` arm.
            // In this case, the value which needs to be rooted is
            // found only when checking which pattern matches: but
            // this check is done before entering the arm.  Therefore,
            // even in this case we just choose to keep the value
            // rooted for the entire alt.  This means the value will be
            // rooted even if the none arm is taken.  Oh well.
            //
            // At first, I tried to optimize the second case to only
            // root in one arm, but the result was suboptimal: first,
            // it interfered with the construction of phi nodes in the
            // arm, as we were adding code to root values before the
            // phi nodes were added.  This could have been addressed
            // with a second basic block.  However, the naive approach
            // also yielded suboptimal results for patterns like:
            //
            //    let x = @mut @...;
            //    alt x { @@some_variant(y) | @@some_other_variant(y) {...} }
            //
            // The reason is that we would root the value once for
            // each pattern and not once per arm.  This is also easily
            // fixed, but it's yet more code for what is really quite
            // the corner case.
            //
            // Nonetheless, if you decide to optimize this case in the
            // future, you need only adjust where the cat_discr()
            // node appears to draw the line between what will be rooted
            // in the *arm* vs the *alt*.

            // current scope must be the arm, which is always a child of alt:
            assert self.tcx.region_map.get(opt_scope_id.get()) == alt_id;

            self.preserve(base, some(alt_id))
          }
        }
    }
}

impl private_methods for borrowck_ctxt {
    fn require_imm(cmt: cmt,
                   cmt_base: cmt,
                   opt_scope_id: option<ast::node_id>,
                   code: bckerr_code) -> bckres<()> {
        // Variant contents and unique pointers: must be immutably
        // rooted to a preserved address.
        alt cmt_base.mutbl {
          m_mutbl | m_const { err({cmt:cmt, code:code}) }
          m_imm { self.preserve(cmt_base, opt_scope_id) }
        }
    }

    fn attempt_root(cmt: cmt, opt_scope_id: option<ast::node_id>,
                    base: cmt, derefs: uint) -> bckres<()> {
        alt opt_scope_id {
          some(scope_id) {
            #debug["Inserting root map entry for %s: \
                    node %d:%u -> scope %d",
                   self.cmt_to_repr(cmt), base.id,
                   derefs, scope_id];

            let rk = {id: base.id, derefs: derefs};
            self.root_map.insert(rk, scope_id);
            ok(())
          }
          none {
            err({cmt:cmt, code:err_preserve_gc})
          }
        }
    }
}
<commit_msg>Correct typo in comment<commit_after>// ----------------------------------------------------------------------
// Preserve(Ex, S) holds if ToAddr(Ex) will remain valid for the entirety of
// the scope S.
export public_methods;

impl public_methods for borrowck_ctxt {
    fn preserve(cmt: cmt, opt_scope_id: option<ast::node_id>) -> bckres<()> {
        #debug["preserve(%s)", self.cmt_to_repr(cmt)];
        let _i = indenter();

        alt cmt.cat {
          cat_rvalue | cat_special(_) {
            ok(())
          }
          cat_stack_upvar(cmt) {
            self.preserve(cmt, opt_scope_id)
          }
          cat_local(_) {
            // Normally, local variables are lendable, and so this
            // case should never trigger.  However, if we are
            // preserving an expression like a.b where the field `b`
            // has @ type, then it will recurse to ensure that the `a`
            // is stable to try and avoid rooting the value `a.b`.  In
            // this case, opt_scope_id will be none.
            if opt_scope_id.is_some() {
                self.tcx.sess.span_bug(
                    cmt.span,
                    "preserve() called with local and non-none opt_scope_id");
            }
            ok(())
          }
          cat_arg(_) {
            // This can happen as not all args are lendable (e.g., &&
            // modes).  In that case, the caller guarantees stability.
            // This is basically a deref of a region ptr.
            ok(())
          }
          cat_comp(cmt_base, comp_field(*)) |
          cat_comp(cmt_base, comp_index(*)) |
          cat_comp(cmt_base, comp_tuple) |
          cat_comp(cmt_base, comp_res) {
            // Most embedded components: if the base is stable, the
            // type never changes.
            self.preserve(cmt_base, opt_scope_id)
          }
          cat_comp(cmt_base, comp_variant(enum_did)) {
            if ty::enum_is_univariant(self.tcx, enum_did) {
                self.preserve(cmt_base, opt_scope_id)
            } else {
                // If there are multiple variants: overwriting the
                // base could cause the type of this memory to change,
                // so require imm.
                self.require_imm(cmt, cmt_base, opt_scope_id, err_mut_variant)
            }
          }
          cat_deref(cmt_base, _, uniq_ptr) {
            // Overwriting the base could cause this memory to be
            // freed, so require imm.
            self.require_imm(cmt, cmt_base, opt_scope_id, err_mut_uniq)
          }
          cat_deref(_, _, region_ptr) {
            // References are always "stable" by induction (when the
            // reference of type &MT was created, the memory must have
            // been stable)
            ok(())
          }
          cat_deref(_, _, unsafe_ptr) {
            // Unsafe pointers are the user's problem
            ok(())
          }
          cat_deref(base, derefs, gc_ptr) {
            // GC'd pointers of type @MT: if this pointer lives in
            // immutable, stable memory, then everything is fine.  But
            // otherwise we have no guarantee the pointer will stay
            // live, so we must root the pointer (i.e., inc the ref
            // count) for the duration of the loan.
            if base.mutbl == m_imm {
                alt self.preserve(base, none) {
                  ok(()) {ok(())}
                  err(_) {self.attempt_root(cmt, opt_scope_id, base, derefs)}
                }
            } else {
                self.attempt_root(cmt, opt_scope_id, base, derefs)
            }
          }
          cat_discr(base, alt_id) {
            // Subtle: in an alt, we must ensure that each binding
            // variable remains valid for the duration of the arm in
            // which it appears, presuming that this arm is taken.
            // But it is inconvenient in trans to root something just
            // for one arm.  Therefore, we insert a cat_discr(),
            // basically a special kind of category that says "if this
            // value must be dynamically rooted, root it for the scope
            // `alt_id`.
            //
            // As an example, consider this scenario:
            //
            //    let mut x = @some(3);
            //    alt *x { some(y) {...} none {...} }
            //
            // Technically, the value `x` need only be rooted
            // in the `some` arm.  However, we evaluate `x` in trans
            // before we know what arm will be taken, so we just
            // always root it for the duration of the alt.
            //
            // As a second example, consider *this* scenario:
            //
            //    let x = @mut @some(3);
            //    alt x { @@some(y) {...} @@none {...} }
            //
            // Here again, `x` need only be rooted in the `some` arm.
            // In this case, the value which needs to be rooted is
            // found only when checking which pattern matches: but
            // this check is done before entering the arm.  Therefore,
            // even in this case we just choose to keep the value
            // rooted for the entire alt.  This means the value will be
            // rooted even if the none arm is taken.  Oh well.
            //
            // At first, I tried to optimize the second case to only
            // root in one arm, but the result was suboptimal: first,
            // it interfered with the construction of phi nodes in the
            // arm, as we were adding code to root values before the
            // phi nodes were added.  This could have been addressed
            // with a second basic block.  However, the naive approach
            // also yielded suboptimal results for patterns like:
            //
            //    let x = @mut @...;
            //    alt x { @@some_variant(y) | @@some_other_variant(y) {...} }
            //
            // The reason is that we would root the value once for
            // each pattern and not once per arm.  This is also easily
            // fixed, but it's yet more code for what is really quite
            // the corner case.
            //
            // Nonetheless, if you decide to optimize this case in the
            // future, you need only adjust where the cat_discr()
            // node appears to draw the line between what will be rooted
            // in the *arm* vs the *alt*.

            // current scope must be the arm, which is always a child of alt:
            assert self.tcx.region_map.get(opt_scope_id.get()) == alt_id;

            self.preserve(base, some(alt_id))
          }
        }
    }
}

impl private_methods for borrowck_ctxt {
    fn require_imm(cmt: cmt,
                   cmt_base: cmt,
                   opt_scope_id: option<ast::node_id>,
                   code: bckerr_code) -> bckres<()> {
        // Variant contents and unique pointers: must be immutably
        // rooted to a preserved address.
        alt cmt_base.mutbl {
          m_mutbl | m_const { err({cmt:cmt, code:code}) }
          m_imm { self.preserve(cmt_base, opt_scope_id) }
        }
    }

    fn attempt_root(cmt: cmt, opt_scope_id: option<ast::node_id>,
                    base: cmt, derefs: uint) -> bckres<()> {
        alt opt_scope_id {
          some(scope_id) {
            #debug["Inserting root map entry for %s: \
                    node %d:%u -> scope %d",
                   self.cmt_to_repr(cmt), base.id,
                   derefs, scope_id];

            let rk = {id: base.id, derefs: derefs};
            self.root_map.insert(rk, scope_id);
            ok(())
          }
          none {
            err({cmt:cmt, code:err_preserve_gc})
          }
        }
    }
}
<|endoftext|>


<commit_before>use crate::tick::TickUnit;
use crate::version::{Version, V_0_0_1};
use std::fmt::Display;
use std::fmt::Formatter;

pub const HEADER_LEN: usize = 128;
pub const MAGIC_U64: u64 = 0x2A54_4942_4B45_4B2A; //"*KEKBIT*" as bytes as u64
pub const LATEST: Version = V_0_0_1;

#[derive(PartialEq, Debug)]
pub enum Status {
    Open(u64),
    Timedout(u64),
    Closed(u64),
    ForcedClosed(u64),
}

impl Status {
    #[inline]
    fn status_id(&self) -> u64 {
        match self {
            Status::Open(_) => 0,
            Status::Closed(_) => 255,
            Status::ForcedClosed(_) => 512,
            Status::Timedout(_) => 1024,
        }
    }
    #[inline]
    fn from_id_and_ts(id: u64, timestamp: u64) -> Option<Status> {
        match id {
            0 => Some(Status::Open(timestamp)),
            255 => Some(Status::Closed(timestamp)),
            512 => Some(Status::ForcedClosed(timestamp)),
            1024 => Some(Status::Timedout(timestamp)),
            _ => None,
        }
    }
    #[inline]
    fn timestamp(&self) -> u64 {
        match self {
            Status::Open(ts) => *ts,
            Status::Closed(ts) => *ts,
            Status::ForcedClosed(ts) => *ts,
            Status::Timedout(ts) => *ts,
        }
    }
}

impl Display for Status {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        let res = match self {
            Status::Open(_) => "Open",
            Status::Closed(_) => "Closed",
            Status::ForcedClosed(_) => "ForcedClosed",
            Status::Timedout(_) => "Timedout",
        };
        write!(f, "{}", res)
    }
}

#[inline]
pub fn check_header(header: &[u8]) -> Result<(), String> {
    let magic = magic(header);
    if magic != MAGIC_U64 {
        return Err(format!(
            "Invalid magic header {:X}. Expected {:X}",
            magic, MAGIC_U64
        ));
    }
    let v = version(header);
    if !LATEST.is_compatible(v) {
        return Err(format!(
            "Invalid file version {}. Expected something compatible with {}",
            v, LATEST
        ));
    }
    Ok(())
}

#[inline]
pub fn write_header(
    header: &mut [u8],
    producer_id: u64,
    channel_id: u64,
    capacity: u32,
    max_msg_len: u32,
    timeout: u64,
    tick_unit: TickUnit,
) {
    let creation_time = tick_unit.nix_time();
    do_write_header(
        header,
        producer_id,
        channel_id,
        capacity,
        max_msg_len,
        timeout,
        tick_unit,
        creation_time,
    );
}
#[inline]
fn do_write_header(
    header: &mut [u8],
    producer_id: u64,
    channel_id: u64,
    capacity: u32,
    max_msg_len: u32,
    timeout: u64,
    tick_unit: TickUnit,
    creation_time: u64,
) -> usize {
    assert!(header.len() >= HEADER_LEN);
    header[0..8].clone_from_slice(&MAGIC_U64.to_le_bytes());
    let latest_v: u64 = LATEST.into();
    header[8..16].clone_from_slice(&latest_v.to_le_bytes());
    header[16..24].clone_from_slice(&producer_id.to_le_bytes());
    header[24..32].clone_from_slice(&channel_id.to_le_bytes());
    header[32..36].clone_from_slice(&capacity.to_le_bytes());
    header[36..40].clone_from_slice(&max_msg_len.to_le_bytes());
    header[40..48].clone_from_slice(&timeout.to_le_bytes());
    header[48..56].clone_from_slice(&creation_time.to_le_bytes());
    let status = Status::Open(creation_time);
    header[56..64].clone_from_slice(&status.status_id().to_le_bytes());
    header[64] = tick_unit.id();
    header[65..73].clone_from_slice(&creation_time.to_le_bytes()); //status time
    let last = 73;
    for i in last..HEADER_LEN {
        //pad up to HEADER_LEN
        header[i] = 0;
    }
    HEADER_LEN
}

#[inline]
fn read_u64(header: &[u8], offset: usize) -> u64 {
    assert!(header.len() >= HEADER_LEN);
    assert!(offset + 8 < HEADER_LEN);
    u64::from_le_bytes([
        header[offset],
        header[offset + 1],
        header[offset + 2],
        header[offset + 3],
        header[offset + 4],
        header[offset + 5],
        header[offset + 6],
        header[offset + 7],
    ])
}

#[inline]
fn read_u32(header: &[u8], offset: usize) -> u32 {
    assert!(header.len() >= HEADER_LEN);
    assert!(offset + 4 < HEADER_LEN);
    u32::from_le_bytes([
        header[offset],
        header[offset + 1],
        header[offset + 2],
        header[offset + 3],
    ])
}

#[inline]
pub fn magic(header: &[u8]) -> u64 {
    read_u64(header, 0)
}

#[inline]
pub fn version(header: &[u8]) -> Version {
    read_u64(header, 8).into()
}

#[inline]
pub fn channel_id(header: &[u8]) -> u64 {
    read_u64(header, 16)
}

#[inline]
pub fn producer_id(header: &[u8]) -> u64 {
    read_u64(header, 24)
}

#[inline]
pub fn capacity(header: &[u8]) -> u32 {
    read_u32(header, 32)
}
#[inline]
pub fn max_msg_len(header: &[u8]) -> u32 {
    read_u32(header, 36)
}
#[inline]
pub fn prod_timeout(header: &[u8]) -> u64 {
    read_u64(header, 40)
}

#[inline]
pub fn creation_time(header: &[u8]) -> u64 {
    read_u64(header, 48)
}

#[inline]
pub fn status(header: &[u8]) -> Option<Status> {
    Status::from_id_and_ts(read_u64(header, 56), status_time(header))
}

#[inline]
pub fn set_status(header: &mut [u8], new_status: Status) -> Result<Status, String> {
    let status_opt = status(header);
    match status_opt {
        Some(status) => match status {
            Status::Open(_) => {
                header[56..64].clone_from_slice(&new_status.status_id().to_le_bytes());
                header[64..72].clone_from_slice(&new_status.timestamp().to_le_bytes());
                Ok(new_status)
            }
            _ => Err(format!(
                "Invalid request. Transition from {} _ > {}",
                status, new_status
            )),
        },
        None => Err("Unknown curent status".to_string()),
    }
}

#[inline]
pub fn status_time(header: &[u8]) -> u64 {
    read_u64(header, 65)
}

#[inline]
pub fn tick_unit(header: &[u8]) -> TickUnit {
    TickUnit::from_id(header[64])
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn check_header() {
        let mut data = vec![0u8; HEADER_LEN];
        let producer_id: u64 = 111;
        let channel_id: u64 = 101;
        let capacity: u32 = 10001;
        let max_msg_len: u32 = 100;
        let timeout: u64 = 10000;
        let tick_unit = TickUnit::Nanos;
        let creation_time: u64 = 1111111;
        let res = do_write_header(
            &mut data,
            channel_id,
            producer_id,
            capacity,
            max_msg_len,
            timeout,
            tick_unit,
            creation_time,
        );
        assert!(res == HEADER_LEN);
        assert!(magic(&data) == MAGIC_U64);
        assert!(version(&data) == LATEST);
        assert!(super::channel_id(&data) == channel_id);
        assert!(super::producer_id(&data) == producer_id);
        assert!(super::capacity(&data) == capacity);
        assert!(super::max_msg_len(&data) == max_msg_len);
        assert!(super::creation_time(&data) == creation_time);
        assert!(super::status_time(&data) == creation_time);
        assert!(status(&data).unwrap() == Status::Open(creation_time));
        let close_ts = creation_time + 10000;
        assert!(
            super::set_status(&mut data, Status::Closed(close_ts)).unwrap()
                == Status::Closed(close_ts)
        );
    }
}
<commit_msg>Timedout status removed<commit_after>use crate::tick::TickUnit;
use crate::version::{Version, V_0_0_1};
use std::fmt::Display;
use std::fmt::Formatter;

pub const HEADER_LEN: usize = 128;
pub const MAGIC_U64: u64 = 0x2A54_4942_4B45_4B2A; //"*KEKBIT*" as bytes as u64
pub const LATEST: Version = V_0_0_1;

#[derive(PartialEq, Debug)]
pub enum Status {
    Open(u64),
    Closed(u64),
    ForcedClosed(u64),
}

impl Status {
    #[inline]
    fn status_id(&self) -> u64 {
        match self {
            Status::Open(_) => 0,
            Status::Closed(_) => 255,
            Status::ForcedClosed(_) => 512,
        }
    }
    #[inline]
    fn from_id_and_ts(id: u64, timestamp: u64) -> Option<Status> {
        match id {
            0 => Some(Status::Open(timestamp)),
            255 => Some(Status::Closed(timestamp)),
            512 => Some(Status::ForcedClosed(timestamp)),
            _ => None,
        }
    }
    #[inline]
    fn timestamp(&self) -> u64 {
        match self {
            Status::Open(ts) => *ts,
            Status::Closed(ts) => *ts,
            Status::ForcedClosed(ts) => *ts,
        }
    }
}

impl Display for Status {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        let res = match self {
            Status::Open(_) => "Open",
            Status::Closed(_) => "Closed",
            Status::ForcedClosed(_) => "ForcedClosed",
        };
        write!(f, "{}", res)
    }
}

#[inline]
pub fn check_header(header: &[u8]) -> Result<(), String> {
    let magic = magic(header);
    if magic != MAGIC_U64 {
        return Err(format!(
            "Invalid magic header {:X}. Expected {:X}",
            magic, MAGIC_U64
        ));
    }
    let v = version(header);
    if !LATEST.is_compatible(v) {
        return Err(format!(
            "Invalid file version {}. Expected something compatible with {}",
            v, LATEST
        ));
    }
    Ok(())
}

#[inline]
pub fn write_header(
    header: &mut [u8],
    producer_id: u64,
    channel_id: u64,
    capacity: u32,
    max_msg_len: u32,
    timeout: u64,
    tick_unit: TickUnit,
) {
    let creation_time = tick_unit.nix_time();
    do_write_header(
        header,
        producer_id,
        channel_id,
        capacity,
        max_msg_len,
        timeout,
        tick_unit,
        creation_time,
    );
}
#[inline]
fn do_write_header(
    header: &mut [u8],
    producer_id: u64,
    channel_id: u64,
    capacity: u32,
    max_msg_len: u32,
    timeout: u64,
    tick_unit: TickUnit,
    creation_time: u64,
) -> usize {
    assert!(header.len() >= HEADER_LEN);
    header[0..8].clone_from_slice(&MAGIC_U64.to_le_bytes());
    let latest_v: u64 = LATEST.into();
    header[8..16].clone_from_slice(&latest_v.to_le_bytes());
    header[16..24].clone_from_slice(&producer_id.to_le_bytes());
    header[24..32].clone_from_slice(&channel_id.to_le_bytes());
    header[32..36].clone_from_slice(&capacity.to_le_bytes());
    header[36..40].clone_from_slice(&max_msg_len.to_le_bytes());
    header[40..48].clone_from_slice(&timeout.to_le_bytes());
    header[48..56].clone_from_slice(&creation_time.to_le_bytes());
    let status = Status::Open(creation_time);
    header[56..64].clone_from_slice(&status.status_id().to_le_bytes());
    header[64] = tick_unit.id();
    header[65..73].clone_from_slice(&creation_time.to_le_bytes()); //status time
    let last = 73;
    for i in last..HEADER_LEN {
        //pad up to HEADER_LEN
        header[i] = 0;
    }
    HEADER_LEN
}

#[inline]
fn read_u64(header: &[u8], offset: usize) -> u64 {
    assert!(header.len() >= HEADER_LEN);
    assert!(offset + 8 < HEADER_LEN);
    u64::from_le_bytes([
        header[offset],
        header[offset + 1],
        header[offset + 2],
        header[offset + 3],
        header[offset + 4],
        header[offset + 5],
        header[offset + 6],
        header[offset + 7],
    ])
}

#[inline]
fn read_u32(header: &[u8], offset: usize) -> u32 {
    assert!(header.len() >= HEADER_LEN);
    assert!(offset + 4 < HEADER_LEN);
    u32::from_le_bytes([
        header[offset],
        header[offset + 1],
        header[offset + 2],
        header[offset + 3],
    ])
}

#[inline]
pub fn magic(header: &[u8]) -> u64 {
    read_u64(header, 0)
}

#[inline]
pub fn version(header: &[u8]) -> Version {
    read_u64(header, 8).into()
}

#[inline]
pub fn channel_id(header: &[u8]) -> u64 {
    read_u64(header, 16)
}

#[inline]
pub fn producer_id(header: &[u8]) -> u64 {
    read_u64(header, 24)
}

#[inline]
pub fn capacity(header: &[u8]) -> u32 {
    read_u32(header, 32)
}
#[inline]
pub fn max_msg_len(header: &[u8]) -> u32 {
    read_u32(header, 36)
}
#[inline]
pub fn prod_timeout(header: &[u8]) -> u64 {
    read_u64(header, 40)
}

#[inline]
pub fn creation_time(header: &[u8]) -> u64 {
    read_u64(header, 48)
}

#[inline]
pub fn status(header: &[u8]) -> Option<Status> {
    Status::from_id_and_ts(read_u64(header, 56), status_time(header))
}

#[inline]
pub fn set_status(header: &mut [u8], new_status: Status) -> Result<Status, String> {
    let status_opt = status(header);
    match status_opt {
        Some(status) => match status {
            Status::Open(_) => {
                header[56..64].clone_from_slice(&new_status.status_id().to_le_bytes());
                header[64..72].clone_from_slice(&new_status.timestamp().to_le_bytes());
                Ok(new_status)
            }
            _ => Err(format!(
                "Invalid request. Transition from {} _ > {}",
                status, new_status
            )),
        },
        None => Err("Unknown curent status".to_string()),
    }
}

#[inline]
pub fn status_time(header: &[u8]) -> u64 {
    read_u64(header, 65)
}

#[inline]
pub fn tick_unit(header: &[u8]) -> TickUnit {
    TickUnit::from_id(header[64])
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn check_header() {
        let mut data = vec![0u8; HEADER_LEN];
        let producer_id: u64 = 111;
        let channel_id: u64 = 101;
        let capacity: u32 = 10001;
        let max_msg_len: u32 = 100;
        let timeout: u64 = 10000;
        let tick_unit = TickUnit::Nanos;
        let creation_time: u64 = 1111111;
        let res = do_write_header(
            &mut data,
            channel_id,
            producer_id,
            capacity,
            max_msg_len,
            timeout,
            tick_unit,
            creation_time,
        );
        assert!(res == HEADER_LEN);
        assert!(magic(&data) == MAGIC_U64);
        assert!(version(&data) == LATEST);
        assert!(super::channel_id(&data) == channel_id);
        assert!(super::producer_id(&data) == producer_id);
        assert!(super::capacity(&data) == capacity);
        assert!(super::max_msg_len(&data) == max_msg_len);
        assert!(super::creation_time(&data) == creation_time);
        assert!(super::status_time(&data) == creation_time);
        assert!(status(&data).unwrap() == Status::Open(creation_time));
        let close_ts = creation_time + 10000;
        assert!(
            super::set_status(&mut data, Status::Closed(close_ts)).unwrap()
                == Status::Closed(close_ts)
        );
    }
}
<|endoftext|>


<commit_before><commit_msg>todo completed<commit_after><|endoftext|>


<commit_before><commit_msg>Add RawStr::url_decode.<commit_after><|endoftext|>


<commit_before>use super::prelude::v1::*;
use super::hash::*;
use super::mem;
use super::fmt::{Debug, Display};

/// Number of buckets in the hash table
pub const BUCKETS: usize = 256;

/// An linked list (used for entries)
#[derive(Clone)]
pub enum LinkedList<T: Clone> {
    Elem(T, Box<LinkedList<T>>),
    Nil,
}

impl<T: Clone> LinkedList<T> {
    /// Follow
    pub fn follow(&self) -> Option<&Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Follow mutable
    pub fn follow_mut(&mut self) -> Option<&mut Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref mut l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Push (consumes the list)
    pub fn push(self, elem: T) -> Self {
        LinkedList::Elem(elem, Box::new(self))
    }
}

/// A entry in the hash map
#[derive(Clone)]
pub struct Entry<K: Clone, V: Clone> {
    data: LinkedList<(K, V)>,
}

impl<K: PartialEq<K> + Clone + Debug + Display, V: Clone> Entry<K, V> {
    /// Create new
    pub fn new(key: K, value: V) -> Self {
        Entry {
            data: LinkedList::Elem((key, value), Box::new(LinkedList::Nil)),
        }
    }

    /// Get value from entry
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut cur = Some(&self.data);

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref v), ref l) => {
                        debugln!("Check key against: {}", k);
                        if key == k {
                            return Some(v);
                        } else {
                            debugln!("Follow link");
                            l.follow()
                        }
                    },
                    LinkedList::Nil => {
                        debugln!("None 1");
                        return None;
                    },
                },
                None => {
                    debugln!("None 2");
                    return None;
                },
            }

        }
    }

    /// Get value mutable from entry
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {

        let mut cur = Some(&mut self.data);

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref mut v), ref mut l) => {
                        debugln!("Check key against: {}", k);
                        if key == k {
                            return Some(v);
                        } else {
                            debugln!("Follow link");
                            l.follow_mut()
                        }
                    },
                    LinkedList::Nil => {
                        debugln!("None 1");
                        return None;
                    },
                },
                None => {
                    debugln!("None 2");
                    return None;
                },
            }

        }
    }

    /// Push to the list (consumes the entry returning the new one)
    pub fn push(self, key: K, value: V) -> Self {
        Entry {
            data: self.data.push((key, value)),
        }
    }
}

/// A hashtable
pub struct HashMap<K: Clone, V: Clone> {
    data: [Entry<K, V>; BUCKETS],
}

impl<K: Hash + PartialEq + Clone + Debug + Display, V: Clone + Debug> HashMap<K, V> {
    /// Make new HT
    pub fn new() -> Self {
        HashMap {
            // Sorry, but LinkedList is not, and will not be copyable
            data: [Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil} , Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}],
        }
    }

    /// Get entry num
    fn get_entry(key: &K) -> usize {
        let mut s = Djb2::new();
        key.hash(&mut s);
        let res = (s.finish() % BUCKETS as u64) as usize;
        debugln!("Res is: {}", res);
        res
    }

    /// Get value
    pub fn get(&self, key: &K) -> Option<&V> {
        self.data[Self::get_entry(key)].get(key)
    }

    /// Get value mutable
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
        self.data[Self::get_entry(key)].get_mut(key)
    }

    /// Set value (return the previous one if overwritten)
    pub fn insert(&mut self, key: K, val: V) -> Option<V> {
        match self.get_mut(&key) {
            Some(r) => {
                debugln!("Key inserted: {:?}", key);
                debugln!("Old val: {:?}", r);
                debugln!("New val: {:?}", val);
                return Some(mem::replace(r, val));
            },
            _ => {}
        }
        let n = Self::get_entry(&key);
        self.data[n] = self.data[n].clone().push(key, val);
        None
    }
}

/// DJB2 hashing
pub struct Djb2 {
    state: u64,
}

impl Djb2 {
    /// Create new DJB2 hasher
    pub fn new() -> Self {
        Djb2 {
            state: 5381,
        }
    }
}

impl Hasher for Djb2 {
    fn finish(&self) -> u64 {
        self.state
    }
    fn write(&mut self, bytes: &[u8]) {
        for &b in bytes {
            self.state = ((self.state << 5) + self.state) + b as u64;
        }
    }
}

pub fn test() {
    let mut ht = HashMap::new();

    assert!(!ht.insert(1, 42).is_some());
    assert_eq!(ht.get(&1), Some(&42));
    assert!(ht.insert(288, 666).is_some());
    assert_eq!(ht.get(&288), Some(&666));
    assert_eq!(ht.get(&1), Some(&42));

//    for i in 1..300 {
//        debugln!("Set {}", i);
//        ht.insert(i, i);
//    }
//
//    for i in 1..300 {
//        debugln!("Get {}", i);
//        assert_eq!(ht.get(&i), Some(&i));
//    }

}
<commit_msg>Add simple function to know if a key exists in an existed hashmap structure<commit_after>use super::prelude::v1::*;
use super::hash::*;
use super::mem;
use super::fmt::{Debug, Display};

/// Number of buckets in the hash table
pub const BUCKETS: usize = 256;

/// An linked list (used for entries)
#[derive(Clone)]
pub enum LinkedList<T: Clone> {
    Elem(T, Box<LinkedList<T>>),
    Nil,
}

impl<T: Clone> LinkedList<T> {
    /// Follow
    pub fn follow(&self) -> Option<&Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Follow mutable
    pub fn follow_mut(&mut self) -> Option<&mut Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref mut l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Push (consumes the list)
    pub fn push(self, elem: T) -> Self {
        LinkedList::Elem(elem, Box::new(self))
    }
}

/// A entry in the hash map
#[derive(Clone)]
pub struct Entry<K: Clone, V: Clone> {
    data: LinkedList<(K, V)>,
}

impl<K: PartialEq<K> + Clone + Debug + Display, V: Clone> Entry<K, V> {
    /// Create new
    pub fn new(key: K, value: V) -> Self {
        Entry {
            data: LinkedList::Elem((key, value), Box::new(LinkedList::Nil)),
        }
    }

    /// Get value from entry
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut cur = Some(&self.data);

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref v), ref l) => {
                        debugln!("Check key against: {}", k);
                        if key == k {
                            return Some(v);
                        } else {
                            debugln!("Follow link");
                            l.follow()
                        }
                    },
                    LinkedList::Nil => {
                        debugln!("None 1");
                        return None;
                    },
                },
                None => {
                    debugln!("None 2");
                    return None;
                },
            }

        }
    }

    /// Get value mutable from entry
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {

        let mut cur = Some(&mut self.data);

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref mut v), ref mut l) => {
                        debugln!("Check key against: {}", k);
                        if key == k {
                            return Some(v);
                        } else {
                            debugln!("Follow link");
                            l.follow_mut()
                        }
                    },
                    LinkedList::Nil => {
                        debugln!("None 1");
                        return None;
                    },
                },
                None => {
                    debugln!("None 2");
                    return None;
                },
            }

        }
    }

    /// Push to the list (consumes the entry returning the new one)
    pub fn push(self, key: K, value: V) -> Self {
        Entry {
            data: self.data.push((key, value)),
        }
    }
}

/// A hashtable
pub struct HashMap<K: Clone, V: Clone> {
    data: [Entry<K, V>; BUCKETS],
}

impl<K: Hash + PartialEq + Clone + Debug + Display, V: Clone + Debug> HashMap<K, V> {
    /// Make new HT
    pub fn new() -> Self {
        HashMap {
            // Sorry, but LinkedList is not, and will not be copyable
            data: [Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil} , Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}],
        }
    }

    /// Is the key exists?
    pub fn contains_key(&self, key: &K) -> bool {
        match self.data[Self::get_entry(key)].get(key) {
            Some(_) => true,
            None => false
        }
    }

    /// Get entry num
    fn get_entry(key: &K) -> usize {
        let mut s = Djb2::new();
        key.hash(&mut s);
        let res = (s.finish() % BUCKETS as u64) as usize;
        debugln!("Res is: {}", res);
        res
    }

    /// Get value
    pub fn get(&self, key: &K) -> Option<&V> {
        self.data[Self::get_entry(key)].get(key)
    }

    /// Get value mutable
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
        self.data[Self::get_entry(key)].get_mut(key)
    }

    /// Set value (return the previous one if overwritten)
    pub fn insert(&mut self, key: K, val: V) -> Option<V> {
        match self.get_mut(&key) {
            Some(r) => {
                debugln!("Key inserted: {:?}", key);
                debugln!("Old val: {:?}", r);
                debugln!("New val: {:?}", val);
                return Some(mem::replace(r, val));
            },
            _ => {}
        }
        let n = Self::get_entry(&key);
        self.data[n] = self.data[n].clone().push(key, val);
        None
    }
}

/// DJB2 hashing
pub struct Djb2 {
    state: u64,
}

impl Djb2 {
    /// Create new DJB2 hasher
    pub fn new() -> Self {
        Djb2 {
            state: 5381,
        }
    }
}

impl Hasher for Djb2 {
    fn finish(&self) -> u64 {
        self.state
    }
    fn write(&mut self, bytes: &[u8]) {
        for &b in bytes {
            self.state = ((self.state << 5) + self.state) + b as u64;
        }
    }
}

pub fn test() {
    let mut ht = HashMap::new();

    assert!(!ht.insert(1, 42).is_some());
    assert_eq!(ht.get(&1), Some(&42));
    assert!(ht.insert(288, 666).is_some());
    assert_eq!(ht.get(&288), Some(&666));
    assert_eq!(ht.get(&1), Some(&42));

//    for i in 1..300 {
//        debugln!("Set {}", i);
//        ht.insert(i, i);
//    }
//
//    for i in 1..300 {
//        debugln!("Get {}", i);
//        assert_eq!(ht.get(&i), Some(&i));
//    }

}
<|endoftext|>


<commit_before><commit_msg>Fix origin change<commit_after><|endoftext|>


<commit_before><commit_msg>Add set_eid in backup<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: libimaghabit::habit::HabitTemplate should link created instances to the template<commit_after><|endoftext|>


<commit_before><commit_msg>finish rust version<commit_after>#![feature(repeat_generic_slice)]
fn make_dot(dots: String, left: &str, right: &str) -> String {
    let length_dots = dots.len() as i32;
    let mut v = vec![];
    match (left, right) {
        ("L", "R") | ("", "R") | ("L", "") | ("", "") => {
            return dots;
        }
        ("L", "L") | ("", "L") => {
            v.append(&mut ['L'].repeat(length_dots as usize));
        }
        ("R", "R") | ("R", "") => {
            v.append(&mut ['R'].repeat(length_dots as usize));
        }
        ("R", "L") => {
            v.append(&mut ['R'].repeat((length_dots / 2) as usize));
            if length_dots % 2 == 1 {
                v.append(&mut vec!['.']);
            }
            v.append(&mut ['L'].repeat((length_dots / 2) as usize));
        }
        _ => {}
    }

    v.iter().collect::<String>()
}

fn push_dominoes(dominoes: String) -> String {
    let chars = dominoes.chars();
    let mut result: Vec<String> = vec![];
    let mut cache: Vec<char> = vec![];
    let mut last: char = ' ';

    for b in chars {
        if last != '.' && b == '.' {
            cache.push(b);
        } else if last == '.' && b != '.' {
            let cc = cache.iter().collect::<String>();
            if cc != "" {
                result.push(cc);
            }
            cache = vec![];
            result.push(b.to_string());
        } else if last == '.' && b == '.' {
            cache.push(b);
        } else {
            result.push(b.to_string());
        }

        last = b;
    }

    let cc = cache.iter().collect::<String>();
    if cc != "" {
        result.push(cc);
    }

    //println!("{:?}", result);

    let length = result.len();
    for ind in 0..length {
        if result[ind] != "L" && result[ind] != "R" {
            if ind == 0 {
                if length == 1 {
                    result[ind] = make_dot(result[ind].clone(), "", "");
                    continue;
                }
                result[ind] = make_dot(result[ind].clone(), "", &result[ind + 1]);
            } else if ind == length - 1 {
                result[ind] = make_dot(result[ind].clone(), &result[ind - 1], "");
            } else {
                result[ind] = make_dot(result[ind].clone(), &result[ind - 1], &result[ind + 1]);
            }
        }
    }

    //println!("{:?}", result);
    result.join("")
}

fn main() {
    assert_eq!(
        push_dominoes(String::from(".L.R...LR..L..")),
        String::from("LL.RR.LLRRLL..")
    );
    assert_eq!(push_dominoes(String::from("RR.L")), String::from("RR.L"));
    assert_eq!(push_dominoes(String::from(".")), String::from("."));
    assert_eq!(push_dominoes(String::from("LL")), String::from("LL"));

    //println!("{:?}", make_dot(String::from("..."), "L", "R"));
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use path::*;

pub trait PathLike {
    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T;
}

impl<'self> PathLike for &'self str {
    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
        f(*self)
    }
}

impl PathLike for Path {
    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
        let s = self.to_str();
        f(s)
    }
}

#[cfg(test)]
mod test {
    use path::*;
    use super::PathLike;

    #[test]
    #[ignore(cfg(windows))] // FIXME #8812
    fn path_like_smoke_test() {
        let expected = "/home";
        let path = Path(expected);
        path.path_as_str(|p| assert!(p == expected));
        path.path_as_str(|p| assert!(p == expected));
    }
}
<commit_msg>std::rt::io::support: Fix ignored test on Win32<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use path::*;

pub trait PathLike {
    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T;
}

impl<'self> PathLike for &'self str {
    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
        f(*self)
    }
}

impl PathLike for Path {
    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
        let s = self.to_str();
        f(s)
    }
}

#[cfg(test)]
mod test {
    use path::*;
    use super::PathLike;

    #[test]
    fn path_like_smoke_test() {
        let expected = if cfg!(unix) { "/home" } else { "C:\\" };
        let path = Path(expected);
        path.path_as_str(|p| assert!(p == expected));
        path.path_as_str(|p| assert!(p == expected));
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix imag-bookmark error handling<commit_after><|endoftext|>


<commit_before>extern crate backtrace;

pub use backtrace::Backtrace;

mod quick_error;

#[derive(Debug)]
pub struct ForeignError {
    pub description: String,
    pub display: String,
}

impl ForeignError {
    pub fn new<E>(e: &E) -> ForeignError
        where E: ::std::error::Error
    {
        ForeignError {
            description: e.description().to_string(),
            display: format!("{}", e)
        }
    }
}

#[macro_export]
macro_rules! declare_errors {
    (
        types {
            $error_name:ident, $error_kind_name:ident,
            $chain_error_name:ident, $result_name:ident;
        }

        links {
            $( $link_chain_path:path, $link_error_path:path, $link_variant:ident;  ) *
        }

        foreign_links {
            $( $foreign_link_error_path:path, $foreign_link_variant:ident;  ) *
        }

        errors {
            $( $error_chunks:tt ) *
        }

    ) => {

        // The Error type
        // --------------

        #[derive(Debug)]
        pub struct $error_name(pub $error_kind_name,
                               pub Option<Box<::std::error::Error + Send>>,
                               pub $crate::Backtrace);

        #[allow(unused)]
        impl $error_name {
            pub fn inner(&self) -> &$error_kind_name {
                &self.0
            }

            pub fn into_inner(self) -> $error_kind_name {
                self.0
            }
        }

        impl ::std::error::Error for $error_name {
            fn description(&self) -> &str { self.0.description() }
            fn cause(&self) -> Option<&::std::error::Error> {
                match self.1 {
                    Some(ref c) => Some(&**c),
                    None => None
                }
            }
        }

        impl ::std::fmt::Display for $error_name {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                ::std::fmt::Display::fmt(&self.0, f)
            }
        }

        $(
            impl From<$link_chain_path> for $error_name {
                fn from(e: $link_chain_path) -> Self {
                    $error_name($error_kind_name::$link_variant(e.0), e.1, e.2)
                }
            }
        ) *

        $(
            impl From<$foreign_link_error_path> for $error_name {
                fn from(e: $foreign_link_error_path) -> Self {
                    $error_name(
                        $error_kind_name::$foreign_link_variant($crate::ForeignError::new(&e)),
                        Some(Box::new(e)),
                        $crate::Backtrace::new())
                }
            }
        ) *

        impl From<$error_kind_name> for $error_name {
            fn from(e: $error_kind_name) -> Self {
                $error_name(e, None, $crate::Backtrace::new())
            }
        }

        impl<'a> From<&'a str> for $error_name {
            fn from(s: &'a str) -> Self {
                $error_name(s.into(), None, $crate::Backtrace::new())
            }
        }

        impl From<String> for $error_name {
            fn from(s: String) -> Self {
                $error_name(s.into(), None, $crate::Backtrace::new())
            }
        }

        // The ErrorKind type
        // --------------

        quick_error! {
            #[derive(Debug)]
            pub enum $error_kind_name {

                Msg(s: String) {
                    description(&s)
                    display("{}", s)
                }

                $(
                    $link_variant(e: $link_error_path) {
                        description(e.description())
                        display("{}", e)
                    }
                ) *

                $(
                    $foreign_link_variant(e: $crate::ForeignError) {
                        description(&e.description)
                        display("{}", e.display)
                    }
                ) *

                $($error_chunks)*
            }
        }

        $(
            impl From<$link_error_path> for $error_kind_name {
                fn from(e: $link_error_path) -> Self {
                    $error_kind_name::$link_variant(e)
                }
            }
        ) *

        impl<'a> From<&'a str> for $error_kind_name {
            fn from(s: &'a str) -> Self {
                $error_kind_name::Msg(s.to_string())
            }
        }

        impl From<String> for $error_kind_name {
            fn from(s: String) -> Self {
                $error_kind_name::Msg(s)
            }
        }

        // Lesser types
        // ------------

        pub trait $chain_error_name<T> {
            fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
                where F: FnOnce() -> EK,
                      EK: Into<$error_kind_name>;
        }

        impl<T, E> $chain_error_name<T> for ::std::result::Result<T, E>
            where E: ::std::error::Error + Send + 'static
        {
            fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
                where F: FnOnce() -> EK,
                      EK: Into<$error_kind_name>
            {
                self.map_err(move |e| {
                    // FIXME: Unfortunate backtrace if E already has one
                    $error_name(callback().into(), Some(Box::new(e)), $crate::Backtrace::new())
                })
            }
        }

        pub type $result_name<T> = ::std::result::Result<T, $error_name>;
    };
}
<commit_msg>Fix some macro variable names<commit_after>extern crate backtrace;

pub use backtrace::Backtrace;

mod quick_error;

#[derive(Debug)]
pub struct ForeignError {
    pub description: String,
    pub display: String,
}

impl ForeignError {
    pub fn new<E>(e: &E) -> ForeignError
        where E: ::std::error::Error
    {
        ForeignError {
            description: e.description().to_string(),
            display: format!("{}", e)
        }
    }
}

#[macro_export]
macro_rules! declare_errors {
    (
        types {
            $error_name:ident, $error_kind_name:ident,
            $chain_error_name:ident, $result_name:ident;
        }

        links {
            $( $link_error_path:path, $link_kind_path:path, $link_variant:ident;  ) *
        }

        foreign_links {
            $( $foreign_link_error_path:path, $foreign_link_variant:ident;  ) *
        }

        errors {
            $( $error_chunks:tt ) *
        }

    ) => {

        // The Error type
        // --------------

        #[derive(Debug)]
        pub struct $error_name(pub $error_kind_name,
                               pub Option<Box<::std::error::Error + Send>>,
                               pub $crate::Backtrace);

        #[allow(unused)]
        impl $error_name {
            pub fn inner(&self) -> &$error_kind_name {
                &self.0
            }

            pub fn into_inner(self) -> $error_kind_name {
                self.0
            }
        }

        impl ::std::error::Error for $error_name {
            fn description(&self) -> &str { self.0.description() }
            fn cause(&self) -> Option<&::std::error::Error> {
                match self.1 {
                    Some(ref c) => Some(&**c),
                    None => None
                }
            }
        }

        impl ::std::fmt::Display for $error_name {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                ::std::fmt::Display::fmt(&self.0, f)
            }
        }

        $(
            impl From<$link_error_path> for $error_name {
                fn from(e: $link_error_path) -> Self {
                    $error_name($error_kind_name::$link_variant(e.0), e.1, e.2)
                }
            }
        ) *

        $(
            impl From<$foreign_link_error_path> for $error_name {
                fn from(e: $foreign_link_error_path) -> Self {
                    $error_name(
                        $error_kind_name::$foreign_link_variant($crate::ForeignError::new(&e)),
                        Some(Box::new(e)),
                        $crate::Backtrace::new())
                }
            }
        ) *

        impl From<$error_kind_name> for $error_name {
            fn from(e: $error_kind_name) -> Self {
                $error_name(e, None, $crate::Backtrace::new())
            }
        }

        impl<'a> From<&'a str> for $error_name {
            fn from(s: &'a str) -> Self {
                $error_name(s.into(), None, $crate::Backtrace::new())
            }
        }

        impl From<String> for $error_name {
            fn from(s: String) -> Self {
                $error_name(s.into(), None, $crate::Backtrace::new())
            }
        }

        // The ErrorKind type
        // --------------

        quick_error! {
            #[derive(Debug)]
            pub enum $error_kind_name {

                Msg(s: String) {
                    description(&s)
                    display("{}", s)
                }

                $(
                    $link_variant(e: $link_kind_path) {
                        description(e.description())
                        display("{}", e)
                    }
                ) *

                $(
                    $foreign_link_variant(e: $crate::ForeignError) {
                        description(&e.description)
                        display("{}", e.display)
                    }
                ) *

                $($error_chunks)*
            }
        }

        $(
            impl From<$link_kind_path> for $error_kind_name {
                fn from(e: $link_kind_path) -> Self {
                    $error_kind_name::$link_variant(e)
                }
            }
        ) *

        impl<'a> From<&'a str> for $error_kind_name {
            fn from(s: &'a str) -> Self {
                $error_kind_name::Msg(s.to_string())
            }
        }

        impl From<String> for $error_kind_name {
            fn from(s: String) -> Self {
                $error_kind_name::Msg(s)
            }
        }

        // Lesser types
        // ------------

        pub trait $chain_error_name<T> {
            fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
                where F: FnOnce() -> EK,
                      EK: Into<$error_kind_name>;
        }

        impl<T, E> $chain_error_name<T> for ::std::result::Result<T, E>
            where E: ::std::error::Error + Send + 'static
        {
            fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
                where F: FnOnce() -> EK,
                      EK: Into<$error_kind_name>
            {
                self.map_err(move |e| {
                    // FIXME: Unfortunate backtrace if E already has one
                    $error_name(callback().into(), Some(Box::new(e)), $crate::Backtrace::new())
                })
            }
        }

        pub type $result_name<T> = ::std::result::Result<T, $error_name>;
    };
}
<|endoftext|>