<commit_before>use notify_rust::{Notification, NotificationHint, NotificationUrgency};
use rusthub::notifications;
use std::process::Command;

const APP_NAME: &'static str = "gh-notify";

pub fn show_notification(notification: &notifications::Notification) {
    notify_action(
        &notification.subject.title,
        &notification.reason,
        "Open in Browser",
        120,
        |action| {
            match action {
                "default" | "clicked" => {
                    open_link(&notification.url);
                },
                "__closed" => (),
                _ => ()
            }
        }
    );
}

pub fn open_link(url: &str) {
    debug!("Opening browser link: {}", url);
    let _ = Command::new("sh")
        .arg("-c")
        .arg(format!("xdg-open '{}'", url))
        .output()
        .expect("Failed to open web browser instance.");
}

pub fn notify_action<F>(summary: &str, body: &str, button_text: &str, timeout: i32, action: F) where F:FnOnce(&str) {
    Notification::new()
        .appname(APP_NAME)
        .summary(&summary)
        .body(&body)
        .action("default", &button_text)    // IDENTIFIER, LABEL
        .action("clicked", &button_text) // IDENTIFIER, LABEL
        .hint(NotificationHint::Urgency(NotificationUrgency::Normal))
        .timeout(timeout)
        .show()
        .unwrap()
        .wait_for_action(action);
}<commit_msg>notifications are now more legible<commit_after>use notify_rust::{Notification, NotificationHint, NotificationUrgency};
use rusthub::notifications;
use std::process::Command;
use std::thread;

const APP_NAME: &'static str = "gh-notify";

pub fn show_notification(notification: &notifications::Notification) {
    let subject = format!("{} - {}", notification.repository.name, notification.subject.subject_type);
    let body = notification.subject.title.clone();
    let url = notification.repository.html_url.clone();
    thread::spawn(move || {
        notify_action(
            &subject,
            &body,
            "Open in Browser",
            120,
            |action| {
                match action {
                    "default" | "clicked" => {
                        open_link(&url);
                    },
                    "__closed" => (),
                    _ => ()
                }
            }
        );
    });
}

pub fn open_link(url: &str) {
    debug!("Opening browser link: {}", url);
    let _ = Command::new("sh")
        .arg("-c")
        .arg(format!("xdg-open '{}'", url))
        .output()
        .expect("Failed to open web browser instance.");
}

pub fn notify_action<F>(summary: &str, body: &str, button_text: &str, timeout: i32, action: F) where F:FnOnce(&str) {
    Notification::new()
        .appname(APP_NAME)
        .summary(&summary)
        .body(&body)
        .action("default", &button_text)    // IDENTIFIER, LABEL
        .action("clicked", &button_text) // IDENTIFIER, LABEL
        .hint(NotificationHint::Urgency(NotificationUrgency::Normal))
        .timeout(timeout)
        .show()
        .unwrap()
        .wait_for_action(action);
}<|endoftext|>


<commit_before>use std;
use std::ptr;

use class::Class;
use gc::Gc;
use mem;
use mem::ptr::Ptr;

pub struct Header {
    class: *mut Class<'static>,
}

// String in Dora is immutable
// length + string content is stored in one contiguous memory
pub struct Str {
    ptr: Ptr
}

impl Str {
    pub fn len(&self) -> usize {
        unsafe {
            *(self.ptr.raw() as *const usize)
        }
    }

    pub fn ptr(&self) -> Ptr {
        self.ptr
    }

    pub fn set_len(&self, len: usize) {
        unsafe {
            *(self.ptr.raw() as *mut usize) = len;
        }
    }

    pub fn data(&self) -> *mut u8 {
        unsafe {
            self.ptr.raw().offset(mem::ptr_width() as isize) as *mut u8
        }
    }
}

impl Str {
    pub fn from_buffer(gc: &mut Gc, buf: &[u8]) -> Str {
        let string = Str::new(gc, buf.len());

        unsafe {
            // write len of Str (excluding 0 at end)
            string.set_len(buf.len());

            // copy buffer content into Str
            ptr::copy_nonoverlapping(buf.as_ptr(), string.data(), buf.len());

            // string should end with 0 for C compatibility
            *(string.data().offset(buf.len() as isize)) = 0;
        }

        string
    }

    pub fn new(gc: &mut Gc, len: usize) -> Str {
        let size = mem::ptr_width() as usize + len + 1;

        Str { ptr: gc.alloc(size) }
    }

    pub fn concat(gc: &mut Gc, lhs: Str, rhs: Str) -> Str {
        let len = lhs.len() + rhs.len();
        let string = Str::new(gc, len);

        unsafe {
            string.set_len(len);

            ptr::copy_nonoverlapping(lhs.data(), string.data(), lhs.len());
            ptr::copy_nonoverlapping(rhs.data(),
                string.data().offset(lhs.len() as isize), rhs.len());

            *(string.data().offset(len as isize)) = 0;
        }

        string
    }
}

pub struct IntArray {
    ptr: *mut i32,
    length: usize,
}

impl IntArray {
    pub fn empty() -> IntArray {
        IntArray {
            ptr: ptr::null_mut(),
            length: 0,
        }
    }

    pub fn with_element(gc: &mut Gc, length: usize, elem: isize) -> IntArray {
        if length < 0 {
            panic!("length needs to be greater or equal to 0.");
        }

        let ptr = if length > 0 {
            gc.alloc(std::mem::size_of::<i32>() * length).raw() as *mut i32
        } else {
            ptr::null_mut()
        };

        for i in 0..length {
            unsafe {
                *ptr.offset(i as isize) = elem as i32;
            }
        }

        IntArray {
            ptr: ptr,
            length: length,
        }
    }

    pub fn size() -> usize {
        std::mem::size_of::<IntArray>()
    }

    pub fn len(&self) -> usize {
        self.length
    }

    pub fn get(&self, ind: i32) -> i32 {
        if ind < 0 || ind as usize >= self.length {
            panic!("index out of bounds");
        }

        unsafe {
            *self.ptr.offset(ind as isize)
        }
    }

    pub fn set(&self, ind: i32, value: i32) {
        if ind < 0 || ind as usize >= self.length {
            panic!("index out of bounds");
        }

        unsafe {
            *self.ptr.offset(ind as isize) = value;
        }
    }
}

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

    use gc::Gc;
    use libc;

    #[test]
    pub fn test_create_string() {
        let mut gc = Gc::new();
        let string = Str::from_buffer(&mut gc, "hello world!".as_bytes());

        unsafe {
            assert_eq!(12, string.len());

            let expected = "hello world!".as_ptr() as *const i8;
            let value = string.data() as *const i8;
            assert_eq!(0, libc::strncmp(expected, value, string.len()));
        }
    }
}
<commit_msg>added IntArray2<commit_after>use std;
use std::ops::Index;
use std::ptr;

use class::Class;
use gc::Gc;
use mem;
use mem::ptr::Ptr;

pub struct Header {
    class: *mut Class<'static>,
}

// String in Dora is immutable
// length + string content is stored in one contiguous memory
pub struct Str {
    ptr: Ptr
}

impl Str {
    pub fn len(&self) -> usize {
        unsafe {
            *(self.ptr.raw() as *const usize)
        }
    }

    pub fn ptr(&self) -> Ptr {
        self.ptr
    }

    pub fn set_len(&self, len: usize) {
        unsafe {
            *(self.ptr.raw() as *mut usize) = len;
        }
    }

    pub fn data(&self) -> *mut u8 {
        unsafe {
            self.ptr.raw().offset(mem::ptr_width() as isize) as *mut u8
        }
    }
}

impl Str {
    pub fn from_buffer(gc: &mut Gc, buf: &[u8]) -> Str {
        let string = Str::new(gc, buf.len());

        unsafe {
            // write len of Str (excluding 0 at end)
            string.set_len(buf.len());

            // copy buffer content into Str
            ptr::copy_nonoverlapping(buf.as_ptr(), string.data(), buf.len());

            // string should end with 0 for C compatibility
            *(string.data().offset(buf.len() as isize)) = 0;
        }

        string
    }

    pub fn new(gc: &mut Gc, len: usize) -> Str {
        let size = mem::ptr_width() as usize + len + 1;

        Str { ptr: gc.alloc(size) }
    }

    pub fn concat(gc: &mut Gc, lhs: Str, rhs: Str) -> Str {
        let len = lhs.len() + rhs.len();
        let string = Str::new(gc, len);

        unsafe {
            string.set_len(len);

            ptr::copy_nonoverlapping(lhs.data(), string.data(), lhs.len());
            ptr::copy_nonoverlapping(rhs.data(),
                string.data().offset(lhs.len() as isize), rhs.len());

            *(string.data().offset(len as isize)) = 0;
        }

        string
    }
}

pub struct IntArray2 {
    length: usize,
    data: [i32; 1]
}

impl IntArray2 {
    fn len(&self) -> usize {
        self.length
    }
}

impl Index<usize> for IntArray2 {
    type Output = i32;

    fn index<'a>(&'a self, ind: usize) -> &'a i32 {
        if ind >= self.length {
            panic!("index out of bounds");
        }

        unsafe {
            let ptr = self.data.as_ptr();

            &*ptr.offset(ind as isize)
        }
    }
}

pub struct IntArray {
    ptr: *mut i32,
    length: usize,
}

impl IntArray {
    pub fn empty() -> IntArray {
        IntArray {
            ptr: ptr::null_mut(),
            length: 0,
        }
    }

    pub fn with_element(gc: &mut Gc, length: usize, elem: isize) -> IntArray {
        if length < 0 {
            panic!("length needs to be greater or equal to 0.");
        }

        let ptr = if length > 0 {
            gc.alloc(std::mem::size_of::<i32>() * length).raw() as *mut i32
        } else {
            ptr::null_mut()
        };

        for i in 0..length {
            unsafe {
                *ptr.offset(i as isize) = elem as i32;
            }
        }

        IntArray {
            ptr: ptr,
            length: length,
        }
    }

    pub fn size() -> usize {
        std::mem::size_of::<IntArray>()
    }

    pub fn len(&self) -> usize {
        self.length
    }

    pub fn get(&self, ind: i32) -> i32 {
        if ind < 0 || ind as usize >= self.length {
            panic!("index out of bounds");
        }

        unsafe {
            *self.ptr.offset(ind as isize)
        }
    }

    pub fn set(&self, ind: i32, value: i32) {
        if ind < 0 || ind as usize >= self.length {
            panic!("index out of bounds");
        }

        unsafe {
            *self.ptr.offset(ind as isize) = value;
        }
    }
}

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

    use gc::Gc;
    use libc;

    #[test]
    pub fn test_create_string() {
        let mut gc = Gc::new();
        let string = Str::from_buffer(&mut gc, "hello world!".as_bytes());

        unsafe {
            assert_eq!(12, string.len());

            let expected = "hello world!".as_ptr() as *const i8;
            let value = string.data() as *const i8;
            assert_eq!(0, libc::strncmp(expected, value, string.len()));
        }
    }
}
<|endoftext|>


<commit_before>use super::interface::DBusInterface;

extern crate core;
use self::core::ops::Deref;

extern crate dbus;
use self::dbus::{Connection, Error};

use std::collections::btree_map::BTreeMap;

pub struct DBusObject<'a> {
    ifaces: BTreeMap<String, Box<DBusInterface>>,

    conn: &'a Connection,
    path: String,
}

impl<'a> DBusObject<'a> {
    pub fn new(conn: &'a Connection, ifaces: BTreeMap<String, Box<DBusInterface>>, path: &str) -> Result<Self, Error> {
        try!(conn.register_object_path(path));

        Ok(DBusObject {
            ifaces: ifaces,

            conn: conn,
            path: path.to_string(),
        })
    }

    pub fn path(&self) -> &str {
        &self.path[..]
    }

    pub fn get_interface(&self, interface: &str) -> Option<&DBusInterface> {
        self.ifaces.get(interface).map(|iface| {
            iface.deref()
        })
    }
}

impl<'a> Drop for DBusObject<'a> {
    fn drop(&mut self) {
        self.conn.unregister_object_path(self.path())
    }
}
<commit_msg>object: remove unnecessary &String[..]<commit_after>use super::interface::DBusInterface;

extern crate core;
use self::core::ops::Deref;

extern crate dbus;
use self::dbus::{Connection, Error};

use std::collections::btree_map::BTreeMap;

pub struct DBusObject<'a> {
    ifaces: BTreeMap<String, Box<DBusInterface>>,

    conn: &'a Connection,
    path: String,
}

impl<'a> DBusObject<'a> {
    pub fn new(conn: &'a Connection, ifaces: BTreeMap<String, Box<DBusInterface>>, path: &str) -> Result<Self, Error> {
        try!(conn.register_object_path(path));

        Ok(DBusObject {
            ifaces: ifaces,

            conn: conn,
            path: path.to_string(),
        })
    }

    pub fn path(&self) -> &str {
        &self.path
    }

    pub fn get_interface(&self, interface: &str) -> Option<&DBusInterface> {
        self.ifaces.get(interface).map(|iface| {
            iface.deref()
        })
    }
}

impl<'a> Drop for DBusObject<'a> {
    fn drop(&mut self) {
        self.conn.unregister_object_path(self.path())
    }
}
<|endoftext|>


<commit_before>use common::*;
use nalgebra::Pnt3;
use nalgebra::partial_lt;
use ncollide::bounding_volume::{AABB, AABB3};
use ncollide::bounding_volume::BoundingVolume;
use ncollide::ray::{Ray3, LocalRayCast};
use std::hash::Hash;
use std::num::NumCast;
use std::ptr::RawPtr;

fn aabb_overlap(aabb1: &AABB3<f32>, aabb2: &AABB3<f32>) -> bool {
  partial_lt(aabb1.mins(), aabb2.maxs()) &&
  partial_lt(aabb2.mins(), aabb1.maxs())
}

fn length(bounds: &AABB3<f32>, d: Dimension) -> f32 {
  get(d, bounds.maxs()) - get(d, bounds.mins())
}

fn middle(bounds: &AABB3<f32>, d: Dimension) -> f32 {
  (get(d, bounds.maxs()) + get(d, bounds.mins())) / 2.0
}

fn get(d: Dimension, p: &Pnt3<f32>) -> f32 {
  match d {
    Dimension::X => p.x,
    Dimension::Y => p.y,
    Dimension::Z => p.z,
  }
}

fn set(d: Dimension, p: &mut Pnt3<f32>, v: f32) {
  match d {
    Dimension::X => p.x = v,
    Dimension::Y => p.y = v,
    Dimension::Z => p.z = v,
  }
}

fn split(mid: f32, d: Dimension, bounds: AABB3<f32>) -> (Option<AABB3<f32>>, Option<AABB3<f32>>) {
  if get(d, bounds.maxs()) <= mid {
    (Some(bounds), None)
  } else if get(d, bounds.mins()) >= mid {
    (None, Some(bounds))
  } else {
    let (new_min, new_max) = {
      let (mut new_min, mut new_max) = (bounds.mins().clone(), bounds.maxs().clone());
      set(d, &mut new_min, mid.clone());
      set(d, &mut new_max, mid);
      (new_min, new_max)
    };
    (
      Some(AABB::new(*bounds.mins(), new_max)),
      Some(AABB::new(new_min, *bounds.maxs()))
    )
  }
}

#[deriving(Copy)]
pub enum Dimension { X, Y, Z }

struct Branches<V> {
  low_tree: Box<Octree<V>>,
  high_tree: Box<Octree<V>>,
}

type LeafContents<V> = Vec<(AABB3<f32>, V)>;

enum OctreeContents<V> {
  Leaf(LeafContents<V>),
  Branch(Branches<V>),
}

// TODO: allow inserting things with a "mobile" flag; don't subdivide those objects.
pub struct Octree<V> {
  parent: *mut Octree<V>,
  dimension: Dimension,
  bounds: AABB3<f32>,
  contents: OctreeContents<V>,
}

// TODO: fix shaky octree outline insertion/removal conditions.

impl<V: Copy + Eq + PartialOrd + Hash> Octree<V> {
  pub fn new(bounds: &AABB3<f32>) -> Octree<V> {
    Octree {
      parent: RawPtr::null(),
      dimension: Dimension::X,
      bounds: bounds.clone(),
      contents: OctreeContents::Leaf(Vec::new()),
    }
  }

  pub fn insert(&mut self, bounds: AABB3<f32>, v: V) {
    assert!(self.bounds.contains(&bounds));
    let contents = match self.contents {
      OctreeContents::Leaf(ref mut vs) => {
        vs.push((bounds, v));

        let d = self.dimension;
        let avg_length =
          vs.iter().fold(
            0.0,
            |x, &(ref bounds, _)| x + length(bounds, d)
          ) / NumCast::from(vs.len()).unwrap();

        if avg_length < length(&self.bounds, self.dimension) / 2.0 {
          let (low, high) =
            Octree::bisect(
              self,
              &self.bounds,
              self.dimension,
              vs
            );
          Some(OctreeContents::Branch(Branches { low_tree: box low, high_tree: box high }))
        } else {
          None
        }
      },
      OctreeContents::Branch(ref mut b) => {
        // copied in remove()
        let (l, h) = split(middle(&self.bounds, self.dimension), self.dimension, bounds);
        l.map(|low_half| b.low_tree.insert(low_half, v));
        h.map(|high_half| b.high_tree.insert(high_half, v));
        None
      },
    };
    contents.map(|c| self.contents = c);
  }

  // Split a leaf into two subtrees.
  fn bisect(
    parent: *mut Octree<V>,
    bounds: &AABB3<f32>,
    dimension: Dimension,
    vs: &LeafContents<V>
  ) -> (Octree<V>, Octree<V>) {
    let mid = middle(bounds, dimension);
    let (low_bounds, high_bounds) = split(mid, dimension, bounds.clone());
    let low_bounds = low_bounds.unwrap();
    let high_bounds = high_bounds.unwrap();
    let new_d = match dimension {
        Dimension::X => Dimension::Y,
        Dimension::Y => Dimension::Z,
        Dimension::Z => Dimension::X,
      };

    let mut low = Octree {
      parent: parent,
      dimension: new_d,
      bounds: low_bounds.clone(),
      contents: OctreeContents::Leaf(Vec::new()),
    };
    let mut high = Octree {
      parent: parent,
      dimension: new_d,
      bounds: high_bounds.clone(),
      contents: OctreeContents::Leaf(Vec::new()),
    };

    for &(ref bounds, v) in vs.iter() {
      let (low_bounds, high_bounds) = split(mid, dimension, bounds.clone());
      low_bounds.map(|bs| low.insert(bs, v));
      high_bounds.map(|bs| high.insert(bs, v));
    }

    (low, high)
  }

  #[allow(dead_code)]
  fn on_ancestor<T>(&self, bounds: &AABB3<f32>, f: |&Octree<V>| -> T) -> T {
    if self.bounds.contains(bounds) {
      f(self)
    } else {
      unsafe {
        assert!(self.parent.is_not_null());
        (*self.parent).on_ancestor(bounds, f)
      }
    }
  }

  fn on_mut_ancestor<T>(&mut self, bounds: &AABB3<f32>, f: |&mut Octree<V>| -> T) -> T {
    if self.bounds.contains(bounds) {
      f(self)
    } else {
      unsafe {
        assert!(self.parent.is_not_null());
        (*self.parent).on_mut_ancestor(bounds, f)
      }
    }
  }

  // Find whether there are objects overlapping the object & bounds provided in
  // this/child trees. Uses equality comparison on V to ignore "same" objects.
  // Returns the value associated with the first object intersected.
  pub fn intersect(&self, bounds: &AABB3<f32>, self_v: Option<V>) -> Option<(AABB3<f32>, V)> {
    match self.contents {
      OctreeContents::Leaf(ref vs) => {
        vs.iter()
          .find(|&&(ref bs, ref v)| Some(*v) != self_v && aabb_overlap(bounds, bs))
          .map(|&(ref bounds, v)| (bounds.clone(), v))
      },
      OctreeContents::Branch(ref b) => {
        let mid = middle(&self.bounds, self.dimension);
        let (low_bounds, high_bounds) = split(mid, self.dimension, bounds.clone());
        let high = |high_bounds| {
          match high_bounds {
            None => None,
            Some(bs) => b.high_tree.intersect(&bs, self_v),
          }
        };
        match low_bounds {
          None => high(high_bounds),
          Some(bs) =>
            match b.low_tree.intersect(&bs, self_v) {
              None => high(high_bounds),
              r => r,
            }
        }
      },
    }
  }

  // like insert, but before recursing downward, we recurse up the parents
  // until the bounds provided are inside the tree.
  fn insert_from(&mut self, bounds: AABB3<f32>, v: V) {
    self.on_mut_ancestor(&bounds, |t| t.insert(bounds.clone(), v))
  }

  pub fn remove(&mut self, bounds: &AABB3<f32>, v: V) {
    assert!(self.bounds.contains(bounds));
    let collapse_contents = match self.contents {
      OctreeContents::Leaf(ref mut vs) => {
        let i = vs.iter().position(|&(_, ref x)| *x == v).unwrap();
        vs.swap_remove(i);
        false
      },
      OctreeContents::Branch(ref mut bs) => {
        let (l, h) = split(middle(&self.bounds, self.dimension), self.dimension, bounds.clone());
        l.map(|low_half| bs.low_tree.remove(&low_half, v));
        h.map(|high_half| bs.high_tree.remove(&high_half, v));
        bs.low_tree.is_empty() && bs.high_tree.is_empty()
      }
    };

    if collapse_contents {
      self.contents = OctreeContents::Leaf(Vec::new());
    }
  }

  pub fn is_empty(&self) -> bool {
    match self.contents {
      OctreeContents::Leaf(ref vs) => vs.is_empty(),
      _ => false,
    }
  }

  pub fn reinsert(&mut self, v: V, bounds: &AABB3<f32>, new_bounds: AABB3<f32>) {
    self.remove(bounds, v);
    self.insert_from(new_bounds, v)
  }

  #[allow(dead_code)]
  pub fn cast_ray(&self, ray: &Ray3<f32>, self_v: V) -> Vec<V> {
    match self.contents {
      OctreeContents::Leaf(ref vs) => {
        // find the time of intersection (TOI) of the ray with each object in
        // this leaf; filter out the objects it doesn't intersect at all. Then
        // find the object with the lowest TOI.
        partial_min_by(
          vs.iter().filter_map(|&(ref bounds, v)| {
              if v == self_v {
                None
              } else {
                bounds.toi_with_ray(ray, true).map(|x| (x, v))
              }
            }
          ),
          |(toi, _)| toi
        )
        .into_iter().map(|(_, v)| v).collect()
      },
      OctreeContents::Branch(ref bs) => {
        let mut trees: Vec<(f32, &Box<Octree<V>>)> = Vec::new();
        let ref l = bs.low_tree;
        let ref h = bs.high_tree;
        for &t in [l, h].iter() {
          (**t).bounds.toi_with_ray(ray, true).map(|toi| trees.push((toi, t)));
        }
        trees.sort_by(|&(t1, _), &(t2, _)| {
          if t1 < t2 {
            Less
          } else if t1 > t2 {
            Greater
          } else {
            Equal
          }
        });
        for &(_, t) in trees.iter() {
          let r = t.cast_ray(ray, self_v);
          if !r.is_empty() {
            return r;
          }
        }
        Vec::new()
      }
    }
  }
}
<commit_msg>Impose minimum octree cell width<commit_after>use common::*;
use nalgebra::Pnt3;
use nalgebra::partial_lt;
use ncollide::bounding_volume::{AABB, AABB3};
use ncollide::bounding_volume::BoundingVolume;
use ncollide::ray::{Ray3, LocalRayCast};
use std::hash::Hash;
use std::num::NumCast;
use std::ptr::RawPtr;

pub const MIN_CELL_WIDTH: f32 = 0.1;

fn aabb_overlap(aabb1: &AABB3<f32>, aabb2: &AABB3<f32>) -> bool {
  partial_lt(aabb1.mins(), aabb2.maxs()) &&
  partial_lt(aabb2.mins(), aabb1.maxs())
}

fn length(bounds: &AABB3<f32>, d: Dimension) -> f32 {
  get(d, bounds.maxs()) - get(d, bounds.mins())
}

fn middle(bounds: &AABB3<f32>, d: Dimension) -> f32 {
  (get(d, bounds.maxs()) + get(d, bounds.mins())) / 2.0
}

fn get(d: Dimension, p: &Pnt3<f32>) -> f32 {
  match d {
    Dimension::X => p.x,
    Dimension::Y => p.y,
    Dimension::Z => p.z,
  }
}

fn set(d: Dimension, p: &mut Pnt3<f32>, v: f32) {
  match d {
    Dimension::X => p.x = v,
    Dimension::Y => p.y = v,
    Dimension::Z => p.z = v,
  }
}

fn split(mid: f32, d: Dimension, bounds: AABB3<f32>) -> (Option<AABB3<f32>>, Option<AABB3<f32>>) {
  if get(d, bounds.maxs()) <= mid {
    (Some(bounds), None)
  } else if get(d, bounds.mins()) >= mid {
    (None, Some(bounds))
  } else {
    let (new_min, new_max) = {
      let (mut new_min, mut new_max) = (bounds.mins().clone(), bounds.maxs().clone());
      set(d, &mut new_min, mid.clone());
      set(d, &mut new_max, mid);
      (new_min, new_max)
    };
    (
      Some(AABB::new(*bounds.mins(), new_max)),
      Some(AABB::new(new_min, *bounds.maxs()))
    )
  }
}

#[deriving(Copy)]
pub enum Dimension { X, Y, Z }

struct Branches<V> {
  low_tree: Box<Octree<V>>,
  high_tree: Box<Octree<V>>,
}

type LeafContents<V> = Vec<(AABB3<f32>, V)>;

enum OctreeContents<V> {
  Leaf(LeafContents<V>),
  Branch(Branches<V>),
}

// TODO: allow inserting things with a "mobile" flag; don't subdivide those objects.
pub struct Octree<V> {
  parent: *mut Octree<V>,
  dimension: Dimension,
  bounds: AABB3<f32>,
  contents: OctreeContents<V>,
}

// TODO: fix shaky octree outline insertion/removal conditions.

impl<V: Copy + Eq + PartialOrd + Hash> Octree<V> {
  pub fn new(bounds: &AABB3<f32>) -> Octree<V> {
    Octree {
      parent: RawPtr::null(),
      dimension: Dimension::X,
      bounds: bounds.clone(),
      contents: OctreeContents::Leaf(Vec::new()),
    }
  }

  pub fn insert(&mut self, bounds: AABB3<f32>, v: V) {
    assert!(self.bounds.contains(&bounds));
    let contents = match self.contents {
      OctreeContents::Leaf(ref mut vs) => {
        vs.push((bounds, v));

        let d = self.dimension;
        let avg_length =
          vs.iter().fold(
            0.0,
            |x, &(ref bounds, _)| x + length(bounds, d)
          ) / NumCast::from(vs.len()).unwrap();

        let l = length(&self.bounds, self.dimension);
        let should_bisect_cell =
          l > MIN_CELL_WIDTH && avg_length < length(&self.bounds, self.dimension) / 2.0;
        if should_bisect_cell {
          let (low, high) =
            Octree::bisect(
              self,
              &self.bounds,
              self.dimension,
              vs
            );
          Some(OctreeContents::Branch(Branches { low_tree: box low, high_tree: box high }))
        } else {
          None
        }
      },
      OctreeContents::Branch(ref mut b) => {
        // copied in remove()
        let (l, h) = split(middle(&self.bounds, self.dimension), self.dimension, bounds);
        l.map(|low_half| b.low_tree.insert(low_half, v));
        h.map(|high_half| b.high_tree.insert(high_half, v));
        None
      },
    };
    contents.map(|c| self.contents = c);
  }

  // Split a leaf into two subtrees.
  fn bisect(
    parent: *mut Octree<V>,
    bounds: &AABB3<f32>,
    dimension: Dimension,
    vs: &LeafContents<V>
  ) -> (Octree<V>, Octree<V>) {
    let mid = middle(bounds, dimension);
    let (low_bounds, high_bounds) = split(mid, dimension, bounds.clone());
    let low_bounds = low_bounds.unwrap();
    let high_bounds = high_bounds.unwrap();
    let new_d = match dimension {
        Dimension::X => Dimension::Y,
        Dimension::Y => Dimension::Z,
        Dimension::Z => Dimension::X,
      };

    let mut low = Octree {
      parent: parent,
      dimension: new_d,
      bounds: low_bounds.clone(),
      contents: OctreeContents::Leaf(Vec::new()),
    };
    let mut high = Octree {
      parent: parent,
      dimension: new_d,
      bounds: high_bounds.clone(),
      contents: OctreeContents::Leaf(Vec::new()),
    };

    for &(ref bounds, v) in vs.iter() {
      let (low_bounds, high_bounds) = split(mid, dimension, bounds.clone());
      low_bounds.map(|bs| low.insert(bs, v));
      high_bounds.map(|bs| high.insert(bs, v));
    }

    (low, high)
  }

  #[allow(dead_code)]
  fn on_ancestor<T>(&self, bounds: &AABB3<f32>, f: |&Octree<V>| -> T) -> T {
    if self.bounds.contains(bounds) {
      f(self)
    } else {
      unsafe {
        assert!(self.parent.is_not_null());
        (*self.parent).on_ancestor(bounds, f)
      }
    }
  }

  fn on_mut_ancestor<T>(&mut self, bounds: &AABB3<f32>, f: |&mut Octree<V>| -> T) -> T {
    if self.bounds.contains(bounds) {
      f(self)
    } else {
      unsafe {
        assert!(self.parent.is_not_null());
        (*self.parent).on_mut_ancestor(bounds, f)
      }
    }
  }

  // Find whether there are objects overlapping the object & bounds provided in
  // this/child trees. Uses equality comparison on V to ignore "same" objects.
  // Returns the value associated with the first object intersected.
  pub fn intersect(&self, bounds: &AABB3<f32>, self_v: Option<V>) -> Option<(AABB3<f32>, V)> {
    match self.contents {
      OctreeContents::Leaf(ref vs) => {
        vs.iter()
          .find(|&&(ref bs, ref v)| Some(*v) != self_v && aabb_overlap(bounds, bs))
          .map(|&(ref bounds, v)| (bounds.clone(), v))
      },
      OctreeContents::Branch(ref b) => {
        let mid = middle(&self.bounds, self.dimension);
        let (low_bounds, high_bounds) = split(mid, self.dimension, bounds.clone());
        let high = |high_bounds| {
          match high_bounds {
            None => None,
            Some(bs) => b.high_tree.intersect(&bs, self_v),
          }
        };
        match low_bounds {
          None => high(high_bounds),
          Some(bs) =>
            match b.low_tree.intersect(&bs, self_v) {
              None => high(high_bounds),
              r => r,
            }
        }
      },
    }
  }

  // like insert, but before recursing downward, we recurse up the parents
  // until the bounds provided are inside the tree.
  fn insert_from(&mut self, bounds: AABB3<f32>, v: V) {
    self.on_mut_ancestor(&bounds, |t| t.insert(bounds.clone(), v))
  }

  pub fn remove(&mut self, bounds: &AABB3<f32>, v: V) {
    assert!(self.bounds.contains(bounds));
    let collapse_contents = match self.contents {
      OctreeContents::Leaf(ref mut vs) => {
        let i = vs.iter().position(|&(_, ref x)| *x == v).unwrap();
        vs.swap_remove(i);
        false
      },
      OctreeContents::Branch(ref mut bs) => {
        let (l, h) = split(middle(&self.bounds, self.dimension), self.dimension, bounds.clone());
        l.map(|low_half| bs.low_tree.remove(&low_half, v));
        h.map(|high_half| bs.high_tree.remove(&high_half, v));
        bs.low_tree.is_empty() && bs.high_tree.is_empty()
      }
    };

    if collapse_contents {
      self.contents = OctreeContents::Leaf(Vec::new());
    }
  }

  pub fn is_empty(&self) -> bool {
    match self.contents {
      OctreeContents::Leaf(ref vs) => vs.is_empty(),
      _ => false,
    }
  }

  pub fn reinsert(&mut self, v: V, bounds: &AABB3<f32>, new_bounds: AABB3<f32>) {
    self.remove(bounds, v);
    self.insert_from(new_bounds, v)
  }

  #[allow(dead_code)]
  pub fn cast_ray(&self, ray: &Ray3<f32>, self_v: V) -> Vec<V> {
    match self.contents {
      OctreeContents::Leaf(ref vs) => {
        // find the time of intersection (TOI) of the ray with each object in
        // this leaf; filter out the objects it doesn't intersect at all. Then
        // find the object with the lowest TOI.
        partial_min_by(
          vs.iter().filter_map(|&(ref bounds, v)| {
              if v == self_v {
                None
              } else {
                bounds.toi_with_ray(ray, true).map(|x| (x, v))
              }
            }
          ),
          |(toi, _)| toi
        )
        .into_iter().map(|(_, v)| v).collect()
      },
      OctreeContents::Branch(ref bs) => {
        let mut trees: Vec<(f32, &Box<Octree<V>>)> = Vec::new();
        let ref l = bs.low_tree;
        let ref h = bs.high_tree;
        for &t in [l, h].iter() {
          (**t).bounds.toi_with_ray(ray, true).map(|toi| trees.push((toi, t)));
        }
        trees.sort_by(|&(t1, _), &(t2, _)| {
          if t1 < t2 {
            Less
          } else if t1 > t2 {
            Greater
          } else {
            Equal
          }
        });
        for &(_, t) in trees.iter() {
          let r = t.cast_ray(ray, self_v);
          if !r.is_empty() {
            return r;
          }
        }
        Vec::new()
      }
    }
  }
}
<|endoftext|>


<commit_before>// Copyright 2015 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 std::fmt;
use std::io;
use std::mem;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
#[cfg(unix)]
use libc::c_int;
#[cfg(windows)]
use winapi::c_int;

use sys;
use sys::c;

pub struct Socket {
    inner: sys::Socket,
}

impl Socket {
    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
        Ok(Socket { inner: try!(sys::Socket::new(family, ty)) })
    }

    pub fn bind(&self, addr: &SocketAddr) -> io::Result<()> {
        #[cfg(not(all(target_arch = "aarch64",target_os = "android")))]
        use sys::c::socklen_t as len_t;
        #[cfg(all(target_arch = "aarch64",target_os = "android"))]
        use libc::c_int as len_t;

        let (addr, len) = addr2raw(addr);
        unsafe {
            ::cvt(c::bind(self.inner.raw(), addr, len as len_t)).map(|_| ())
        }
    }

    pub fn listen(&self, backlog: i32) -> io::Result<()> {
        unsafe {
            ::cvt(c::listen(self.inner.raw(), backlog)).map(|_| ())
        }
    }

    pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
        let (addr, len) = addr2raw(addr);
        unsafe {
            ::cvt(c::connect(self.inner.raw(), addr, len)).map(|_| ())
        }
    }

    pub fn getsockname(&self) -> io::Result<SocketAddr> {
        unsafe {
            let mut storage: c::sockaddr_storage = mem::zeroed();
            let mut len = mem::size_of_val(&storage) as c::socklen_t;
            try!(::cvt(c::getsockname(self.inner.raw(),
                                      &mut storage as *mut _ as *mut _,
                                      &mut len)));
            raw2addr(&storage, len)
        }
    }
}

impl fmt::Debug for Socket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.inner.raw().fmt(f)
    }
}

impl ::AsInner for Socket {
    type Inner = sys::Socket;
    fn as_inner(&self) -> &sys::Socket { &self.inner }
}

impl ::FromInner for Socket {
    type Inner = sys::Socket;
    fn from_inner(sock: sys::Socket) -> Socket {
        Socket { inner: sock }
    }
}

impl ::IntoInner for Socket {
    type Inner = sys::Socket;
    fn into_inner(self) -> sys::Socket { self.inner }
}

fn addr2raw(addr: &SocketAddr) -> (*const c::sockaddr, c::socklen_t) {
    match *addr {
        SocketAddr::V4(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
        }
        SocketAddr::V6(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
        }
    }
}

fn raw2addr(storage: &c::sockaddr_storage, len: c::socklen_t) -> io::Result<SocketAddr> {
    match storage.ss_family as c_int {
        c::AF_INET => {
            unsafe {
                assert!(len as usize >= mem::size_of::<c::sockaddr_in>());
                let sa = storage as *const _ as *const c::sockaddr_in;
                let bits = c::sockaddr_in_u32(&(*sa));
                let ip = Ipv4Addr::new((bits >> 24) as u8,
                                       (bits >> 16) as u8,
                                       (bits >> 8) as u8,
                                       bits as u8);
                Ok(SocketAddr::V4(SocketAddrV4::new(ip, ::ntoh((*sa).sin_port))))
            }
        }
        c::AF_INET6 => {
            unsafe {
                assert!(len as usize >= mem::size_of::<c::sockaddr_in6>());

                let sa = storage as *const _ as *const c::sockaddr_in6;
                let arr = (*sa).sin6_addr.s6_addr;

                let ip = Ipv6Addr::new(
                    (arr[0] as u16) << 8 | (arr[1] as u16),
                    (arr[2] as u16) << 8 | (arr[3] as u16),
                    (arr[4] as u16) << 8 | (arr[5] as u16),
                    (arr[6] as u16) << 8 | (arr[7] as u16),
                    (arr[8] as u16) << 8 | (arr[9] as u16),
                    (arr[10] as u16) << 8 | (arr[11] as u16),
                    (arr[12] as u16) << 8 | (arr[13] as u16),
                    (arr[14] as u16) << 8 | (arr[15] as u16),
                );

                Ok(SocketAddr::V6(SocketAddrV6::new(ip,
                                                    ::ntoh((*sa).sin6_port),
                                                    (*sa).sin6_flowinfo,
                                                    (*sa).sin6_scope_id)))
            }
        }
        _ => Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid argument")),
    }
}
<commit_msg>Fix x86_64-android socket type<commit_after>// Copyright 2015 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 std::fmt;
use std::io;
use std::mem;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
#[cfg(unix)]
use libc::c_int;
#[cfg(windows)]
use winapi::c_int;

use sys;
use sys::c;

pub struct Socket {
    inner: sys::Socket,
}

impl Socket {
    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
        Ok(Socket { inner: try!(sys::Socket::new(family, ty)) })
    }

    pub fn bind(&self, addr: &SocketAddr) -> io::Result<()> {
        #[cfg(not(all(any(target_arch = "aarch64", target_arch = "x86_64"), target_os = "android")))]
        use sys::c::socklen_t as len_t;
        #[cfg(all(any(target_arch = "aarch64", target_arch = "x86_64"), target_os = "android"))]
        use libc::c_int as len_t;

        let (addr, len) = addr2raw(addr);
        unsafe {
            ::cvt(c::bind(self.inner.raw(), addr, len as len_t)).map(|_| ())
        }
    }

    pub fn listen(&self, backlog: i32) -> io::Result<()> {
        unsafe {
            ::cvt(c::listen(self.inner.raw(), backlog)).map(|_| ())
        }
    }

    pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
        let (addr, len) = addr2raw(addr);
        unsafe {
            ::cvt(c::connect(self.inner.raw(), addr, len)).map(|_| ())
        }
    }

    pub fn getsockname(&self) -> io::Result<SocketAddr> {
        unsafe {
            let mut storage: c::sockaddr_storage = mem::zeroed();
            let mut len = mem::size_of_val(&storage) as c::socklen_t;
            try!(::cvt(c::getsockname(self.inner.raw(),
                                      &mut storage as *mut _ as *mut _,
                                      &mut len)));
            raw2addr(&storage, len)
        }
    }
}

impl fmt::Debug for Socket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.inner.raw().fmt(f)
    }
}

impl ::AsInner for Socket {
    type Inner = sys::Socket;
    fn as_inner(&self) -> &sys::Socket { &self.inner }
}

impl ::FromInner for Socket {
    type Inner = sys::Socket;
    fn from_inner(sock: sys::Socket) -> Socket {
        Socket { inner: sock }
    }
}

impl ::IntoInner for Socket {
    type Inner = sys::Socket;
    fn into_inner(self) -> sys::Socket { self.inner }
}

fn addr2raw(addr: &SocketAddr) -> (*const c::sockaddr, c::socklen_t) {
    match *addr {
        SocketAddr::V4(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
        }
        SocketAddr::V6(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
        }
    }
}

fn raw2addr(storage: &c::sockaddr_storage, len: c::socklen_t) -> io::Result<SocketAddr> {
    match storage.ss_family as c_int {
        c::AF_INET => {
            unsafe {
                assert!(len as usize >= mem::size_of::<c::sockaddr_in>());
                let sa = storage as *const _ as *const c::sockaddr_in;
                let bits = c::sockaddr_in_u32(&(*sa));
                let ip = Ipv4Addr::new((bits >> 24) as u8,
                                       (bits >> 16) as u8,
                                       (bits >> 8) as u8,
                                       bits as u8);
                Ok(SocketAddr::V4(SocketAddrV4::new(ip, ::ntoh((*sa).sin_port))))
            }
        }
        c::AF_INET6 => {
            unsafe {
                assert!(len as usize >= mem::size_of::<c::sockaddr_in6>());

                let sa = storage as *const _ as *const c::sockaddr_in6;
                let arr = (*sa).sin6_addr.s6_addr;

                let ip = Ipv6Addr::new(
                    (arr[0] as u16) << 8 | (arr[1] as u16),
                    (arr[2] as u16) << 8 | (arr[3] as u16),
                    (arr[4] as u16) << 8 | (arr[5] as u16),
                    (arr[6] as u16) << 8 | (arr[7] as u16),
                    (arr[8] as u16) << 8 | (arr[9] as u16),
                    (arr[10] as u16) << 8 | (arr[11] as u16),
                    (arr[12] as u16) << 8 | (arr[13] as u16),
                    (arr[14] as u16) << 8 | (arr[15] as u16),
                );

                Ok(SocketAddr::V6(SocketAddrV6::new(ip,
                                                    ::ntoh((*sa).sin6_port),
                                                    (*sa).sin6_flowinfo,
                                                    (*sa).sin6_scope_id)))
            }
        }
        _ => Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid argument")),
    }
}
<|endoftext|>


<commit_before>use std::hash::{Hash};
use std::slice::{
    Items,
};
use std::fmt;
use test;

#[deriving(Copy, Clone, Show, PartialEq, PartialOrd, Eq, Hash)]
pub struct NodeIndex(uint);
#[deriving(Copy, Clone, Show, PartialEq, PartialOrd, Eq, Hash)]
pub struct EdgeIndex(uint);

const EdgeEnd: EdgeIndex = EdgeIndex(::std::uint::MAX);
//const InvalidNode: NodeIndex = NodeIndex(::std::uint::MAX);

/// Index into the EdgeIndex arrays
enum Dir {
    Out = 0,
    In = 1
}

#[deriving(Show)]
pub struct Node<N> {
    pub data: N,
    next: [EdgeIndex, ..2],
}

#[deriving(Show, Copy)]
pub struct Edge<E> {
    pub data: E,
    next: [EdgeIndex, ..2],
    a: NodeIndex,
    b: NodeIndex,
}

/// **OGraph\<N, E\>** is a directed graph using an adjacency list representation.
///
/// The graph maintains unique indices for nodes and edges, so both node and edge
/// data may be accessed mutably. Removing nodes or edges from the graph is expensive,
/// while adding is very cheap.
///
/// Based upon the graph implementation in rustc.
//#[deriving(Show)]
pub struct OGraph<N> {
    nodes: Vec<Node<N>>,
    edges: Vec<Edge<()>>,
}

impl<N: fmt::Show> fmt::Show for OGraph<N>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for n in self.nodes.iter() {
            try!(writeln!(f, "{}", n));
        }
        for n in self.edges.iter() {
            try!(writeln!(f, "{}", n));
        }
        Ok(())
    }
}

pub enum Pair<'a, T: 'a> {
    Both(&'a mut T, &'a mut T),
    One(&'a mut T),
    None,
}

pub fn index_twice<T>(slc: &mut [T], a: uint, b: uint) -> Pair<T>
{
    if a == b {
        slc.get_mut(a).map_or(Pair::None, Pair::One)
    } else {
        if a >= slc.len() || b >= slc.len() {
            Pair::None
        } else {
            // safe because a, b are in bounds and distinct
            unsafe {
                let ar = &mut *(slc.unsafe_mut(a) as *mut _);
                let br = &mut *(slc.unsafe_mut(b) as *mut _);
                Pair::Both(ar, br)
            }
        }
    }
}

impl<N> OGraph<N>
//where N: fmt::Show
{
    pub fn new() -> OGraph<N>
    {
        OGraph{nodes: Vec::new(), edges: Vec::new()}
    }

    pub fn add_node(&mut self, data: N) -> NodeIndex
    {
        let node = Node{data: data, next: [EdgeEnd, EdgeEnd]};
        let node_idx = NodeIndex(self.nodes.len());
        self.nodes.push(node);
        node_idx
    }

    pub fn node(&self, a: NodeIndex) -> Option<&N>
    {
        self.nodes.get(a.0).map(|n| &n.data)
    }

    pub fn node_mut(&mut self, a: NodeIndex) -> Option<&mut N>
    {
        self.nodes.get_mut(a.0).map(|n| &mut n.data)
    }

    pub fn neighbors(&self, a: NodeIndex) -> Neighbors<N>
    {
        Neighbors{
            graph: self,
            next: match self.nodes.get(a.0) {
                None => EdgeEnd,
                Some(n) => n.next[0],
            }
        }
    }

    pub fn add_edge(&mut self, a: NodeIndex, b: NodeIndex) -> EdgeIndex
    {
        let edge_idx = EdgeIndex(self.edges.len());
        match index_twice(self.nodes[mut], a.0, b.0) {
            Pair::None => panic!("NodeIndices out of bounds"),
            Pair::One(an) => {
                let edge = Edge {
                    data: (),
                    a: a,
                    b: b,
                    next: an.next,
                };
                an.next[0] = edge_idx;
                an.next[1] = edge_idx;
                self.edges.push(edge);
            }
            Pair::Both(an, bn) => {
                // a and b are different indices
                let edge = Edge {
                    data: (),
                    a: a,
                    b: b,
                    next: [an.next[0], bn.next[1]],
                };
                an.next[0] = edge_idx;
                bn.next[1] = edge_idx;
                self.edges.push(edge);
            }
        }
        edge_idx
    }

    pub fn remove_node(&mut self, a: NodeIndex) -> Option<N>
    {
        match self.nodes.get(a.0) {
            None => return None,
            _ => {}
        }
        // Remove all edges from and to this node.
        loop {
            let next = self.nodes[a.0].next[0];
            if next == EdgeEnd {
                break
            }
            //println!("Rmove edge {}", next);
            self.remove_edge(next);
        }

        loop {
            let next = self.nodes[a.0].next[1];
            if next == EdgeEnd {
                break
            }
            //println!("Rmove edge {}", next);
            self.remove_edge(next);
        }

        //println!("REMOVED EDGES: {}", self);

        // Adjust all node indices affected
        for edge in self.edges.iter_mut() {
            debug_assert!(edge.a != a);
            debug_assert!(edge.b != a);
            if edge.a > a {
                edge.a.0 -= 1;
            }
            if edge.b > a {
                edge.b.0 -= 1;
            }
        }
        self.nodes.remove(a.0).map(|n|n.data)
    }

    pub fn edge_mut(&mut self, e: EdgeIndex) -> &mut Edge<()>
    {
        &mut self.edges[e.0]
    }

    pub fn remove_edge(&mut self, e: EdgeIndex)
    {
        fn update_edge_list(replace: EdgeIndex, fst: EdgeIndex, edges: &mut [Edge<()>], d: Dir) {
            debug_assert!(fst != replace);
            let k = d as uint;
            let edge_next = edges[replace.0].next[k];
            // walk through edge list
            let mut cur = fst;
            while cur != EdgeEnd {
                let curedge = &mut edges[cur.0];
                if curedge.next[k] == replace {
                    //println!("Have to replace link in {}", curedge);
                    curedge.next[k] = edge_next;
                    break
                } else {
                    cur = curedge.next[k];
                }
            }
        }
        // every edge is part of two lists,
        // outgoing and incoming edges.
        // Remove it from both
        let (edge_a, edge_b, edge_next) = match self.edges.get(e.0) {
            None => return,
            Some(x) => (x.a, x.b, x.next),
        };
        {
            // List out from A
            let node = &mut self.nodes[edge_a.0];
            let fst = node.next[0];
            if fst == e {
                node.next[0] = edge_next[0];
            } else {
                update_edge_list(e, fst, self.edges[mut], Dir::Out);
            }
        }
        {
            // List in to B
            let node = &mut self.nodes[edge_b.0];
            let fst = node.next[1];
            if fst == e {
                node.next[1] = edge_next[1];
            } else {
                update_edge_list(e, fst, self.edges[mut], Dir::In);
            }
        }
        self.remove_edge_adjust_indices(e);
    }

    fn remove_edge_adjust_indices(&mut self, e: EdgeIndex) -> Option<()>
    {
        // Edge lists are fine, so remove the edge and adjust all edge indices in nodes
        let edge_data = self.edges.remove(e.0).unwrap().data;
        for &k in [0u, 1].iter() {
            for node in self.nodes.iter_mut() {
                debug_assert!(node.next[k] != e);
                if node.next[k] != EdgeEnd && node.next[k] > e {
                    node.next[k].0 -= 1;
                }
            }
            for edge in self.edges.iter_mut() {
                debug_assert!(edge.next[k] != e);
                if edge.next[k] != EdgeEnd && edge.next[k] > e {
                    edge.next[k].0 -= 1;
                }
            }
        }
        Some(edge_data)
    }
}

pub struct Neighbors<'a, N: 'a> {
    graph: &'a OGraph<N>,
    next: EdgeIndex,
}

impl<'a, N> Iterator<NodeIndex> for Neighbors<'a, N>
{
    fn next(&mut self) -> Option<NodeIndex>
    {
        match self.graph.edges.get(self.next.0) {
            None => None,
            Some(edge) => {
                self.next = edge.next[0];
                Some(edge.b)
            }
        }
    }
}

#[bench]
fn bench_inser(b: &mut test::Bencher) {
    let mut og = OGraph::new();
    let fst = og.add_node(0i);
    for x in range(1, 125) {
        let n = og.add_node(x);
        og.add_edge(fst, n);
    }
    b.iter(|| {
        og.add_node(1)
    })
}

#[bench]
fn bench_remove(b: &mut test::Bencher) {
    // removal is very slow in a big graph.
    // and this one doesn't even have many nodes.
    let mut og = OGraph::new();
    let fst = og.add_node(0i);
    let mut prev = fst;
    for x in range(1, 1250) {
        let n = og.add_node(x);
        og.add_edge(prev, n);
        prev = n;
    }
    //println!("{}", og);
    b.iter(|| {
        og.remove_node(fst)
    })
}
<commit_msg>Implement .swap_remove removal of Edges<commit_after>use std::hash::{Hash};
use std::slice::{
    Items,
};
use std::fmt;
use test;

// FIXME: These aren't stable, so a public wrapper of node/edge indices
// should be lifetimed just like pointers.
#[deriving(Copy, Clone, Show, PartialEq, PartialOrd, Eq, Hash)]
pub struct NodeIndex(uint);
#[deriving(Copy, Clone, Show, PartialEq, PartialOrd, Eq, Hash)]
pub struct EdgeIndex(uint);

const EdgeEnd: EdgeIndex = EdgeIndex(::std::uint::MAX);
//const InvalidNode: NodeIndex = NodeIndex(::std::uint::MAX);

/// Index into the EdgeIndex arrays
enum Dir {
    Out = 0,
    In = 1
}

#[deriving(Show)]
pub struct Node<N> {
    pub data: N,
    next: [EdgeIndex, ..2],
}

#[deriving(Show, Copy)]
pub struct Edge<E> {
    pub data: E,
    next: [EdgeIndex, ..2],
    a: NodeIndex,
    b: NodeIndex,
}

/// **OGraph\<N, E\>** is a directed graph using an adjacency list representation.
///
/// The graph maintains unique indices for nodes and edges, so both node and edge
/// data may be accessed mutably. Removing nodes or edges from the graph is expensive,
/// while adding is very cheap.
///
/// Based upon the graph implementation in rustc.
//#[deriving(Show)]
pub struct OGraph<N> {
    nodes: Vec<Node<N>>,
    edges: Vec<Edge<()>>,
}

impl<N: fmt::Show> fmt::Show for OGraph<N>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for n in self.nodes.iter() {
            try!(writeln!(f, "{}", n));
        }
        for n in self.edges.iter() {
            try!(writeln!(f, "{}", n));
        }
        Ok(())
    }
}

pub enum Pair<'a, T: 'a> {
    Both(&'a mut T, &'a mut T),
    One(&'a mut T),
    None,
}

pub fn index_twice<T>(slc: &mut [T], a: uint, b: uint) -> Pair<T>
{
    if a == b {
        slc.get_mut(a).map_or(Pair::None, Pair::One)
    } else {
        if a >= slc.len() || b >= slc.len() {
            Pair::None
        } else {
            // safe because a, b are in bounds and distinct
            unsafe {
                let ar = &mut *(slc.unsafe_mut(a) as *mut _);
                let br = &mut *(slc.unsafe_mut(b) as *mut _);
                Pair::Both(ar, br)
            }
        }
    }
}

impl<N> OGraph<N>
//where N: fmt::Show
{
    pub fn new() -> OGraph<N>
    {
        OGraph{nodes: Vec::new(), edges: Vec::new()}
    }

    pub fn add_node(&mut self, data: N) -> NodeIndex
    {
        let node = Node{data: data, next: [EdgeEnd, EdgeEnd]};
        let node_idx = NodeIndex(self.nodes.len());
        self.nodes.push(node);
        node_idx
    }

    pub fn node(&self, a: NodeIndex) -> Option<&N>
    {
        self.nodes.get(a.0).map(|n| &n.data)
    }

    pub fn node_mut(&mut self, a: NodeIndex) -> Option<&mut N>
    {
        self.nodes.get_mut(a.0).map(|n| &mut n.data)
    }

    pub fn neighbors(&self, a: NodeIndex) -> Neighbors<N>
    {
        Neighbors{
            graph: self,
            next: match self.nodes.get(a.0) {
                None => EdgeEnd,
                Some(n) => n.next[0],
            }
        }
    }

    pub fn add_edge(&mut self, a: NodeIndex, b: NodeIndex) -> EdgeIndex
    {
        let edge_idx = EdgeIndex(self.edges.len());
        match index_twice(self.nodes[mut], a.0, b.0) {
            Pair::None => panic!("NodeIndices out of bounds"),
            Pair::One(an) => {
                let edge = Edge {
                    data: (),
                    a: a,
                    b: b,
                    next: an.next,
                };
                an.next[0] = edge_idx;
                an.next[1] = edge_idx;
                self.edges.push(edge);
            }
            Pair::Both(an, bn) => {
                // a and b are different indices
                let edge = Edge {
                    data: (),
                    a: a,
                    b: b,
                    next: [an.next[0], bn.next[1]],
                };
                an.next[0] = edge_idx;
                bn.next[1] = edge_idx;
                self.edges.push(edge);
            }
        }
        edge_idx
    }

    pub fn remove_node(&mut self, a: NodeIndex) -> Option<N>
    {
        match self.nodes.get(a.0) {
            None => return None,
            _ => {}
        }
        // Remove all edges from and to this node.
        loop {
            let next = self.nodes[a.0].next[0];
            if next == EdgeEnd {
                break
            }
            //println!("Rmove edge {}", next);
            self.remove_edge(next);
        }

        loop {
            let next = self.nodes[a.0].next[1];
            if next == EdgeEnd {
                break
            }
            //println!("Rmove edge {}", next);
            self.remove_edge(next);
        }

        //println!("REMOVED EDGES: {}", self);

        // Adjust all node indices affected
        for edge in self.edges.iter_mut() {
            debug_assert!(edge.a != a);
            debug_assert!(edge.b != a);
            if edge.a > a {
                edge.a.0 -= 1;
            }
            if edge.b > a {
                edge.b.0 -= 1;
            }
        }
        self.nodes.remove(a.0).map(|n|n.data)
    }

    pub fn edge_mut(&mut self, e: EdgeIndex) -> &mut Edge<()>
    {
        &mut self.edges[e.0]
    }

    pub fn remove_edge(&mut self, e: EdgeIndex)
    {
        fn update_edge_list(replace: EdgeIndex, fst: EdgeIndex, edges: &mut [Edge<()>], d: Dir) {
            debug_assert!(fst != replace);
            let k = d as uint;
            let edge_next = edges[replace.0].next[k];
            // walk through edge list
            let mut cur = fst;
            while cur != EdgeEnd {
                let curedge = &mut edges[cur.0];
                if curedge.next[k] == replace {
                    //println!("Have to replace link in {}", curedge);
                    curedge.next[k] = edge_next;
                    break
                } else {
                    cur = curedge.next[k];
                }
            }
        }
        // every edge is part of two lists,
        // outgoing and incoming edges.
        // Remove it from both
        let (edge_a, edge_b, edge_next) = match self.edges.get(e.0) {
            None => return,
            Some(x) => (x.a, x.b, x.next),
        };
        {
            // List out from A
            let node = &mut self.nodes[edge_a.0];
            let fst = node.next[0];
            if fst == e {
                node.next[0] = edge_next[0];
            } else {
                update_edge_list(e, fst, self.edges[mut], Dir::Out);
            }
        }
        {
            // List in to B
            let node = &mut self.nodes[edge_b.0];
            let fst = node.next[1];
            if fst == e {
                node.next[1] = edge_next[1];
            } else {
                update_edge_list(e, fst, self.edges[mut], Dir::In);
            }
        }
        self.remove_edge_adjust_indices(e);
    }

    fn remove_edge_adjust_indices(&mut self, e: EdgeIndex) -> Option<()>
    {
        // swap_remove the edge -- only the removed edge
        // and the edge swapped into place are affected and need updating
        // indices.
        let edge = self.edges.swap_remove(e.0).unwrap();
        if self.edges.len() == e.0 {
            return Some(edge.data);
        }
        let swapped_e = EdgeIndex(self.edges.len());
        let swapped_edge = self.edges[e.0];

        fn update_edge_list(replace: EdgeIndex, fst: EdgeIndex, new: EdgeIndex, edges: &mut [Edge<()>], d: Dir) {
            debug_assert!(fst != replace);
            let k = d as uint;
            // walk through edge list
            let mut cur = fst;
            while cur != EdgeEnd {
                let curedge = &mut edges[cur.0];
                if curedge.next[k] == replace {
                    //println!("Have to replace link in {}", curedge);
                    curedge.next[k] = new;
                    break
                } else {
                    cur = curedge.next[k];
                }
            }
        }
        {
            // List out from A
            let node = &mut self.nodes[swapped_edge.a.0];
            let fst = node.next[0];
            if fst == swapped_e {
                node.next[0] = e;
            } else {
                update_edge_list(swapped_e, fst, e, self.edges[mut], Dir::Out);
            }
        }
        {
            // List in to B
            let node = &mut self.nodes[swapped_edge.b.0];
            let fst = node.next[1];
            if fst == swapped_e {
                node.next[1] = e;
            } else {
                update_edge_list(swapped_e, fst, e, self.edges[mut], Dir::In);
            }
        }
        // All that refer to the swapped edge need to update.
        //
        /*
        // Edge lists are fine, so remove the edge and adjust all edge indices in nodes
        let edge_data = self.edges.remove(e.0).unwrap().data;
        for &k in [0u, 1].iter() {
            for node in self.nodes.iter_mut() {
                debug_assert!(node.next[k] != e);
                if node.next[k] != EdgeEnd && node.next[k] > e {
                    node.next[k].0 -= 1;
                }
            }
            for edge in self.edges.iter_mut() {
                debug_assert!(edge.next[k] != e);
                if edge.next[k] != EdgeEnd && edge.next[k] > e {
                    edge.next[k].0 -= 1;
                }
            }
        }
        */
        let edge_data = edge.data;
        Some(edge_data)
    }
}

pub struct Neighbors<'a, N: 'a> {
    graph: &'a OGraph<N>,
    next: EdgeIndex,
}

impl<'a, N> Iterator<NodeIndex> for Neighbors<'a, N>
{
    fn next(&mut self) -> Option<NodeIndex>
    {
        match self.graph.edges.get(self.next.0) {
            None => None,
            Some(edge) => {
                self.next = edge.next[0];
                Some(edge.b)
            }
        }
    }
}

#[bench]
fn bench_inser(b: &mut test::Bencher) {
    let mut og = OGraph::new();
    let fst = og.add_node(0i);
    for x in range(1, 125) {
        let n = og.add_node(x);
        og.add_edge(fst, n);
    }
    b.iter(|| {
        og.add_node(1)
    })
}

#[bench]
fn bench_remove(b: &mut test::Bencher) {
    // removal is very slow in a big graph.
    // and this one doesn't even have many nodes.
    let mut og = OGraph::new();
    let fst = og.add_node(0i);
    let mut prev = fst;
    for x in range(1, 1250) {
        let n = og.add_node(x);
        og.add_edge(prev, n);
        prev = n;
    }
    //println!("{}", og);
    b.iter(|| {
        for _ in range(0, 100i) {
            og.remove_node(fst);
        }
    })
}
<|endoftext|>


<commit_before>use nitro::App;
use nitro::Canvas;
use nitro::component::Component;
use nitro::component::Message;
use nitro::GameObject;
use axes::AxisId;
use actions::ActionId;

pub struct Spinny {}

impl Component for Spinny {
    fn receive_message(&mut self, app: &mut App, game_object: &mut GameObject, message: &Message) {
        match *message {
            Message::Start { .. } => {
                println!("Audio result: {:?}", app.audio.play_sound("example.ogg", 1.0));
            }

            Message::Update { delta_time } => {
                if let Some(horizontal) = app.input.get_axis_value(AxisId::Horizontal as i32) {
                    *game_object.transform.mut_position() += 100.0 * delta_time * horizontal *
                                                             game_object.transform.right();
                }
                if let Some(vertical) = app.input.get_axis_value(AxisId::Vertical as i32) {
                    *game_object.transform.mut_position() += 100.0 * delta_time * vertical *
                                                             game_object.transform.forward();
                }
                if let Some(rotation) = app.input.get_axis_value(AxisId::Rotation as i32) {
                    *game_object.transform.mut_rotation() += 1.0 * delta_time * rotation;
                }
                if let Some(true) = app.input.action_released(ActionId::Blink as i32) {
                    *game_object.transform.mut_x() += 50.0;
                }
            }
            _ => {}
        }
    }
    fn render_gui(&self, canvas: &mut Canvas, game_object: &GameObject) {}
}
<commit_msg>Update example project to use new audio.<commit_after>use nitro::App;
use nitro::Canvas;
use nitro::component::Component;
use nitro::component::Message;
use nitro::GameObject;
use axes::AxisId;
use actions::ActionId;

pub struct Spinny {}

impl Component for Spinny {
    fn receive_message(&mut self, app: &mut App, game_object: &mut GameObject, message: &Message) {
        match *message {
            Message::Start { .. } => {
                app.audio.play_sound("example.ogg", 1.0).expect("Sound failed to play.");
            }

            Message::Update { delta_time } => {
                if let Some(horizontal) = app.input.get_axis_value(AxisId::Horizontal as i32) {
                    *game_object.transform.mut_position() += 100.0 * delta_time * horizontal *
                                                             game_object.transform.right();
                }
                if let Some(vertical) = app.input.get_axis_value(AxisId::Vertical as i32) {
                    *game_object.transform.mut_position() += 100.0 * delta_time * vertical *
                                                             game_object.transform.forward();
                }
                if let Some(rotation) = app.input.get_axis_value(AxisId::Rotation as i32) {
                    *game_object.transform.mut_rotation() += 1.0 * delta_time * rotation;
                }
                if let Some(true) = app.input.action_released(ActionId::Blink as i32) {
                    *game_object.transform.mut_x() += 50.0;
                }
            }
            _ => {}
        }
    }
    fn render_gui(&self, canvas: &mut Canvas, game_object: &GameObject) {}
}
<|endoftext|>


<commit_before>use bollard::service::{HostConfig, PortBinding};
use bollard::{
    container::{Config, CreateContainerOptions, ListContainersOptions, StartContainerOptions},
    errors::Error as BollardError,
    image::CreateImageOptions,
    Docker,
};
use elasticsearch::{
    http::transport::{
        BuildError as TransportBuilderError, SingleNodeConnectionPool, TransportBuilder,
    },
    indices::{IndicesDeleteAliasParts, IndicesDeleteIndexTemplateParts, IndicesDeleteParts},
    Elasticsearch, Error as ElasticsearchError,
};
use futures::stream::TryStreamExt;
use lazy_static::lazy_static;
use snafu::{ResultExt, Snafu};
use std::collections::HashMap;
use std::sync::{Arc, Mutex, MutexGuard};
use tokio::time::{sleep, Duration};
use url::Url;

use crate::adapters::secondary::elasticsearch::remote::{self, Error as ElasticsearchRemoteError};
use crate::domain::ports::secondary::remote::{Error as RemoteError, Remote};

lazy_static! {
    pub static ref AVAILABLE: Arc<Mutex<()>> = Arc::new(Mutex::new(()));
}

// This function takes the mutex related to the availability of the elasticsearch docker container,
// and then creates or reset the container depending on its availability.
// Finally, it tests if elasticsearch is available, before returning
// the mutex guard.
// TODO Document the usage of the mutexguard, how you should avoid running asserts
// while holding the mutex.
pub async fn initialize() -> Result<MutexGuard<'static, ()>, Error> {
    let guard = AVAILABLE.lock().unwrap();
    let mut docker = DockerWrapper::new();
    let is_available = docker.is_container_available().await?;
    if !is_available {
        docker.create_container().await?;
    } else {
        docker.cleanup().await?;
    }
    let is_available = docker.is_container_available().await?;
    if !is_available {
        return Err(Error::Misc {
            msg: format!("Cannot get docker {} available", docker.docker_image),
        });
    }
    let pool = remote::connection_test_pool()
        .await
        .context(ElasticsearchPoolCreation)?;
    let _client = pool.conn().await.context(ElasticsearchConnection)?;

    Ok(guard)
}

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("Connection to docker socket: {}", source))]
    DockerConnection { source: BollardError },

    #[snafu(display("Creation of elasticsearch pool: {}", source))]
    ElasticsearchPoolCreation { source: ElasticsearchRemoteError },

    #[snafu(display("Connection to elasticsearch: {}", source))]
    ElasticsearchConnection { source: RemoteError },

    #[snafu(display("docker version: {}", source))]
    Version { source: BollardError },

    #[snafu(display("url parsing error: {}", source))]
    UrlParse { source: url::ParseError },

    #[snafu(display("elasticsearch transport error: {}", source))]
    ElasticsearchTransport { source: TransportBuilderError },

    #[snafu(display("elasticsearch client error: {}", source))]
    ElasticsearchClient { source: ElasticsearchError },

    #[snafu(display("docker error: {}", source))]
    DockerEngine { source: BollardError },

    #[snafu(display("error: {}", msg))]
    Misc { msg: String },
}

pub struct DockerWrapper {
    ports: Vec<(u32, u32)>, // list of ports to publish (host port, container port)
    docker_image: String,
    container_name: String, // ip: String,
}

// FIXME: Here we hardcode elasticsearch ports. These should be had from the ELASTICSEARCH_TEST_URL
impl Default for DockerWrapper {
    fn default() -> Self {
        DockerWrapper {
            ports: vec![(9201, 9200), (9301, 9300)],
            docker_image: String::from("docker.elastic.co/elasticsearch/elasticsearch:7.13.0"),
            container_name: String::from("mimir-test-elasticsearch"),
        }
    }
}

impl DockerWrapper {
    pub fn new() -> DockerWrapper {
        DockerWrapper::default()
    }

    // Returns true if the container self.container_name is running
    // TODO Probably should run a check on Elasticsearch status
    pub async fn is_container_available(&mut self) -> Result<bool, Error> {
        let docker = Docker::connect_with_unix(
            "unix:///var/run/docker.sock",
            120,
            &bollard::ClientVersion {
                major_version: 1,
                minor_version: 24,
            },
        )
        .context(DockerConnection)?;

        let docker = &docker.negotiate_version().await.context(Version)?;

        docker.version().await.context(Version)?;

        let mut filters = HashMap::new();
        filters.insert("name", vec![self.container_name.as_str()]);

        let options = Some(ListContainersOptions {
            all: false, // only running containers
            filters,
            ..Default::default()
        });

        let containers = docker
            .list_containers(options)
            .await
            .context(DockerEngine)?;

        Ok(!containers.is_empty())
    }

    // If the container is already created, then start it.
    // If it is not created, then create it and start it.
    pub async fn create_container(&mut self) -> Result<(), Error> {
        let docker = Docker::connect_with_unix(
            "unix:///var/run/docker.sock",
            120,
            &bollard::ClientVersion {
                major_version: 1,
                minor_version: 24,
            },
        )
        .context(DockerConnection)?;

        let docker = docker.negotiate_version().await.context(Version)?;

        let _ = docker.version().await.context(Version);

        let mut filters = HashMap::new();
        filters.insert("name", vec![self.container_name.as_str()]);

        let options = Some(ListContainersOptions {
            all: true, // only running containers
            filters,
            ..Default::default()
        });

        let containers = docker
            .list_containers(options)
            .await
            .context(DockerEngine)?;

        if containers.is_empty() {
            let options = CreateContainerOptions {
                name: &self.container_name,
            };

            let mut port_bindings = HashMap::new();
            for (host_port, container_port) in self.ports.iter() {
                port_bindings.insert(
                    format!("{}/tcp", &container_port),
                    Some(vec![PortBinding {
                        host_ip: Some(String::from("0.0.0.0")),
                        host_port: Some(host_port.to_string()),
                    }]),
                );
            }

            let host_config = HostConfig {
                port_bindings: Some(port_bindings),
                ..Default::default()
            };

            let mut exposed_ports = HashMap::new();
            self.ports.iter().for_each(|(_, container)| {
                let v: HashMap<(), ()> = HashMap::new();
                exposed_ports.insert(format!("{}/tcp", container), v);
            });

            let env_vars = vec![String::from("discovery.type=single-node")];

            let config = Config {
                image: Some(self.docker_image.clone()),
                exposed_ports: Some(exposed_ports),
                host_config: Some(host_config),
                env: Some(env_vars),
                ..Default::default()
            };

            docker
                .create_image(
                    Some(CreateImageOptions {
                        from_image: self.docker_image.clone(),
                        ..Default::default()
                    }),
                    None,
                    None,
                )
                .try_collect::<Vec<_>>()
                .await
                .context(DockerEngine)?;

            let _ = docker
                .create_container(Some(options), config)
                .await
                .context(DockerEngine)?;

            sleep(Duration::from_secs(5)).await;
        }
        let _ = docker
            .start_container(&self.container_name, None::<StartContainerOptions<String>>)
            .await
            .context(DockerEngine)?;

        sleep(Duration::from_secs(15)).await;

        Ok(())
    }

    async fn cleanup(&mut self) -> Result<(), Error> {
        let pool = remote::connection_test_pool()
            .await
            .context(ElasticsearchPoolCreation)?;
        let client = pool.conn().await.context(ElasticsearchConnection)?;

        let _ = client
            .0
            .indices()
            .delete(IndicesDeleteParts::Index(&["*"]))
            .send()
            .await
            .context(ElasticsearchClient)?;

        let _ = client
            .0
            .indices()
            .delete_alias(IndicesDeleteAliasParts::IndexName(&["*"], &["*"]))
            .send()
            .await
            .context(ElasticsearchClient)?;

        let _ = client
            .0
            .indices()
            .delete_index_template(IndicesDeleteIndexTemplateParts::Name("*"))
            .send()
            .await
            .context(ElasticsearchClient)?;

        println!("done with cleanup");
        sleep(Duration::from_secs(1)).await;
        Ok(())
    }

    async fn _drop(&mut self) {
        if std::env::var("DONT_KILL_THE_WHALE") == Ok("1".to_string()) {
            println!(
                "the docker won't be stoped at the end, you can debug it.
                Note: ES has been mapped to the port 9242 in you localhost
                manually stop and rm the container mimirsbrunn_tests after debug"
            );
            return;
        }
        let docker = Docker::connect_with_unix(
            "unix:///var/run/docker.sock",
            120,
            &bollard::ClientVersion {
                major_version: 1,
                minor_version: 24,
            },
        )
        .expect("docker connection");

        let options = Some(bollard::container::StopContainerOptions { t: 0 });
        docker
            .stop_container(&self.container_name, options)
            .await
            .expect("stop container");

        let options = Some(bollard::container::RemoveContainerOptions {
            force: true,
            ..Default::default()
        });

        let _res = docker
            .remove_container(&self.container_name, options)
            .await
            .expect("remove container");
    }
}
<commit_msg>Cleanup tests<commit_after>use bollard::service::{HostConfig, PortBinding};
use bollard::{
    container::{Config, CreateContainerOptions, ListContainersOptions, StartContainerOptions},
    errors::Error as BollardError,
    image::CreateImageOptions,
    Docker,
};
use elasticsearch::{
    http::transport::BuildError as TransportBuilderError,
    indices::{IndicesDeleteAliasParts, IndicesDeleteIndexTemplateParts, IndicesDeleteParts},
    Error as ElasticsearchError,
};
use futures::stream::TryStreamExt;
use lazy_static::lazy_static;
use snafu::{ResultExt, Snafu};
use std::collections::HashMap;
use std::sync::{Arc, Mutex, MutexGuard};
use tokio::time::{sleep, Duration};

use crate::adapters::secondary::elasticsearch::remote::{self, Error as ElasticsearchRemoteError};
use crate::domain::ports::secondary::remote::{Error as RemoteError, Remote};

lazy_static! {
    pub static ref AVAILABLE: Arc<Mutex<()>> = Arc::new(Mutex::new(()));
}

// This function takes the mutex related to the availability of the elasticsearch docker container,
// and then creates or reset the container depending on its availability.
// Finally, it tests if elasticsearch is available, before returning
// the mutex guard.
// TODO Document the usage of the mutexguard, how you should avoid running asserts
// while holding the mutex.
pub async fn initialize() -> Result<MutexGuard<'static, ()>, Error> {
    let guard = AVAILABLE.lock().unwrap();
    let mut docker = DockerWrapper::new();
    let is_available = docker.is_container_available().await?;
    if !is_available {
        docker.create_container().await?;
    } else {
        docker.cleanup().await?;
    }
    let is_available = docker.is_container_available().await?;
    if !is_available {
        return Err(Error::Misc {
            msg: format!("Cannot get docker {} available", docker.docker_image),
        });
    }
    let pool = remote::connection_test_pool()
        .await
        .context(ElasticsearchPoolCreation)?;
    let _client = pool.conn().await.context(ElasticsearchConnection)?;

    Ok(guard)
}

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("Connection to docker socket: {}", source))]
    DockerConnection { source: BollardError },

    #[snafu(display("Creation of elasticsearch pool: {}", source))]
    ElasticsearchPoolCreation { source: ElasticsearchRemoteError },

    #[snafu(display("Connection to elasticsearch: {}", source))]
    ElasticsearchConnection { source: RemoteError },

    #[snafu(display("docker version: {}", source))]
    Version { source: BollardError },

    #[snafu(display("url parsing error: {}", source))]
    UrlParse { source: url::ParseError },

    #[snafu(display("elasticsearch transport error: {}", source))]
    ElasticsearchTransport { source: TransportBuilderError },

    #[snafu(display("elasticsearch client error: {}", source))]
    ElasticsearchClient { source: ElasticsearchError },

    #[snafu(display("docker error: {}", source))]
    DockerEngine { source: BollardError },

    #[snafu(display("error: {}", msg))]
    Misc { msg: String },
}

pub struct DockerWrapper {
    ports: Vec<(u32, u32)>, // list of ports to publish (host port, container port)
    docker_image: String,
    container_name: String, // ip: String,
}

// FIXME: Here we hardcode elasticsearch ports. These should be had from the ELASTICSEARCH_TEST_URL
impl Default for DockerWrapper {
    fn default() -> Self {
        DockerWrapper {
            ports: vec![(9201, 9200), (9301, 9300)],
            docker_image: String::from("docker.elastic.co/elasticsearch/elasticsearch:7.13.0"),
            container_name: String::from("mimir-test-elasticsearch"),
        }
    }
}

impl DockerWrapper {
    pub fn new() -> DockerWrapper {
        DockerWrapper::default()
    }

    // Returns true if the container self.container_name is running
    // TODO Probably should run a check on Elasticsearch status
    pub async fn is_container_available(&mut self) -> Result<bool, Error> {
        let docker = Docker::connect_with_unix(
            "unix:///var/run/docker.sock",
            120,
            &bollard::ClientVersion {
                major_version: 1,
                minor_version: 24,
            },
        )
        .context(DockerConnection)?;

        let docker = &docker.negotiate_version().await.context(Version)?;

        docker.version().await.context(Version)?;

        let mut filters = HashMap::new();
        filters.insert("name", vec![self.container_name.as_str()]);

        let options = Some(ListContainersOptions {
            all: false, // only running containers
            filters,
            ..Default::default()
        });

        let containers = docker
            .list_containers(options)
            .await
            .context(DockerEngine)?;

        Ok(!containers.is_empty())
    }

    // If the container is already created, then start it.
    // If it is not created, then create it and start it.
    pub async fn create_container(&mut self) -> Result<(), Error> {
        let docker = Docker::connect_with_unix(
            "unix:///var/run/docker.sock",
            120,
            &bollard::ClientVersion {
                major_version: 1,
                minor_version: 24,
            },
        )
        .context(DockerConnection)?;

        let docker = docker.negotiate_version().await.context(Version)?;

        let _ = docker.version().await.context(Version);

        let mut filters = HashMap::new();
        filters.insert("name", vec![self.container_name.as_str()]);

        let options = Some(ListContainersOptions {
            all: true, // only running containers
            filters,
            ..Default::default()
        });

        let containers = docker
            .list_containers(options)
            .await
            .context(DockerEngine)?;

        if containers.is_empty() {
            let options = CreateContainerOptions {
                name: &self.container_name,
            };

            let mut port_bindings = HashMap::new();
            for (host_port, container_port) in self.ports.iter() {
                port_bindings.insert(
                    format!("{}/tcp", &container_port),
                    Some(vec![PortBinding {
                        host_ip: Some(String::from("0.0.0.0")),
                        host_port: Some(host_port.to_string()),
                    }]),
                );
            }

            let host_config = HostConfig {
                port_bindings: Some(port_bindings),
                ..Default::default()
            };

            let mut exposed_ports = HashMap::new();
            self.ports.iter().for_each(|(_, container)| {
                let v: HashMap<(), ()> = HashMap::new();
                exposed_ports.insert(format!("{}/tcp", container), v);
            });

            let env_vars = vec![String::from("discovery.type=single-node")];

            let config = Config {
                image: Some(self.docker_image.clone()),
                exposed_ports: Some(exposed_ports),
                host_config: Some(host_config),
                env: Some(env_vars),
                ..Default::default()
            };

            docker
                .create_image(
                    Some(CreateImageOptions {
                        from_image: self.docker_image.clone(),
                        ..Default::default()
                    }),
                    None,
                    None,
                )
                .try_collect::<Vec<_>>()
                .await
                .context(DockerEngine)?;

            let _ = docker
                .create_container(Some(options), config)
                .await
                .context(DockerEngine)?;

            sleep(Duration::from_secs(5)).await;
        }
        let _ = docker
            .start_container(&self.container_name, None::<StartContainerOptions<String>>)
            .await
            .context(DockerEngine)?;

        sleep(Duration::from_secs(15)).await;

        Ok(())
    }

    async fn cleanup(&mut self) -> Result<(), Error> {
        let pool = remote::connection_test_pool()
            .await
            .context(ElasticsearchPoolCreation)?;
        let client = pool.conn().await.context(ElasticsearchConnection)?;

        let _ = client
            .0
            .indices()
            .delete(IndicesDeleteParts::Index(&["*"]))
            .send()
            .await
            .context(ElasticsearchClient)?;

        let _ = client
            .0
            .indices()
            .delete_alias(IndicesDeleteAliasParts::IndexName(&["*"], &["*"]))
            .send()
            .await
            .context(ElasticsearchClient)?;

        let _ = client
            .0
            .indices()
            .delete_index_template(IndicesDeleteIndexTemplateParts::Name("*"))
            .send()
            .await
            .context(ElasticsearchClient)?;

        println!("done with cleanup");
        sleep(Duration::from_secs(1)).await;
        Ok(())
    }

    async fn _drop(&mut self) {
        if std::env::var("DONT_KILL_THE_WHALE") == Ok("1".to_string()) {
            println!(
                "the docker won't be stoped at the end, you can debug it.
                Note: ES has been mapped to the port 9242 in you localhost
                manually stop and rm the container mimirsbrunn_tests after debug"
            );
            return;
        }
        let docker = Docker::connect_with_unix(
            "unix:///var/run/docker.sock",
            120,
            &bollard::ClientVersion {
                major_version: 1,
                minor_version: 24,
            },
        )
        .expect("docker connection");

        let options = Some(bollard::container::StopContainerOptions { t: 0 });
        docker
            .stop_container(&self.container_name, options)
            .await
            .expect("stop container");

        let options = Some(bollard::container::RemoveContainerOptions {
            force: true,
            ..Default::default()
        });

        let _res = docker
            .remove_container(&self.container_name, options)
            .await
            .expect("remove container");
    }
}
<|endoftext|>


<commit_before>extern crate flac;

fn run_metaflac(fname: &Path) -> String {
    use std::io::Command;

    // Run metaflac on the specified file and print all streaminfo data.
    let mut child = Command::new("metaflac")
                        .arg("--show-min-blocksize")
                        .arg("--show-max-blocksize")
                        .arg("--show-min-framesize")
                        .arg("--show-max-framesize")
                        .arg("--show-sample-rate")
                        .arg("--show-channels")
                        .arg("--show-bps")
                        .arg("--show-total-samples")
                        .arg("--show-md5sum")
                        .arg(fname.as_str().expect("unsupported filename"))
                        .spawn().ok().expect("failed to run metaflac");

    assert!(child.wait().unwrap().success());

    let output = match child.stdout {
        Some(ref mut stdout) => stdout.read_to_string().ok()
                                      .expect("failed to read metaflac stdout"),
        None => panic!("failed to open metaflac stdout")
    };

    output
}

fn print_hex(seq: &[u8]) -> String {
    let vec: Vec<String> = seq.iter().map(|x| format!("{:x}", *x)).collect();
    vec.concat()
}

fn read_streaminfo(fname: &Path) -> String {
    use std::io::fs::File;
    use flac::{read_stream_header, read_metadata_block_header, read_streaminfo_block};

    // Open the file and extract its streaminfo block.
    // TODO: avoid repetition in the tests and library;
    // there might be some kind of metadata block iterator in the future.
    let mut file = File::open(fname).ok().expect("failed to open flac file");
    read_stream_header(&mut file).ok().expect("invalid flac header");
    read_metadata_block_header(&mut file).ok().expect("invalid metadata block header");
    let streaminfo = read_streaminfo_block(&mut file).ok().expect("failed to read streaminfo");

    // Format the streaminfo in the same way that metaflac prints it.
    format!("{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
            streaminfo.min_block_size,
            streaminfo.max_block_size,
            streaminfo.min_frame_size.unwrap_or(0),
            streaminfo.max_frame_size.unwrap_or(0),
            streaminfo.sample_rate,
            streaminfo.n_channels,
            streaminfo.bits_per_sample,
            streaminfo.n_samples.unwrap_or(0),
            print_hex(&streaminfo.md5sum)) // TODO implement LowerHex for &[u8] and submit a PR.
}

fn compare_metaflac(fname: &Path) {
    let metaflac = run_metaflac(fname);
    let streaminfo = read_streaminfo(fname);
    let mut mf_lines = metaflac.lines_any();
    let mut si_lines = streaminfo.lines_any();
    while let (Some(mf), Some(si)) = (mf_lines.next(), si_lines.next()) {
        if mf != si {
            println!("metaflac: {}\nstreaminfo: {}", metaflac, streaminfo);
            panic!("metaflac disagrees on parsed streaminfo (run with --nocapture for details)");
        }
    };
}

#[test]
fn test_foo() {
    compare_metaflac(&Path::new("foo.flac"));
}
<commit_msg>verify with all flac files in the directory<commit_after>extern crate flac;

fn run_metaflac(fname: &Path) -> String {
    use std::io::Command;

    // Run metaflac on the specified file and print all streaminfo data.
    let mut child = Command::new("metaflac")
                        .arg("--show-min-blocksize")
                        .arg("--show-max-blocksize")
                        .arg("--show-min-framesize")
                        .arg("--show-max-framesize")
                        .arg("--show-sample-rate")
                        .arg("--show-channels")
                        .arg("--show-bps")
                        .arg("--show-total-samples")
                        .arg("--show-md5sum")
                        .arg(fname.as_str().expect("unsupported filename"))
                        .spawn().ok().expect("failed to run metaflac");

    assert!(child.wait().unwrap().success());

    let output = match child.stdout {
        Some(ref mut stdout) => stdout.read_to_string().ok()
                                      .expect("failed to read metaflac stdout"),
        None => panic!("failed to open metaflac stdout")
    };

    output
}

fn print_hex(seq: &[u8]) -> String {
    let vec: Vec<String> = seq.iter().map(|x| format!("{:x}", *x)).collect();
    vec.concat()
}

fn read_streaminfo(fname: &Path) -> String {
    use std::io::fs::File;
    use flac::{read_stream_header, read_metadata_block_header, read_streaminfo_block};

    // Open the file and extract its streaminfo block.
    // TODO: avoid repetition in the tests and library;
    // there might be some kind of metadata block iterator in the future.
    let mut file = File::open(fname).ok().expect("failed to open flac file");
    read_stream_header(&mut file).ok().expect("invalid flac header");
    read_metadata_block_header(&mut file).ok().expect("invalid metadata block header");
    let streaminfo = read_streaminfo_block(&mut file).ok().expect("failed to read streaminfo");

    // Format the streaminfo in the same way that metaflac prints it.
    format!("{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
            streaminfo.min_block_size,
            streaminfo.max_block_size,
            streaminfo.min_frame_size.unwrap_or(0),
            streaminfo.max_frame_size.unwrap_or(0),
            streaminfo.sample_rate,
            streaminfo.n_channels,
            streaminfo.bits_per_sample,
            streaminfo.n_samples.unwrap_or(0),
            print_hex(&streaminfo.md5sum)) // TODO implement LowerHex for &[u8] and submit a PR.
}

fn compare_metaflac(fname: &Path) {
    let metaflac = run_metaflac(fname);
    let streaminfo = read_streaminfo(fname);
    let mut mf_lines = metaflac.lines_any();
    let mut si_lines = streaminfo.lines_any();
    while let (Some(mf), Some(si)) = (mf_lines.next(), si_lines.next()) {
        if mf != si {
            println!("metaflac\n--------\n{}", metaflac);
            println!("streaminfo\n----------\n{}", streaminfo);
            panic!("metaflac disagrees on parsed streaminfo");
        }
    };
}

#[test]
fn verify_streaminfo() {
    use std::io::fs::{readdir, PathExtensions};

    // Compare our streaminfo parsing with metaflac on all flac files in the
    // current directory.
    let dir = readdir(&Path::new(".")).ok().expect("failed to enumerate flac files");
    for path in dir.iter() {
        if path.is_file() && path.extension_str() == Some("flac") {
            print!("    comparing {} ...", path.as_str().expect("unsupported filename"));
            compare_metaflac(path);
            println!(" ok");
        }
    }
}
<|endoftext|>


<commit_before>use ladspa::Data;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};

pub const BUFFER_SIZE: usize = 1024;
pub const BYTE_BUFFER_SIZE: usize = BUFFER_SIZE * 4 * 2 + 8 * 2 + 8; // data + data size + timestamp

#[derive(RustcEncodable, RustcDecodable, Clone)]
pub struct Packet {
    ldata: Vec<Data>,
    rdata: Vec<Data>,
    timestamp: u64,
}

impl Packet {
    pub fn parse(bytes: &[u8]) -> Packet {
        decode(bytes).unwrap()
    }

    pub fn new(ldata: &[Data], rdata: &[Data], time: u64) -> Packet {
        assert_eq!(ldata.len(), BUFFER_SIZE);
        assert_eq!(rdata.len(), BUFFER_SIZE);

        let mut packet = Packet {
            ldata: vec![0f32; BUFFER_SIZE],
            rdata: vec![0f32; BUFFER_SIZE],
            timestamp: time,
        };
        (&mut packet.ldata[..]).clone_from_slice(ldata);
        (&mut packet.rdata[..]).clone_from_slice(rdata);

        packet
    }

    pub fn as_bytes(&self) -> Vec<u8> {
        encode(self, SizeLimit::Infinite).unwrap()
    }

    pub fn get_ldata(&self) -> &[Data] {
        &self.ldata[..]
    }

    pub fn get_rdata(&self) -> &[Data] {
        &self.rdata[..]
    }

    pub fn read(&self, time: u64) -> (Data, Data) {
        if !self.active(time) {
            return (0_f32, 0_f32);
        }
        let position = (time - self.timestamp) as usize;
        let ldata = self.ldata[position];
        let rdata = self.rdata[position];
        (ldata, rdata)
    }

    pub fn active(&self, time: u64) -> bool {
        time >= self.timestamp && !self.complete(time)
    }

    pub fn complete(&self, time: u64) -> bool {
        time >= self.timestamp + BUFFER_SIZE as u64
    }
}

#[test]
fn test_packet_serialize() {
    let ldata = vec![1.0; BUFFER_SIZE];
    let rdata = vec![2.0; BUFFER_SIZE];
    let new = Packet::new(&ldata, &rdata, 0);
    assert_eq!(new.get_ldata(), ldata.as_slice());
    assert_eq!(new.get_rdata(), rdata.as_slice());
    let parsed = Packet::parse(&new.as_bytes()[..]);
    assert_eq!(parsed.get_ldata(), ldata.as_slice());
    assert_eq!(parsed.get_rdata(), rdata.as_slice());
    assert_eq!(&new.as_bytes()[..], &parsed.as_bytes()[..]);
    println!("{}", new.as_bytes().len());
}

#[test]
#[should_panic]
fn test_packet_wrong_size() {
    let ldata = vec![1.0; 5];
    let rdata = vec![2.0; 6];
    Packet::new(&ldata, &rdata, 0);
}

#[test]
fn test_packet_read() {
    let ldata = vec![1.0; BUFFER_SIZE];
    let rdata = vec![2.0; BUFFER_SIZE];
    let packet = Packet::new(&ldata, &rdata, 100);
    assert_eq!((0.0, 0.0), packet.read(0));
    assert_eq!((0.0, 0.0), packet.read(99));
    assert_eq!((1.0, 2.0), packet.read(100));
    assert_eq!((1.0, 2.0), packet.read(100 + BUFFER_SIZE as u64 - 1));
    assert_eq!((0.0, 0.0), packet.read(100 + BUFFER_SIZE as u64));
}

#[test]
fn test_packet_active_complete() {
    let ldata = vec![1.0; BUFFER_SIZE];
    let rdata = vec![2.0; BUFFER_SIZE];
    let packet = Packet::new(&ldata, &rdata, 100);
    assert!(!packet.active(0));
    assert!(!packet.complete(0));
    assert!(!packet.active(99));
    assert!(!packet.complete(99));
    assert!(packet.active(100));
    assert!(!packet.complete(100));
    assert!(packet.active(100 + BUFFER_SIZE as u64 - 1));
    assert!(!packet.complete(100 + BUFFER_SIZE as u64 - 1));
    assert!(!packet.active(100 + BUFFER_SIZE as u64));
    assert!(packet.complete(100 + BUFFER_SIZE as u64));
}
<commit_msg>more asserts and a getter<commit_after>use ladspa::Data;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};

pub const BUFFER_SIZE: usize = 1024;
pub const BYTE_BUFFER_SIZE: usize = BUFFER_SIZE * 4 * 2 + 8 * 2 + 8; // data + data size + timestamp

#[derive(RustcEncodable, RustcDecodable, Clone)]
pub struct Packet {
    ldata: Vec<Data>,
    rdata: Vec<Data>,
    timestamp: u64,
}

impl Packet {
    pub fn parse(bytes: &[u8]) -> Packet {
        decode(bytes).unwrap()
    }

    pub fn new(ldata: &[Data], rdata: &[Data], time: u64) -> Packet {
        assert_eq!(ldata.len(), BUFFER_SIZE);
        assert_eq!(rdata.len(), BUFFER_SIZE);

        let mut packet = Packet {
            ldata: vec![0f32; BUFFER_SIZE],
            rdata: vec![0f32; BUFFER_SIZE],
            timestamp: time,
        };
        (&mut packet.ldata[..]).clone_from_slice(ldata);
        (&mut packet.rdata[..]).clone_from_slice(rdata);

        packet
    }

    pub fn as_bytes(&self) -> Vec<u8> {
        let bytes = encode(self, SizeLimit::Infinite).unwrap();
        assert_eq!(bytes.len(), BYTE_BUFFER_SIZE);
        bytes
    }

    pub fn get_ldata(&self) -> &[Data] {
        &self.ldata[..]
    }

    pub fn get_rdata(&self) -> &[Data] {
        &self.rdata[..]
    }

    pub fn read(&self, time: u64) -> (Data, Data) {
        if !self.active(time) {
            return (0_f32, 0_f32);
        }
        let position = (time - self.timestamp) as usize;
        let ldata = self.ldata[position];
        let rdata = self.rdata[position];
        (ldata, rdata)
    }

    pub fn active(&self, time: u64) -> bool {
        time >= self.timestamp && !self.complete(time)
    }

    pub fn complete(&self, time: u64) -> bool {
        time >= self.timestamp + BUFFER_SIZE as u64
    }

    pub fn get_timestamp(&self) -> u64 {
        self.timestamp
    }
}

#[test]
fn test_packet_serialize() {
    let ldata = vec![1.0; BUFFER_SIZE];
    let rdata = vec![2.0; BUFFER_SIZE];
    let new = Packet::new(&ldata, &rdata, 0);
    assert_eq!(new.get_ldata(), ldata.as_slice());
    assert_eq!(new.get_rdata(), rdata.as_slice());
    let parsed = Packet::parse(&new.as_bytes()[..]);
    assert_eq!(parsed.get_ldata(), ldata.as_slice());
    assert_eq!(parsed.get_rdata(), rdata.as_slice());
    assert_eq!(&new.as_bytes()[..], &parsed.as_bytes()[..]);
    println!("{}", new.as_bytes().len());
}

#[test]
#[should_panic]
fn test_packet_wrong_size() {
    let ldata = vec![1.0; 5];
    let rdata = vec![2.0; 6];
    Packet::new(&ldata, &rdata, 0);
}

#[test]
fn test_packet_read() {
    let ldata = vec![1.0; BUFFER_SIZE];
    let rdata = vec![2.0; BUFFER_SIZE];
    let packet = Packet::new(&ldata, &rdata, 100);
    assert_eq!((0.0, 0.0), packet.read(0));
    assert_eq!((0.0, 0.0), packet.read(99));
    assert_eq!((1.0, 2.0), packet.read(100));
    assert_eq!((1.0, 2.0), packet.read(100 + BUFFER_SIZE as u64 - 1));
    assert_eq!((0.0, 0.0), packet.read(100 + BUFFER_SIZE as u64));
}

#[test]
fn test_packet_active_complete() {
    let ldata = vec![1.0; BUFFER_SIZE];
    let rdata = vec![2.0; BUFFER_SIZE];
    let packet = Packet::new(&ldata, &rdata, 100);
    assert!(!packet.active(0));
    assert!(!packet.complete(0));
    assert!(!packet.active(99));
    assert!(!packet.complete(99));
    assert!(packet.active(100));
    assert!(!packet.complete(100));
    assert!(packet.active(100 + BUFFER_SIZE as u64 - 1));
    assert!(!packet.complete(100 + BUFFER_SIZE as u64 - 1));
    assert!(!packet.active(100 + BUFFER_SIZE as u64));
    assert!(packet.complete(100 + BUFFER_SIZE as u64));
}
<|endoftext|>