<commit_before>use std::cmp::Ordering;
use std::{mem};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

#[derive(Debug, Clone)]
struct Node {
    weight: usize,
    leaf_counts: Vec<usize>,
}

impl Node {
    fn new(weight: usize, initial_count: usize, capacity: usize) -> Node {
        let mut n = Node {
            weight: weight,
            leaf_counts: Vec::with_capacity(capacity),
        };
        n.leaf_counts.push(initial_count);
        n
    }
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    index: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List {
    lookahead1: Node,
    lookahead2: Node,
    next_leaf_index: usize,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], maxbits: i32) -> Vec<u32> {
    let num_freqs = frequencies.len();

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, index: i })
        .collect();

    // Short circuit some special cases
    if leaves.is_empty() {
        // There are no non-zero frequencies.
        return vec![0; num_freqs];
    }
    if leaves.len() == 1 {
        let mut result = vec![0; num_freqs];
        result[leaves[0].index] = 1;
        return result;
    }
    if leaves.len() == 2 {
        let mut result = vec![0; num_freqs];
        result[leaves[0].index] = 1;
        result[leaves[1].index] = 1;
        return result;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_num_leaves = 2 * leaves.len() - 2;
    let mut lists = vec![
        List {
            lookahead1: Node::new(leaves[0].weight, 1, max_num_leaves),
            lookahead2: Node::new(leaves[1].weight, 2, max_num_leaves),
            next_leaf_index: 2,
        };
        maxbits as usize
    ];

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = max_num_leaves - 2;
    for _ in 0..num_boundary_pm_runs {
        boundary_pm_toplevel(&mut lists[..], &leaves);
    }

    let n = num_freqs;
    let mut result = vec![0; n];

    let mut a = lists.pop().unwrap().lookahead2.leaf_counts.into_iter().rev().peekable();

    let mut bitlength_value = 1;
    while let Some(leaf_count) = a.next() {
        let next_count = *a.peek().unwrap_or(&0);
        for leaf in &leaves[next_count..leaf_count] {
            result[leaf.index] = bitlength_value;
        }
        bitlength_value += 1;
    }

    result
}

fn lowest_list(lists: &mut [List], leaves: &[Leaf]) {
    // We're in the lowest list, just add another leaf to the lookaheads
    // There will always be more leaves to be added on level 0 so this is safe.
    let mut current_list = &mut lists[0];
    let next_leaf = &leaves[current_list.next_leaf_index];
    current_list.lookahead2.weight = next_leaf.weight;

    current_list.lookahead2.leaf_counts[0] = current_list.lookahead1.leaf_counts.last().unwrap() + 1;
    current_list.next_leaf_index += 1;
}

fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let mut current_list = &mut lists[current_list_index];

    // The next leaf goes next; counting itself makes the leaf_count increase by one.
    current_list.lookahead2.weight = leaves[current_list.next_leaf_index].weight;
    current_list.lookahead2.leaf_counts.clear();
    current_list.lookahead2.leaf_counts.extend_from_slice(&current_list.lookahead1.leaf_counts);
    let last_index = current_list.lookahead2.leaf_counts.len() - 1;
    current_list.lookahead2.leaf_counts[last_index] += 1;
    current_list.next_leaf_index += 1;
}

fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    {
        let (head, tail) = lists.split_at_mut(current_list_index);
        let prev_list = head.last_mut().unwrap();
        let current_list = tail.first_mut().unwrap();

        let previous_list_leaf_counts = &prev_list.lookahead2.leaf_counts;

        // Make a tree from the lookaheads from the previous list; that goes next.
        // This is not a leaf node, so the leaf count stays the same.
        current_list.lookahead2.weight = weight_sum;
        current_list.lookahead2.leaf_counts.clear();

        current_list.lookahead2.leaf_counts.extend_from_slice(previous_list_leaf_counts);
        current_list.lookahead2.leaf_counts.push(*current_list.lookahead1.leaf_counts.last().unwrap());
    }

    // The previous list needs two new lookahead nodes.
    boundary_pm(lists, leaves, current_list_index - 1);
    boundary_pm(lists, leaves, current_list_index - 1);
}

fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
    let last_index = lists.len() - 1;
    boundary_pm(lists, leaves, last_index);
}

fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let next_leaf_index = lists[current_list_index].next_leaf_index;

    if current_list_index == 0 && next_leaf_index == leaves.len() {
        // We've added all the leaves to the lowest list, so we're done here
        return;
    }

    mem::swap(&mut lists[current_list_index].lookahead1, &mut lists[current_list_index].lookahead2);

    if current_list_index == 0 {
        lowest_list(lists, leaves);
    } else {
        // We're at a list other than the lowest list.
        let weight_sum = {
            let previous_list = &lists[current_list_index - 1];
            previous_list.lookahead1.weight + previous_list.lookahead2.weight
        };

        if next_leaf_index < leaves.len() && weight_sum > leaves[next_leaf_index].weight {
            next_leaf(lists, leaves, current_list_index);
        } else {
            next_tree(weight_sum, lists, leaves, current_list_index);
        }
    }
}

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn maxbits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn maxbits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<commit_msg>Remove some duplication<commit_after>use std::cmp::Ordering;
use std::{mem};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

#[derive(Debug, Clone)]
struct Node {
    weight: usize,
    leaf_counts: Vec<usize>,
}

impl Node {
    fn new(weight: usize, initial_count: usize, capacity: usize) -> Node {
        let mut n = Node {
            weight: weight,
            leaf_counts: Vec::with_capacity(capacity),
        };
        n.leaf_counts.push(initial_count);
        n
    }
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    index: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List {
    lookahead1: Node,
    lookahead2: Node,
    next_leaf_index: usize,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], maxbits: i32) -> Vec<u32> {
    let num_freqs = frequencies.len();
    let mut result = vec![0; num_freqs];

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, index: i })
        .collect();

    // Short circuit some special cases
    if leaves.is_empty() {
        // There are no non-zero frequencies.
        return result;
    }
    if leaves.len() == 1 {
        result[leaves[0].index] = 1;
        return result;
    }
    if leaves.len() == 2 {
        result[leaves[0].index] = 1;
        result[leaves[1].index] = 1;
        return result;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_num_leaves = 2 * leaves.len() - 2;
    let mut lists = vec![
        List {
            lookahead1: Node::new(leaves[0].weight, 1, max_num_leaves),
            lookahead2: Node::new(leaves[1].weight, 2, max_num_leaves),
            next_leaf_index: 2,
        };
        maxbits as usize
    ];

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = max_num_leaves - 2;
    for _ in 0..num_boundary_pm_runs {
        boundary_pm_toplevel(&mut lists[..], &leaves);
    }

    let mut a = lists.pop().unwrap().lookahead2.leaf_counts.into_iter().rev().peekable();

    let mut bitlength_value = 1;
    while let Some(leaf_count) = a.next() {
        let next_count = *a.peek().unwrap_or(&0);
        for leaf in &leaves[next_count..leaf_count] {
            result[leaf.index] = bitlength_value;
        }
        bitlength_value += 1;
    }

    result
}

fn lowest_list(lists: &mut [List], leaves: &[Leaf]) {
    // We're in the lowest list, just add another leaf to the lookaheads
    // There will always be more leaves to be added on level 0 so this is safe.
    let mut current_list = &mut lists[0];
    let next_leaf = &leaves[current_list.next_leaf_index];
    current_list.lookahead2.weight = next_leaf.weight;

    current_list.lookahead2.leaf_counts[0] = current_list.lookahead1.leaf_counts.last().unwrap() + 1;
    current_list.next_leaf_index += 1;
}

fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let mut current_list = &mut lists[current_list_index];

    // The next leaf goes next; counting itself makes the leaf_count increase by one.
    current_list.lookahead2.weight = leaves[current_list.next_leaf_index].weight;
    current_list.lookahead2.leaf_counts.clear();
    current_list.lookahead2.leaf_counts.extend_from_slice(&current_list.lookahead1.leaf_counts);
    let last_index = current_list.lookahead2.leaf_counts.len() - 1;
    current_list.lookahead2.leaf_counts[last_index] += 1;
    current_list.next_leaf_index += 1;
}

fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    {
        let (head, tail) = lists.split_at_mut(current_list_index);
        let prev_list = head.last_mut().unwrap();
        let current_list = tail.first_mut().unwrap();

        let previous_list_leaf_counts = &prev_list.lookahead2.leaf_counts;

        // Make a tree from the lookaheads from the previous list; that goes next.
        // This is not a leaf node, so the leaf count stays the same.
        current_list.lookahead2.weight = weight_sum;
        current_list.lookahead2.leaf_counts.clear();

        current_list.lookahead2.leaf_counts.extend_from_slice(previous_list_leaf_counts);
        current_list.lookahead2.leaf_counts.push(*current_list.lookahead1.leaf_counts.last().unwrap());
    }

    // The previous list needs two new lookahead nodes.
    boundary_pm(lists, leaves, current_list_index - 1);
    boundary_pm(lists, leaves, current_list_index - 1);
}

fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
    let last_index = lists.len() - 1;
    boundary_pm(lists, leaves, last_index);
}

fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let next_leaf_index = lists[current_list_index].next_leaf_index;

    if current_list_index == 0 && next_leaf_index == leaves.len() {
        // We've added all the leaves to the lowest list, so we're done here
        return;
    }

    mem::swap(&mut lists[current_list_index].lookahead1, &mut lists[current_list_index].lookahead2);

    if current_list_index == 0 {
        lowest_list(lists, leaves);
    } else {
        // We're at a list other than the lowest list.
        let weight_sum = {
            let previous_list = &lists[current_list_index - 1];
            previous_list.lookahead1.weight + previous_list.lookahead2.weight
        };

        if next_leaf_index < leaves.len() && weight_sum > leaves[next_leaf_index].weight {
            next_leaf(lists, leaves, current_list_index);
        } else {
            next_tree(weight_sum, lists, leaves, current_list_index);
        }
    }
}

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn maxbits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn maxbits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::{mem};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

#[derive(Debug, Clone)]
struct Node {
    weight: usize,
    leaf_counts: Vec<usize>,
}

impl Node {
    fn new(weight: usize, initial_count: usize, capacity: usize) -> Node {
        let mut n = Node {
            weight: weight,
            leaf_counts: Vec::with_capacity(capacity),
        };
        n.leaf_counts.push(initial_count);
        n
    }
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    count: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List {
    lookahead1: Node,
    lookahead2: Node,
    next_leaf_index: usize,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], max_bits: usize) -> Vec<u32> {
    let num_freqs = frequencies.len();
    let mut bit_lengths = vec![0; num_freqs];

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, count: i })
        .collect();

    let num_symbols = leaves.len();

    // Short circuit some special cases

    // TODO:
    // if ((1 << maxbits) < numsymbols) {
    //   free(leaves);
    //   return 1;  /* Error, too few maxbits to represent symbols. */
    // }

    if num_symbols == 0 {
        // There are no non-zero frequencies.
        return bit_lengths;
    }
    if num_symbols == 1 {
        bit_lengths[leaves[0].count] = 1;
        return bit_lengths;
    }
    if num_symbols == 2 {
        bit_lengths[leaves[0].count] = 1;
        bit_lengths[leaves[1].count] = 1;
        return bit_lengths;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_num_leaves = 2 * num_symbols - 2;
    let mut lists = vec![
        List {
            lookahead1: Node::new(leaves[0].weight, 1, max_num_leaves),
            lookahead2: Node::new(leaves[1].weight, 2, max_num_leaves),
            next_leaf_index: 2,
        };
        max_bits
    ];

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = max_num_leaves - 2;
    for _ in 0..num_boundary_pm_runs {
        boundary_pm_toplevel(&mut lists[..], &leaves);
    }

    let mut a = lists.pop().unwrap().lookahead2.leaf_counts.into_iter().rev().peekable();

    let mut bitlength_value = 1;
    while let Some(leaf_count) = a.next() {
        let next_count = *a.peek().unwrap_or(&0);
        for leaf in &leaves[next_count..leaf_count] {
            bit_lengths[leaf.count] = bitlength_value;
        }
        bitlength_value += 1;
    }

    bit_lengths
}

fn lowest_list(lists: &mut [List], leaves: &[Leaf]) {
    // We're in the lowest list, just add another leaf to the lookaheads
    // There will always be more leaves to be added on level 0 so this is safe.
    let mut current_list = &mut lists[0];
    let next_leaf = &leaves[current_list.next_leaf_index];
    current_list.lookahead2.weight = next_leaf.weight;

    current_list.lookahead2.leaf_counts[0] = current_list.lookahead1.leaf_counts.last().unwrap() + 1;
    current_list.next_leaf_index += 1;
}

fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let mut current_list = &mut lists[current_list_index];

    // The next leaf goes next; counting itself makes the leaf_count increase by one.
    current_list.lookahead2.weight = leaves[current_list.next_leaf_index].weight;
    current_list.lookahead2.leaf_counts.clear();
    current_list.lookahead2.leaf_counts.extend_from_slice(&current_list.lookahead1.leaf_counts);
    let last_index = current_list.lookahead2.leaf_counts.len() - 1;
    current_list.lookahead2.leaf_counts[last_index] += 1;
    current_list.next_leaf_index += 1;
}

fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    {
        let (head, tail) = lists.split_at_mut(current_list_index);
        let prev_list = head.last_mut().unwrap();
        let current_list = tail.first_mut().unwrap();

        let previous_list_leaf_counts = &prev_list.lookahead2.leaf_counts;

        // Make a tree from the lookaheads from the previous list; that goes next.
        // This is not a leaf node, so the leaf count stays the same.
        current_list.lookahead2.weight = weight_sum;
        current_list.lookahead2.leaf_counts.clear();

        current_list.lookahead2.leaf_counts.extend_from_slice(previous_list_leaf_counts);
        current_list.lookahead2.leaf_counts.push(*current_list.lookahead1.leaf_counts.last().unwrap());
    }

    // The previous list needs two new lookahead nodes.
    boundary_pm(lists, leaves, current_list_index - 1);
    boundary_pm(lists, leaves, current_list_index - 1);
}

fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
    let last_index = lists.len() - 1;
    boundary_pm(lists, leaves, last_index);
}

fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let next_leaf_index = lists[current_list_index].next_leaf_index;
    let num_symbols = leaves.len();

    if current_list_index == 0 && next_leaf_index == num_symbols {
        // We've added all the leaves to the lowest list, so we're done here
        return;
    }

    mem::swap(&mut lists[current_list_index].lookahead1, &mut lists[current_list_index].lookahead2);

    if current_list_index == 0 {
        lowest_list(lists, leaves);
    } else {
        // We're at a list other than the lowest list.
        let weight_sum = {
            let previous_list = &lists[current_list_index - 1];
            previous_list.lookahead1.weight + previous_list.lookahead2.weight
        };

        if next_leaf_index < num_symbols && weight_sum > leaves[next_leaf_index].weight {
            next_leaf(lists, leaves, current_list_index);
        } else {
            next_tree(weight_sum, lists, leaves, current_list_index);
        }
    }
}

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<commit_msg>Add a check limiting max_bits that the C code has<commit_after>use std::cmp::Ordering;
use std::{mem};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

#[derive(Debug, Clone)]
struct Node {
    weight: usize,
    leaf_counts: Vec<usize>,
}

impl Node {
    fn new(weight: usize, initial_count: usize, capacity: usize) -> Node {
        let mut n = Node {
            weight: weight,
            leaf_counts: Vec::with_capacity(capacity),
        };
        n.leaf_counts.push(initial_count);
        n
    }
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    count: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List {
    lookahead1: Node,
    lookahead2: Node,
    next_leaf_index: usize,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], max_bits: usize) -> Vec<u32> {
    let num_freqs = frequencies.len();
    let mut bit_lengths = vec![0; num_freqs];

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, count: i })
        .collect();

    let num_symbols = leaves.len();

    // Short circuit some special cases

    // TODO:
    // if ((1 << maxbits) < numsymbols) {
    //   free(leaves);
    //   return 1;  /* Error, too few maxbits to represent symbols. */
    // }

    if num_symbols == 0 {
        // There are no non-zero frequencies.
        return bit_lengths;
    }
    if num_symbols == 1 {
        bit_lengths[leaves[0].count] = 1;
        return bit_lengths;
    }
    if num_symbols == 2 {
        bit_lengths[leaves[0].count] = 1;
        bit_lengths[leaves[1].count] = 1;
        return bit_lengths;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_bits = if num_symbols - 1 < max_bits {
        num_symbols - 1
    } else {
        max_bits
    };

    let max_num_leaves = 2 * num_symbols - 2;
    let mut lists = vec![
        List {
            lookahead1: Node::new(leaves[0].weight, 1, max_num_leaves),
            lookahead2: Node::new(leaves[1].weight, 2, max_num_leaves),
            next_leaf_index: 2,
        };
        max_bits
    ];

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = max_num_leaves - 2;
    for _ in 0..num_boundary_pm_runs {
        boundary_pm_toplevel(&mut lists[..], &leaves);
    }

    let mut a = lists.pop().unwrap().lookahead2.leaf_counts.into_iter().rev().peekable();

    let mut bitlength_value = 1;
    while let Some(leaf_count) = a.next() {
        let next_count = *a.peek().unwrap_or(&0);
        for leaf in &leaves[next_count..leaf_count] {
            bit_lengths[leaf.count] = bitlength_value;
        }
        bitlength_value += 1;
    }

    bit_lengths
}

fn lowest_list(lists: &mut [List], leaves: &[Leaf]) {
    // We're in the lowest list, just add another leaf to the lookaheads
    // There will always be more leaves to be added on level 0 so this is safe.
    let mut current_list = &mut lists[0];
    let next_leaf = &leaves[current_list.next_leaf_index];
    current_list.lookahead2.weight = next_leaf.weight;

    current_list.lookahead2.leaf_counts[0] = current_list.lookahead1.leaf_counts.last().unwrap() + 1;
    current_list.next_leaf_index += 1;
}

fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let mut current_list = &mut lists[current_list_index];

    // The next leaf goes next; counting itself makes the leaf_count increase by one.
    current_list.lookahead2.weight = leaves[current_list.next_leaf_index].weight;
    current_list.lookahead2.leaf_counts.clear();
    current_list.lookahead2.leaf_counts.extend_from_slice(&current_list.lookahead1.leaf_counts);
    let last_index = current_list.lookahead2.leaf_counts.len() - 1;
    current_list.lookahead2.leaf_counts[last_index] += 1;
    current_list.next_leaf_index += 1;
}

fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    {
        let (head, tail) = lists.split_at_mut(current_list_index);
        let prev_list = head.last_mut().unwrap();
        let current_list = tail.first_mut().unwrap();

        let previous_list_leaf_counts = &prev_list.lookahead2.leaf_counts;

        // Make a tree from the lookaheads from the previous list; that goes next.
        // This is not a leaf node, so the leaf count stays the same.
        current_list.lookahead2.weight = weight_sum;
        current_list.lookahead2.leaf_counts.clear();

        current_list.lookahead2.leaf_counts.extend_from_slice(previous_list_leaf_counts);
        current_list.lookahead2.leaf_counts.push(*current_list.lookahead1.leaf_counts.last().unwrap());
    }

    // The previous list needs two new lookahead nodes.
    boundary_pm(lists, leaves, current_list_index - 1);
    boundary_pm(lists, leaves, current_list_index - 1);
}

fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
    let last_index = lists.len() - 1;
    boundary_pm(lists, leaves, last_index);
}

fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let next_leaf_index = lists[current_list_index].next_leaf_index;
    let num_symbols = leaves.len();

    if current_list_index == 0 && next_leaf_index == num_symbols {
        // We've added all the leaves to the lowest list, so we're done here
        return;
    }

    mem::swap(&mut lists[current_list_index].lookahead1, &mut lists[current_list_index].lookahead2);

    if current_list_index == 0 {
        lowest_list(lists, leaves);
    } else {
        // We're at a list other than the lowest list.
        let weight_sum = {
            let previous_list = &lists[current_list_index - 1];
            previous_list.lookahead1.weight + previous_list.lookahead2.weight
        };

        if next_leaf_index < num_symbols && weight_sum > leaves[next_leaf_index].weight {
            next_leaf(lists, leaves, current_list_index);
        } else {
            next_tree(weight_sum, lists, leaves, current_list_index);
        }
    }
}

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate serde_json;

use request;

pub use types::{Account, CreateAccountResponse};

impl Account {
    pub fn new(short_name: &str, author_name: &str, author_url: &str) -> Account {
        Account {
            short_name: short_name.to_string(),
            author_name: author_name.to_string(),
            author_url: author_url.to_string(),
            access_token: "".to_string(),
            auth_url: "".to_string(),
            page_count: 0,
        }
    }

    pub fn set_short_name(&mut self, short_name: &str) -> &mut Account {
        self.short_name = short_name.to_string();
        self
    }

    pub fn set_author_name(&mut self, author_name: &str) -> &mut Account {
        self.author_name = author_name.to_string();
        self
    }

    pub fn set_author_url(&mut self, author_url: &str) -> &mut Account {
        self.author_url = author_url.to_string();
        self
    }

    pub fn set_auth_url(&mut self, auth_url: &str) -> &mut Account {
        self.auth_url = auth_url.to_string();
        self
    }

    pub fn set_access_token(&mut self, access_token: &str) -> &mut Account {
        self.access_token = access_token.to_string();
        self
    }

    pub fn create_account(&mut self) -> String {
        let req_url = format!(
            "https://api.telegra.ph/createAccount?short_name={}&author_name={}",
            self.short_name,
            self.author_name
        );
        let res_json = request::get(&req_url);
        let decoded: CreateAccountResponse = serde_json::from_str(&res_json).unwrap();

        self.set_access_token(&decoded.result.access_token)
            .set_auth_url(&decoded.result.auth_url);

        res_json
    }

    pub fn edit_accout_info(&self, acc: Account) -> String {
        let url = String::from("https://api.telegra.ph/editAccountInfo?");
        let mut params: Vec<String> = vec![];

        let access_token = "access_token=".to_string() + &if acc.access_token.len() == 0 {
                self.access_token.clone()
            } else {
                acc.access_token
            };
        params.push(access_token);

        if acc.short_name.len() > 0 {
            let short_name = "short_name=".to_string() + &acc.short_name;
            params.push(short_name);
        }
        if acc.author_url.len() > 0 {
            let author_url = "author_url=".to_string() + &acc.author_url;
            params.push(author_url);
        }
        if acc.author_name.len() > 0 {
            let author_name = "author_name=".to_string() + &acc.author_name;
            params.push(author_name);
        }
        if acc.auth_url.len() > 0 {
            let auth_url = "auth_url=".to_string() + &acc.auth_url;
            params.push(auth_url);
        }

        let url = url + &params.join("&");

        request::get(&url)
    }

}
<commit_msg>edit_accout_info method refactor, changed type of parameter<commit_after>extern crate hyper;
extern crate serde_json;

use request;

pub use types::{Account, CreateAccountResponse};

impl Account {
    pub fn new(short_name: &str, author_name: &str, author_url: &str) -> Account {
        Account {
            short_name: short_name.to_string(),
            author_name: author_name.to_string(),
            author_url: author_url.to_string(),
            access_token: "".to_string(),
            auth_url: "".to_string(),
            page_count: 0,
        }
    }

    pub fn set_short_name(&mut self, short_name: &str) -> &mut Account {
        self.short_name = short_name.to_string();
        self
    }

    pub fn set_author_name(&mut self, author_name: &str) -> &mut Account {
        self.author_name = author_name.to_string();
        self
    }

    pub fn set_author_url(&mut self, author_url: &str) -> &mut Account {
        self.author_url = author_url.to_string();
        self
    }

    pub fn set_auth_url(&mut self, auth_url: &str) -> &mut Account {
        self.auth_url = auth_url.to_string();
        self
    }

    pub fn set_access_token(&mut self, access_token: &str) -> &mut Account {
        self.access_token = access_token.to_string();
        self
    }

    pub fn create_account(&mut self) -> String {
        let url = format!(
            "https://api.telegra.ph/createAccount?short_name={}&author_name={}",
            self.short_name,
            self.author_name
        );
        let res_json = request::get(&url);
        let decoded: CreateAccountResponse = serde_json::from_str(&res_json).unwrap();

        self.set_access_token(&decoded.result.access_token)
            .set_auth_url(&decoded.result.auth_url);

        res_json
    }

    pub fn edit_accout_info(&self, acc: &Account) -> String {
        let url = String::from("https://api.telegra.ph/editAccountInfo?");
        let mut params: Vec<String> = vec![];

        let access_token = "access_token=".to_string() + &if acc.access_token.len() == 0 {
                self.access_token.clone()
            } else {
                acc.access_token.clone()
            };
        params.push(access_token);

        if acc.short_name.len() > 0 {
            let short_name = "short_name=".to_string() + &acc.short_name;
            params.push(short_name);
        }
        if acc.author_url.len() > 0 {
            let author_url = "author_url=".to_string() + &acc.author_url;
            params.push(author_url);
        }
        if acc.author_name.len() > 0 {
            let author_name = "author_name=".to_string() + &acc.author_name;
            params.push(author_name);
        }
        if acc.auth_url.len() > 0 {
            let auth_url = "auth_url=".to_string() + &acc.auth_url;
            params.push(auth_url);
        }

        let url = url + &params.join("&");

        request::get(&url)
    }

}
<|endoftext|>


<commit_before>use rustc_serialize::{Decodable, Decoder};
use std::fs::File;
use std::path::Path;
use toml;

use Result;

pub struct Details(pub toml::Value);

pub trait Detailable {
    fn detail<'l>(&mut self, Option<&'l toml::Value>);
    fn liated<'l>(&'l self) -> Option<&'l toml::Value>;

    fn lookup(&self, name: &str) -> Option<String> {
        self.liated().and_then(|toml| {
            match toml.lookup(name) {
                Some(&toml::Value::String(ref string)) => Some(string.clone()),
                _ => None,
            }
        })
    }
}

#[derive(RustcDecodable)]
pub struct Config {
    pub time: Option<Time>,
    pub power: Option<Power>,
    pub temperature: Option<Temperature>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Time {
    pub period: Option<f64>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Power {
    pub sources: Option<Vec<Source>>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Temperature {
    pub stack: Option<String>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Source {
    pub name: Option<String>,
    pub path: Option<String>,
    pub details: Option<Details>,
}

impl Config {
    pub fn new(path: &Path) -> Result<Config> {
        use std::io::Read;

        let mut contents = String::new();
        ok!(ok!(File::open(path)).read_to_string(&mut contents));

        let config = match toml::Parser::new(&contents).parse() {
            Some(root) => {
                let mut decoder = toml::Decoder::new(toml::Value::Table(root));
                let mut config: Config = ok!(Decodable::decode(&mut decoder));
                config.detail(decoder.toml.as_ref());
                config
            },
            _ => raise!("failed to parse the configuration file"),
        };

        Ok(config)
    }
}

impl Decodable for Details {
    #[inline]
    fn decode<D: Decoder>(_: &mut D) -> ::std::result::Result<Self, D::Error> {
        panic!("“details” is a reserved keyword");
    }
}

macro_rules! detailable(
    ($kind:ty, [$($scalar:ident),*], [$($vector:ident),*]) => (
        impl Detailable for $kind {
            fn detail<'l>(&mut self, toml: Option<&'l toml::Value>) {
                self.details = toml.and_then(|toml| {
                    $(
                        if let Some(ref mut child) = self.$scalar {
                            child.detail(toml.lookup(stringify!($scalar)));
                        }
                    )*
                    $(
                        if let Some(ref mut children) = self.$vector {
                            match toml.lookup(stringify!($vector)) {
                                Some(&toml::Value::Array(ref array)) => {
                                    for (child, toml) in children.iter_mut().zip(array) {
                                        child.detail(Some(toml));
                                    }
                                },
                                _ => {},
                            }
                        }
                    )*
                    Some(Details(toml.clone()))
                });
            }

            #[inline]
            fn liated<'l>(&'l self) -> Option<&'l toml::Value> {
                self.details.as_ref().map(|details| &details.0)
            }
        }
    );
    ($kind:ty, [$($scalar:ident),*]) => (
        detailable!($kind, [$($scalar),*], []);
    );
    ($kind:ty) => (
        detailable!($kind, [], []);
    );
);

detailable!(Config, [time, power, temperature]);

detailable!(Time);

detailable!(Power, [], [sources]);
detailable!(Source);

detailable!(Temperature);
<commit_msg>Torture Detailable again<commit_after>use rustc_serialize::{Decodable, Decoder};
use std::fs::File;
use std::path::Path;
use toml;

use Result;

pub struct Details(pub toml::Value);

pub trait Detailable {
    fn set_details<'l>(&mut self, Option<&'l toml::Value>);
    fn get_details<'l>(&'l self) -> Option<&'l toml::Value>;

    fn detail(&self, name: &str) -> Option<String> {
        self.get_details().and_then(|toml| {
            match toml.lookup(name) {
                Some(&toml::Value::String(ref string)) => Some(string.clone()),
                _ => None,
            }
        })
    }
}

#[derive(RustcDecodable)]
pub struct Config {
    pub time: Option<Time>,
    pub power: Option<Power>,
    pub temperature: Option<Temperature>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Time {
    pub period: Option<f64>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Power {
    pub sources: Option<Vec<Source>>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Temperature {
    pub stack: Option<String>,
    pub details: Option<Details>,
}

#[derive(RustcDecodable)]
pub struct Source {
    pub name: Option<String>,
    pub path: Option<String>,
    pub details: Option<Details>,
}

impl Config {
    pub fn new(path: &Path) -> Result<Config> {
        use std::io::Read;

        let mut contents = String::new();
        ok!(ok!(File::open(path)).read_to_string(&mut contents));

        let config = match toml::Parser::new(&contents).parse() {
            Some(root) => {
                let mut decoder = toml::Decoder::new(toml::Value::Table(root));
                let mut config: Config = ok!(Decodable::decode(&mut decoder));
                config.set_details(decoder.toml.as_ref());
                config
            },
            _ => raise!("failed to parse the configuration file"),
        };

        Ok(config)
    }
}

impl Decodable for Details {
    #[inline]
    fn decode<D: Decoder>(_: &mut D) -> ::std::result::Result<Self, D::Error> {
        panic!("“details” is a reserved keyword");
    }
}

macro_rules! implement(
    ($kind:ty, [$($scalar:ident),*], [$($vector:ident),*]) => (
        impl Detailable for $kind {
            fn set_details<'l>(&mut self, toml: Option<&'l toml::Value>) {
                self.details = toml.and_then(|toml| {
                    $(
                        if let Some(ref mut child) = self.$scalar {
                            child.set_details(toml.lookup(stringify!($scalar)));
                        }
                    )*
                    $(
                        if let Some(ref mut children) = self.$vector {
                            match toml.lookup(stringify!($vector)) {
                                Some(&toml::Value::Array(ref array)) => {
                                    for (child, toml) in children.iter_mut().zip(array) {
                                        child.set_details(Some(toml));
                                    }
                                },
                                _ => {},
                            }
                        }
                    )*
                    Some(Details(toml.clone()))
                });
            }

            #[inline]
            fn get_details<'l>(&'l self) -> Option<&'l toml::Value> {
                self.details.as_ref().map(|details| &details.0)
            }
        }
    );
    ($kind:ty, [$($scalar:ident),*]) => (
        implement!($kind, [$($scalar),*], []);
    );
    ($kind:ty) => (
        implement!($kind, [], []);
    );
);

implement!(Config, [time, power, temperature]);

implement!(Time);

implement!(Power, [], [sources]);
implement!(Source);

implement!(Temperature);
<|endoftext|>


<commit_before>use objectclass::ObjectClass;
use server::{Id, Entry, Result};

pub trait Transaction<D> {
    fn commit(self) -> Result<()>;

    // TODO: these are the guts of LmdbAdapter leaking out. They should get moved elsewhere
    fn get(&self, database: D, key: &[u8]) -> Result<&[u8]>;
    fn find<P>(&self, db: D, key: &[u8], predicate: P) -> Result<&[u8]> where P: Fn(&[u8]) -> bool;
}

pub trait Adapter<'a, D, R: Transaction<D>, W: Transaction<D>> {
    fn ro_transaction(&'a self) -> Result<R>;
    fn rw_transaction(&'a self) -> Result<W>;
    fn next_available_id(&self, txn: &W) -> Result<Id>;
    fn add_entry<'b>(&'b self,
                     txn: &'b mut W,
                     id: Id,
                     parent_id: Id,
                     name: &'b str,
                     objectclass: ObjectClass)
                     -> Result<Entry>;
    fn find_entry<'b, T: Transaction<D>>(&'b self, txn: &'b T, path: &str) -> Result<Entry>;
}
<commit_msg>Remove scary TODO message from Transaction<commit_after>use objectclass::ObjectClass;
use server::{Id, Entry, Result};

pub trait Transaction<D> {
    fn commit(self) -> Result<()>;
    fn get(&self, database: D, key: &[u8]) -> Result<&[u8]>;
    fn find<P>(&self, db: D, key: &[u8], predicate: P) -> Result<&[u8]> where P: Fn(&[u8]) -> bool;
}

pub trait Adapter<'a, D, R: Transaction<D>, W: Transaction<D>> {
    fn ro_transaction(&'a self) -> Result<R>;
    fn rw_transaction(&'a self) -> Result<W>;
    fn next_available_id(&self, txn: &W) -> Result<Id>;
    fn add_entry<'b>(&'b self,
                     txn: &'b mut W,
                     id: Id,
                     parent_id: Id,
                     name: &'b str,
                     objectclass: ObjectClass)
                     -> Result<Entry>;
    fn find_entry<'b, T: Transaction<D>>(&'b self, txn: &'b T, path: &str) -> Result<Entry>;
}
<|endoftext|>


<commit_before>use core::fmt;

/// Represents a physical memory address
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct PhysicalAddress(u64);

impl From<u64> for PhysicalAddress {
    fn from(value: u64) -> Self {
        PhysicalAddress(value)
    }
}

impl From<usize> for PhysicalAddress {
    fn from(value: usize) -> Self {
        PhysicalAddress(value as u64)
    }
}

impl PhysicalAddress {
    /// Convert to `u64`
    pub const fn as_u64(&self) -> u64 {
        self.0
    }
}

impl fmt::Binary for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

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

impl fmt::LowerHex for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::Octal for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::UpperHex for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Represent a virtual (linear) memory address
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct VirtualAddress(usize);

impl From<usize> for VirtualAddress {
    fn from(value: usize) -> Self {
        VirtualAddress(value)
    }
}

impl<T> From<*const T> for VirtualAddress {
    fn from(pointer: *const T) -> Self {
        VirtualAddress(pointer as usize)
    }
}

impl<T> From<*mut T> for VirtualAddress {
    fn from(pointer: *mut T) -> Self {
        VirtualAddress(pointer as usize)
    }
}

impl<'a, T> From<&'a T> for VirtualAddress {
    fn from(pointer: &T) -> Self {
        VirtualAddress::from(pointer as *const _)
    }
}

impl<'a, T> From<&'a mut T> for VirtualAddress {
    fn from(pointer: &mut T) -> Self {
        VirtualAddress::from(pointer as *mut _)
    }
}

impl VirtualAddress {
    /// Convert to `usize`
    pub const fn as_usize(&self) -> usize {
        self.0
    }
}

impl fmt::Binary for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

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

impl fmt::LowerHex for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::Octal for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::UpperHex for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}
<commit_msg>Revert "Implement more From conversions for VirtualAddress (but remove From<u64>)"<commit_after>use core::fmt;

/// Represents a physical memory address
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct PhysicalAddress(u64);

impl From<u64> for PhysicalAddress {
    fn from(value: u64) -> Self {
        PhysicalAddress(value)
    }
}

impl From<usize> for PhysicalAddress {
    fn from(value: usize) -> Self {
        PhysicalAddress(value as u64)
    }
}

impl PhysicalAddress {
    /// Convert to `u64`
    pub const fn as_u64(&self) -> u64 {
        self.0
    }
}

impl fmt::Binary for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

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

impl fmt::LowerHex for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::Octal for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::UpperHex for PhysicalAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Represent a virtual (linear) memory address
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct VirtualAddress(usize);

impl From<usize> for VirtualAddress {
    fn from(value: usize) -> Self {
        VirtualAddress(value)
    }
}

impl From<u64> for VirtualAddress {
    fn from(value: u64) -> Self {
        VirtualAddress(value as usize)
    }
}

impl VirtualAddress {
    /// Convert to `usize`
    pub const fn as_usize(&self) -> usize {
        self.0
    }
}

impl fmt::Binary for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

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

impl fmt::LowerHex for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::Octal for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl fmt::UpperHex for VirtualAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}
<|endoftext|>


<commit_before>
use ai::StatelessAI;

use game;
use game::{Action, GameStructure, PlayerColor, LineState, VictoryState};
use std::rc::Rc;

pub fn easy_judgement(structure: &GameStructure, state: &game::State, my_color: PlayerColor) -> i32 {
    let mut score = 0;

    for subset in &structure.source {
        score += match subset.win_state(state) {
            LineState::Empty => 0,
            LineState::Win(color) => 1000 * (if color == my_color { 1 } else { -1 }),
            // If I'm still allowed to play, that must have been my win.
            LineState::Mixed => 0,
            LineState::Pure { color, count } => {
                println!("{:?} -> {:?}:{}", subset, color, count);
                (count * count * (if color == my_color { 1 } else { -1 })) as i32
            }
        }
    }

    score
}

#[allow(dead_code)]
pub struct TreeJudgementAI {
    structure: Rc<game::GameStructure>,
    search_depth: i8,
}

#[allow(dead_code)]
impl TreeJudgementAI {
    pub fn new(structure: Rc<GameStructure>, depth: i8) -> TreeJudgementAI {
        TreeJudgementAI {
            structure: structure,
            search_depth: depth,
        }
    }
}

impl StatelessAI for TreeJudgementAI {
    fn action(&self, state: &game::State) -> Action {
        let my_color = state.current_color;
        // Create a tree from the current gamestate.
        let mut tree: Node<MinMaxTagging> = Node::new(state.clone(), None);
        // Completely expand the first n layers
        tree.fully_expand_to_depth(&self.structure, self.search_depth);

        let my_easy_judgement = |state: &game::State| {
            MinMaxTagging {
                value: easy_judgement(&self.structure, state, my_color),
                from_action: None,
            }
        };

        tree.tag_all_leaves(&my_easy_judgement);
        min_max(&mut tree);

        let action = tree.tag.from_action.unwrap_or(Action::Surrender);
        println!("{:?} deciding on '{:?}' with valuation {:?}.",
                 my_color,
                 action,
                 tree.tag.value);
        return action;
    }
}

// The type parameter T can carry additional information (like a score)
// and needs to allow a default.
struct Node<T: Default> {
    state: game::State,
    children: Branching<T>,
    parent_action: Option<Action>, // If this isn't the root, how did we get here?
    tag: T,
}

enum Branching<T: Default> {
    GameOver,
    Unexpanded,
    Expanded(Vec<Node<T>>),
}

impl<T: Default> Node<T> {
    pub fn new(state: game::State, parent_action: Option<Action>) -> Node<T> {
        Node {
            state: state,
            children: Branching::Unexpanded,
            parent_action: parent_action,
            tag: Default::default(),
        }
    }

    // Expands the current supplied node, if neccessary.
    // The return value indicates if it was expanded.
    fn expand_total(&mut self, structure: &GameStructure) -> bool {
        match self.children {
            Branching::Unexpanded => {
                let mut children = Vec::new();
                for action in self.state.legal_actions() {
                    let mut new_state = self.state.clone();
                    new_state.execute(structure, action);
                    let mut child =
                        Node::new(new_state,
                                  Some(action.clone()));
                    if child.state.victory_state != VictoryState::Undecided {
                        child.children = Branching::GameOver;
                    }
                    children.push(child);
                }
                if children.len() == 0 {
                    self.children = Branching::GameOver;
                } else {
                    self.children = Branching::Expanded(children);
                }
                true
            }
            Branching::Expanded(_) => false,
            Branching::GameOver => false,
        }
    }

    fn fully_expand_to_depth(&mut self, structure: &GameStructure, depth: i8) {
        if depth <= 0 {
            return;
        }
        self.expand_total(structure);
        match self.children {
            Branching::Expanded(ref mut children) => {
                for mut child in children {
                    child.fully_expand_to_depth(structure, depth - 1);
                }
            }
            _ => (),
        }
    }

    fn tag_all_leaves<F>(&mut self, tagger: &F)
        where F: Fn(&game::State) -> T
    {
        match self.children {
            Branching::GameOver => self.tag = tagger(&self.state),
            Branching::Unexpanded => self.tag = tagger(&self.state),
            Branching::Expanded(ref mut children) => {
                for mut child in children {
                    child.tag_all_leaves(tagger);
                }
            }
        }
    }
}

#[derive(Default, Debug)]
struct MinMaxTagging {
    value: i32,
    from_action: Option<Action>,
}

fn min_max(node: &mut Node<MinMaxTagging>) {
    match node.children {
        Branching::Expanded(ref mut children) => {
            let mut max = i32::min_value();
            let mut action = None;
            for mut child in children {
                max_min(&mut child);
                if child.tag.value > max {
                    max = child.tag.value;
                    action = child.parent_action;
                }
            }
            node.tag.value = max;
            node.tag.from_action = action;
        }
        _ => (), // Leaves don't min-max
    }
}

fn max_min(node: &mut Node<MinMaxTagging>) {
    match node.children {
        Branching::Expanded(ref mut children) => {
            let mut min = i32::max_value();
            let mut action = None;
            for mut child in children {
                min_max(&mut child);
                if child.tag.value < min {
                    min = child.tag.value;
                    action = child.parent_action;
                }
            }
            node.tag.value = min;
            node.tag.from_action = action;
        }
        _ => (), // Leaves don't min-max
    }
}
<commit_msg>Rewrote the tree.rs AI.<commit_after>
use ai::StatelessAI;

use game;
use game::{Action, GameStructure, PlayerColor, LineState};
use std::rc::Rc;

pub fn easy_judgement(structure: &GameStructure,
                      state: &game::State,
                      my_color: PlayerColor)
                      -> i32 {
    let mut score = 0;

    for subset in &structure.source {
        score += match subset.win_state(state) {
            LineState::Empty => 0,
            LineState::Win(color) => 1000 * (if color == my_color { 1 } else { -1 }),
            // If I'm still allowed to play, that must have been my win.
            LineState::Mixed => 0,
            LineState::Pure { color, count } => {
                (count * count * (if color == my_color { 1 } else { -1 })) as i32
            }
        }
    }

    score
}

pub fn recursive_judgement(structure: &GameStructure,
                           state: &game::State,
                           my_color: PlayerColor,
                           depth: i8)
                           -> i32 {
    if depth == 0 {
        easy_judgement(structure, state, my_color)
    } else {
        let values = state
            .legal_actions()
            .map(|action| {
                     let mut new_state = state.clone();
                     new_state.execute(structure, action);
                     let value = recursive_judgement(structure, &new_state, my_color, depth - 1);
                     value
                 });

        if state.current_color == my_color {
            values.max()
        } else {
            values.min()
        }.unwrap_or_else(|| easy_judgement(structure, state, my_color))
    }
}

#[allow(dead_code)]
pub struct TreeJudgementAI {
    structure: Rc<game::GameStructure>,
    search_depth: i8,
}

#[allow(dead_code)]
impl TreeJudgementAI {
    pub fn new(structure: Rc<GameStructure>, depth: i8) -> TreeJudgementAI {
        TreeJudgementAI {
            structure: structure,
            search_depth: depth,
        }
    }
}

impl StatelessAI for TreeJudgementAI {
    fn action(&self, state: &game::State) -> Action {
        let my_color = state.current_color;

        let (best_action, best_value) = state.legal_actions()
            .map(|action| {
                     let mut new_state = state.clone();
                     new_state.execute(&self.structure, action);
                     let value = recursive_judgement(&self.structure,
                                                       &new_state,
                                                       my_color,
                                                       self.search_depth - 1);
                     (action, value)
                 })
            .max_by_key(|&(_, value)| value)
            .unwrap();

        println!("Executing {:?} with value {}.", best_action, best_value);

        best_action
    }
}
<|endoftext|>


<commit_before>extern crate libc;

pub mod anoncreds;
pub mod sovrin;
pub mod wallet;

use std::collections::HashMap;
use std::mem;
use std::sync::{Arc, Mutex, Once, ONCE_INIT};

use self::libc::{c_char, c_uchar};
use super::SovrinClient;

#[derive(Clone)]
pub struct SingletonClients {
    inner: Arc<Mutex<(HashMap<i32, SovrinClient>, i32)>>
}

pub fn get_active_clients() -> SingletonClients {
    static mut SINGLETON: *const SingletonClients = 0 as *const SingletonClients;
    static ONCE: Once = ONCE_INIT;

    unsafe {
        ONCE.call_once(|| {
            let singleton = SingletonClients {
                inner: Arc::new(Mutex::new((HashMap::new(), 1)))
            };
            SINGLETON = mem::transmute(Box::new(singleton));
        });
        (*SINGLETON).clone()
    }
}

#[no_mangle]
pub extern fn init_client(host_and_port: *const c_char) -> i32 {
    let s = get_active_clients();
    let (ref mut clients, mut cl_id): (HashMap<i32, SovrinClient>, i32) = *s.inner.lock().unwrap();

    while clients.contains_key(&cl_id) {
        cl_id += 1;
        if cl_id < 0 {
            cl_id = 1;
        }
    }

    clients.insert(cl_id, SovrinClient::new());

    cl_id
}

#[no_mangle]
pub extern fn release_client(client_id: i32) -> i32 {
    let s = get_active_clients();
    let ref mut clients: HashMap<i32, SovrinClient> = (*s.inner.lock().unwrap()).0;

    if clients.contains_key(&client_id) {
        clients.remove(&client_id);
        0
    } else {
        -1
    }
}

#[no_mangle]
pub extern fn free_str(c_ptr: *mut c_char) {
    unimplemented!();
}

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

    #[test]
    fn sovrin_client_can_be_created() {
        let empty = CString::new("").unwrap();
        init_client(empty.as_ptr());
    }

    #[test]
    fn sovrin_client_can_be_created_and_freed() {
        let empty = CString::new("").unwrap();
        let id = init_client(empty.as_ptr());
        let other_id = id + 1;
        assert_eq!(0, release_client(id));
        assert_eq!(-1, release_client(other_id));
        //TODO create more complex example: use different threads
    }

//        TODO: check memory consumption
//        #[test]
//        fn sovrin_client_no_leak() {
//            let empty = CString::new("").unwrap();
//            for i in 1..1000000 {
//                let id = init_client(empty.as_ptr());
//                assert_eq!(0, release_client(id));
//            }
//        }
}
<commit_msg>Use CommandExecutor instead of SovrinClient in new version of C API (Rust API was removed).<commit_after>extern crate libc;

pub mod anoncreds;
pub mod sovrin;
pub mod wallet;

use std::collections::HashMap;
use std::mem;
use std::sync::{Arc, Mutex, Once, ONCE_INIT};

use self::libc::{c_char, c_uchar};
use commands::CommandExecutor;

#[derive(Clone)]
pub struct SingletonClients {
    inner: Arc<Mutex<(HashMap<i32, CommandExecutor>, i32)>>
}

pub fn get_active_clients() -> SingletonClients {
    static mut SINGLETON: *const SingletonClients = 0 as *const SingletonClients;
    static ONCE: Once = ONCE_INIT;

    unsafe {
        ONCE.call_once(|| {
            let singleton = SingletonClients {
                inner: Arc::new(Mutex::new((HashMap::new(), 1)))
            };
            SINGLETON = mem::transmute(Box::new(singleton));
        });
        (*SINGLETON).clone()
    }
}

#[no_mangle]
pub extern fn init_client(host_and_port: *const c_char) -> i32 {
    let s = get_active_clients();
    let (ref mut clients, mut cl_id): (HashMap<i32, CommandExecutor>, i32) = *s.inner.lock().unwrap();

    while clients.contains_key(&cl_id) {
        cl_id += 1;
        if cl_id < 0 {
            cl_id = 1;
        }
    }

    clients.insert(cl_id, CommandExecutor::new());

    cl_id
}

#[no_mangle]
pub extern fn release_client(client_id: i32) -> i32 {
    let s = get_active_clients();
    let ref mut clients: HashMap<i32, CommandExecutor> = (*s.inner.lock().unwrap()).0;

    if clients.contains_key(&client_id) {
        clients.remove(&client_id);
        0
    } else {
        -1
    }
}

#[no_mangle]
pub extern fn free_str(c_ptr: *mut c_char) {
    unimplemented!();
}

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

    #[test]
    fn sovrin_client_can_be_created() {
        let empty = CString::new("").unwrap();
        init_client(empty.as_ptr());
    }

    #[test]
    fn sovrin_client_can_be_created_and_freed() {
        let empty = CString::new("").unwrap();
        let id = init_client(empty.as_ptr());
        let other_id = id + 1;
        assert_eq!(0, release_client(id));
        assert_eq!(-1, release_client(other_id));
        //TODO create more complex example: use different threads
    }

//        TODO: check memory consumption
//        #[test]
//        fn sovrin_client_no_leak() {
//            let empty = CString::new("").unwrap();
//            for i in 1..1000000 {
//                let id = init_client(empty.as_ptr());
//                assert_eq!(0, release_client(id));
//            }
//        }
}
<|endoftext|>


<commit_before>#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Export {
    pub name: String,
    pub func: String,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum Expr {
    Add(Typ,Box<Expr>,Box<Expr>),
    Return(usize),
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Function {
    pub name: String,
    pub params: Vec<Var>,
    pub result: Option<Typ>,
    pub locals: Vec<Var>,
    pub body: Vec<Expr>,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Import {
    pub func: String,
    pub module: String,
    pub name: String,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Memory {
    pub init: usize,
    pub max: Option<usize>,
    pub segments: Vec<Segment>,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Module {
    pub memory: Option<Memory>,
    pub imports: Vec<Import>,
    pub exports: Vec<Export>,
    pub functions: Vec<Function>,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Segment {
    pub addr: usize,
    pub data: String,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum Typ {
    I32,
    I64,
    F32,
    F64,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Var {
    pub name: String,
    pub typ: Typ,
}
<commit_msg>Added FunctionTyp to AST.<commit_after>#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Export {
    pub name: String,
    pub func: String,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum Expr {
    Add(Typ,Box<Expr>,Box<Expr>),
    Return(usize),
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Function {
    pub name: String,
    pub typ: FunctionTyp,
    pub locals: Vec<Var>,
    pub body: Vec<Expr>,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct FunctionTyp {
    pub params: Vec<Var>,
    pub result: Option<Typ>,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Import {
    pub func: String,
    pub module: String,
    pub name: String,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Memory {
    pub init: usize,
    pub max: Option<usize>,
    pub segments: Vec<Segment>,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Module {
    pub memory: Option<Memory>,
    pub imports: Vec<Import>,
    pub exports: Vec<Export>,
    pub functions: Vec<Function>,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Segment {
    pub addr: usize,
    pub data: String,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum Typ {
    I32,
    I64,
    F32,
    F64,
}

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub struct Var {
    pub name: String,
    pub typ: Typ,
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::cell::RefCell;

use conf::{RemoteBranch};
use constants::{CHANGED_KEY,NEW_KEY,STAGED_KEY,CONFLICTS_KEY};

use git2::*;

struct Cache {
    current_branch_name: RefCell<Option<String>>,
    // TODO: Reference can't be cached (can't be cloned)
    //       implement via OID
    // head: RefCell<Option<Oid>>,
}

pub struct Backend {
    cache: Cache,
    pub repo: Repository,
    pub debug: bool,
}

pub struct BranchAheadBehind {
    pub local_branch_name: Option<String>,
    pub remote_branch_name: Option<String>,
    pub remote_name: Option<String>,
    pub ahead: usize,
    pub behind: usize
}

impl BranchAheadBehind {
    fn new(l: Option<String>) -> BranchAheadBehind {
        BranchAheadBehind{ local_branch_name: l, remote_branch_name: None, remote_name: None,
                           ahead: 0, behind: 0 }
    }
}

#[derive(Clone)]
struct RefPair {
    remote_name: String,
    branch_name: String,
    oid: Oid,
}

impl Cache {
    pub fn new() -> Cache {
        Cache{ current_branch_name: RefCell::new(None) }
    }

    fn set_current_branch_name(&self, n: Option<String>) {
        let mut c = self.current_branch_name.borrow_mut();
        *c = n;
    }

    fn is_current_branch_set(&self) -> bool {
        self.current_branch_name.borrow().is_some()
    }

    fn get_current_branch(&self) -> Option<String> {
        self.current_branch_name.borrow().clone()
    }
}

impl Backend {
    pub fn new(repo: Repository, debug: bool) -> Backend {
        Backend{ repo: repo, debug: debug, cache: Cache::new() }
    }

    fn get_head(&self) -> Option<Reference> {
        match self.repo.head() {
            Ok(head) => Some(head),
            Err(e2) => {
                log!(self, "Can't get HEAD: {}", e2);
                match self.repo.find_reference("HEAD") {
                    Ok(x) => {
                        log!(self, "Found HEAD directly: {:?}", x.name());
                        Some(x)
                    },
                    Err(e) => {
                        log!(self, "reference HEAD: {}", e);
                        return None
                    },
                }
            },
        }
    }

    fn get_current_branch_oid(&self) -> Option<Oid> {
        let head = self.get_head();
        match head {
            Some(v) => v.target(),
            None => {
                log!(self, "Failed to find Oid for HEAD.");
                return None
            },
        }
    }

    fn resolve_symbolic_reference<'a>(&self, reference: Option<Reference<'a>>) -> Option<Reference<'a>> {
        let s_reference = match reference {
            Some(v) => {
                match v.resolve() {
                    Ok(y) => {
                        log!(self, "Branch name is {:?}", y.name());
                        y
                    },
                    Err(e) => {
                        log!(self, "Branch name is {:?}, error: {:?}", v.name(), e);
                        v
                    }
                }
            }
            None => {
                log!(self, "No branch name found");
                return None;
            }
        };
        Some(s_reference)
    }

    fn get_branch_name_for_reference(&self, r: Reference) -> Option<String> {
        if let Some(ref_name_string) = r.shorthand() {
            if ref_name_string != "HEAD" {
                let s = ref_name_string.to_string();
                log!(self, "Shorthand for reference is: {}", s);
                return Some(s);
            } else {
                if let Some(ref_name) = r.symbolic_target() {
                    let ref_name_string = ref_name.to_string();
                    log!(self, "shorthand = HEAD, links to: {}", ref_name_string);
                    let mut path: Vec<&str> = ref_name_string.split('/').collect();
                    if let Some(branch_short) = path.pop() {
                        let s = branch_short.to_string();
                        log!(self, "Last part of full name is: {}", s);
                        return Some(s);
                    }
                }
            }
        }

        // we're getting the commit hash as name
        match r.target() {
            Some(v) => {
                let hash_str = v.to_string();
                if hash_str.len() >= 8 {
                    let (s, _) = hash_str.split_at(7);
                    Some(s.to_string())
                } else {
                    Some(hash_str)
                }
            },
            None => None,
        }
    }

    pub fn get_current_branch_name(&mut self) -> Option<String> {
        if self.cache.is_current_branch_set() {
            return self.cache.get_current_branch();
        }
        let mut head: Option<Reference> = None;
        if head.is_none() {
            head = self.get_head();
        }
        let h = match self.resolve_symbolic_reference(head) {
            Some(v) => v,
            None => return None,
        };
        let current_branch_name = self.get_branch_name_for_reference(h);
        self.cache.set_current_branch_name(current_branch_name.clone());
        current_branch_name
    }

    fn get_branch_remote(&self, reference: Reference) -> Option<RefPair> {
        let b = Branch::wrap(reference);
        let upstream = match b.upstream() {
            Ok(u) => u,
            Err(e) => {
                log!(self, "Can't get upstream branch for {:?}: {:?}", b.name(), e);
                return None;
            }
        };
        let branch_name = match upstream.name() {
            Ok(o_n) => match o_n {
                Some(n) => n,
                None => {
                    log!(self, "Invalid branch name");
                    return None;
                },
            },
            Err(e) => {
                log!(self, "Error while getting name for upstream branch: {:?}", e);
                return None;
            }
        };
        let upstream_reference = upstream.get();
        let oid = match upstream_reference.target() {
            Some(o) => o,
            None => {
                log!(self, "Can't get oid of upstream branch");
                return None;
            }
        };
        let remote_name = match upstream_reference.name() {
            Some(n) => {
                let v: Vec<&str> = n.splitn(3, "/").collect();
                if v.len() >= 3 {
                    v[1]
                } else {
                    log!(self, "Can't figure out remote name: {:?}", v);
                    return None;
                }
            },
            None => {
                log!(self, "Can't get full name of upstream branch.");
                return None;
            }
        };
        Some(RefPair{ remote_name: remote_name.to_string(),
                      branch_name: branch_name.to_string(), oid: oid })
    }

    fn get_current_branch_remote_oid(&self) -> Option<RefPair> {
        match self.get_head() {
            Some(r) => self.get_branch_remote(r),
            None => None
        }
    }

    pub fn get_branch_ahead_behind(&mut self, remote_branch: Option<RemoteBranch>) -> Option<BranchAheadBehind> {
        let current_branch_name = self.get_current_branch_name();
        log!(self, "Current branch name = {:?}", current_branch_name);
        let mut ab = BranchAheadBehind::new(current_branch_name);
        let ref_pair_option = self.get_remote_branch(remote_branch);
        let ref_pair = match ref_pair_option {
            Some(u) => {
                u.clone()
            },
            None => return Some(ab),
        };
        ab.remote_branch_name = Some(ref_pair.branch_name.clone());
        ab.remote_name = Some(ref_pair.remote_name);

        let oid = match self.get_current_branch_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(oid, ref_pair.oid);
        match res {
            Ok((a, b)) => {
                ab.ahead = a;
                ab.behind = b;
            },
            Err(e) => {
                log!(self, "Can't get ahead & behind stats for branch {}: {:?}", ref_pair.branch_name, e);
            }
        };
        Some(ab)
    }

    // find remote branch if branch_name is specified
    // if not, get remote tracking branch for current branch
    fn get_remote_branch(&self, remote_branch: Option<RemoteBranch>) -> Option<RefPair> {
        match remote_branch {
            Some(b) => {
                match self.repo.find_branch(&b.remote_branch, BranchType::Remote) {
                    Ok(o) => Some(RefPair{ branch_name: b.remote_branch_name,
                                           remote_name: b.remote_name,
                                           oid: o.into_reference().target().unwrap() }),
                    Err(e) => {
                        // don't panic here - it doesn't exist, we don't care
                        log!(self, "No remote branch found for {}: {:?}", b.remote_branch_name, e);
                        None
                    }
                }
            },
            None => {
                self.get_current_branch_remote_oid()
            }
        }
    }

    pub fn get_status(&self) -> Option<Statuses> {
        let mut so = StatusOptions::new();
        let mut opts = so.show(StatusShow::IndexAndWorkdir);
        opts.include_untracked(true);
        match self.repo.statuses(Some(&mut opts)) {
            Ok(s) => Some(s),
            Err(e) => {
                log!(self, "Unable to get status of repository: {:?}", e);
                None
            }
        }
    }

    pub fn get_repository_state(&self) -> String {
        let state = self.repo.state();
        match state {
            RepositoryState::Clean => String::from(""),  // XXX: this seems to be hardcoded
            RepositoryState::Merge => String::from("merge"),
            RepositoryState::Revert | RepositoryState::RevertSequence => String::from("revert"),
            RepositoryState::CherryPick | RepositoryState::CherryPickSequence => String::from("cherry-pick"),
            RepositoryState::Bisect => String::from("bisect"),
            RepositoryState::Rebase |
                RepositoryState::RebaseInteractive |
                RepositoryState::RebaseMerge => String::from("rebase"),
            RepositoryState::ApplyMailbox | RepositoryState::ApplyMailboxOrRebase => String::from("apply"),
        }
    }

    pub fn get_file_status(&self) -> Option<HashMap<&str, u32>> {
        let mut d = HashMap::new();

        let changed = STATUS_WT_MODIFIED | STATUS_WT_DELETED | STATUS_WT_TYPECHANGE | STATUS_WT_RENAMED;
        let staged = STATUS_INDEX_MODIFIED | STATUS_INDEX_DELETED | STATUS_INDEX_TYPECHANGE | STATUS_INDEX_RENAMED | STATUS_INDEX_NEW;

        let statuses = match self.get_status() {
            Some(x) => x,
            None => return None,
        };

        for s in statuses.iter() {
            let file_status = s.status();
            log!(self, "{}", s.path().unwrap());

            if file_status.intersects(changed) {
                let counter = d.entry(CHANGED_KEY).or_insert(0);
                *counter += 1;
            };
            if file_status.contains(STATUS_WT_NEW) {
                let counter = d.entry(NEW_KEY).or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(staged) {
                let counter = d.entry(STAGED_KEY).or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(STATUS_CONFLICTED) {
                let counter = d.entry(CONFLICTS_KEY).or_insert(0);
                *counter += 1;
            };
        }
        Some(d)
    }
}
<commit_msg>clippy: useless return<commit_after>use std::collections::HashMap;
use std::cell::RefCell;

use conf::{RemoteBranch};
use constants::{CHANGED_KEY,NEW_KEY,STAGED_KEY,CONFLICTS_KEY};

use git2::*;

struct Cache {
    current_branch_name: RefCell<Option<String>>,
    // TODO: Reference can't be cached (can't be cloned)
    //       implement via OID
    // head: RefCell<Option<Oid>>,
}

pub struct Backend {
    cache: Cache,
    pub repo: Repository,
    pub debug: bool,
}

pub struct BranchAheadBehind {
    pub local_branch_name: Option<String>,
    pub remote_branch_name: Option<String>,
    pub remote_name: Option<String>,
    pub ahead: usize,
    pub behind: usize
}

impl BranchAheadBehind {
    fn new(l: Option<String>) -> BranchAheadBehind {
        BranchAheadBehind{ local_branch_name: l, remote_branch_name: None, remote_name: None,
                           ahead: 0, behind: 0 }
    }
}

#[derive(Clone)]
struct RefPair {
    remote_name: String,
    branch_name: String,
    oid: Oid,
}

impl Cache {
    pub fn new() -> Cache {
        Cache{ current_branch_name: RefCell::new(None) }
    }

    fn set_current_branch_name(&self, n: Option<String>) {
        let mut c = self.current_branch_name.borrow_mut();
        *c = n;
    }

    fn is_current_branch_set(&self) -> bool {
        self.current_branch_name.borrow().is_some()
    }

    fn get_current_branch(&self) -> Option<String> {
        self.current_branch_name.borrow().clone()
    }
}

impl Backend {
    pub fn new(repo: Repository, debug: bool) -> Backend {
        Backend{ repo: repo, debug: debug, cache: Cache::new() }
    }

    fn get_head(&self) -> Option<Reference> {
        match self.repo.head() {
            Ok(head) => Some(head),
            Err(e2) => {
                log!(self, "Can't get HEAD: {}", e2);
                match self.repo.find_reference("HEAD") {
                    Ok(x) => {
                        log!(self, "Found HEAD directly: {:?}", x.name());
                        Some(x)
                    },
                    Err(e) => {
                        log!(self, "reference HEAD: {}", e);
                        None
                    },
                }
            },
        }
    }

    fn get_current_branch_oid(&self) -> Option<Oid> {
        let head = self.get_head();
        match head {
            Some(v) => v.target(),
            None => {
                log!(self, "Failed to find Oid for HEAD.");
                None
            },
        }
    }

    fn resolve_symbolic_reference<'a>(&self, reference: Option<Reference<'a>>) -> Option<Reference<'a>> {
        let s_reference = match reference {
            Some(v) => {
                match v.resolve() {
                    Ok(y) => {
                        log!(self, "Branch name is {:?}", y.name());
                        y
                    },
                    Err(e) => {
                        log!(self, "Branch name is {:?}, error: {:?}", v.name(), e);
                        v
                    }
                }
            }
            None => {
                log!(self, "No branch name found");
                return None;
            }
        };
        Some(s_reference)
    }

    fn get_branch_name_for_reference(&self, r: Reference) -> Option<String> {
        if let Some(ref_name_string) = r.shorthand() {
            if ref_name_string != "HEAD" {
                let s = ref_name_string.to_string();
                log!(self, "Shorthand for reference is: {}", s);
                return Some(s);
            } else {
                if let Some(ref_name) = r.symbolic_target() {
                    let ref_name_string = ref_name.to_string();
                    log!(self, "shorthand = HEAD, links to: {}", ref_name_string);
                    let mut path: Vec<&str> = ref_name_string.split('/').collect();
                    if let Some(branch_short) = path.pop() {
                        let s = branch_short.to_string();
                        log!(self, "Last part of full name is: {}", s);
                        return Some(s);
                    }
                }
            }
        }

        // we're getting the commit hash as name
        match r.target() {
            Some(v) => {
                let hash_str = v.to_string();
                if hash_str.len() >= 8 {
                    let (s, _) = hash_str.split_at(7);
                    Some(s.to_string())
                } else {
                    Some(hash_str)
                }
            },
            None => None,
        }
    }

    pub fn get_current_branch_name(&mut self) -> Option<String> {
        if self.cache.is_current_branch_set() {
            return self.cache.get_current_branch();
        }
        let mut head: Option<Reference> = None;
        if head.is_none() {
            head = self.get_head();
        }
        let h = match self.resolve_symbolic_reference(head) {
            Some(v) => v,
            None => return None,
        };
        let current_branch_name = self.get_branch_name_for_reference(h);
        self.cache.set_current_branch_name(current_branch_name.clone());
        current_branch_name
    }

    fn get_branch_remote(&self, reference: Reference) -> Option<RefPair> {
        let b = Branch::wrap(reference);
        let upstream = match b.upstream() {
            Ok(u) => u,
            Err(e) => {
                log!(self, "Can't get upstream branch for {:?}: {:?}", b.name(), e);
                return None;
            }
        };
        let branch_name = match upstream.name() {
            Ok(o_n) => match o_n {
                Some(n) => n,
                None => {
                    log!(self, "Invalid branch name");
                    return None;
                },
            },
            Err(e) => {
                log!(self, "Error while getting name for upstream branch: {:?}", e);
                return None;
            }
        };
        let upstream_reference = upstream.get();
        let oid = match upstream_reference.target() {
            Some(o) => o,
            None => {
                log!(self, "Can't get oid of upstream branch");
                return None;
            }
        };
        let remote_name = match upstream_reference.name() {
            Some(n) => {
                let v: Vec<&str> = n.splitn(3, "/").collect();
                if v.len() >= 3 {
                    v[1]
                } else {
                    log!(self, "Can't figure out remote name: {:?}", v);
                    return None;
                }
            },
            None => {
                log!(self, "Can't get full name of upstream branch.");
                return None;
            }
        };
        Some(RefPair{ remote_name: remote_name.to_string(),
                      branch_name: branch_name.to_string(), oid: oid })
    }

    fn get_current_branch_remote_oid(&self) -> Option<RefPair> {
        match self.get_head() {
            Some(r) => self.get_branch_remote(r),
            None => None
        }
    }

    pub fn get_branch_ahead_behind(&mut self, remote_branch: Option<RemoteBranch>) -> Option<BranchAheadBehind> {
        let current_branch_name = self.get_current_branch_name();
        log!(self, "Current branch name = {:?}", current_branch_name);
        let mut ab = BranchAheadBehind::new(current_branch_name);
        let ref_pair_option = self.get_remote_branch(remote_branch);
        let ref_pair = match ref_pair_option {
            Some(u) => {
                u.clone()
            },
            None => return Some(ab),
        };
        ab.remote_branch_name = Some(ref_pair.branch_name.clone());
        ab.remote_name = Some(ref_pair.remote_name);

        let oid = match self.get_current_branch_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(oid, ref_pair.oid);
        match res {
            Ok((a, b)) => {
                ab.ahead = a;
                ab.behind = b;
            },
            Err(e) => {
                log!(self, "Can't get ahead & behind stats for branch {}: {:?}", ref_pair.branch_name, e);
            }
        };
        Some(ab)
    }

    // find remote branch if branch_name is specified
    // if not, get remote tracking branch for current branch
    fn get_remote_branch(&self, remote_branch: Option<RemoteBranch>) -> Option<RefPair> {
        match remote_branch {
            Some(b) => {
                match self.repo.find_branch(&b.remote_branch, BranchType::Remote) {
                    Ok(o) => Some(RefPair{ branch_name: b.remote_branch_name,
                                           remote_name: b.remote_name,
                                           oid: o.into_reference().target().unwrap() }),
                    Err(e) => {
                        // don't panic here - it doesn't exist, we don't care
                        log!(self, "No remote branch found for {}: {:?}", b.remote_branch_name, e);
                        None
                    }
                }
            },
            None => {
                self.get_current_branch_remote_oid()
            }
        }
    }

    pub fn get_status(&self) -> Option<Statuses> {
        let mut so = StatusOptions::new();
        let mut opts = so.show(StatusShow::IndexAndWorkdir);
        opts.include_untracked(true);
        match self.repo.statuses(Some(&mut opts)) {
            Ok(s) => Some(s),
            Err(e) => {
                log!(self, "Unable to get status of repository: {:?}", e);
                None
            }
        }
    }

    pub fn get_repository_state(&self) -> String {
        let state = self.repo.state();
        match state {
            RepositoryState::Clean => String::from(""),  // XXX: this seems to be hardcoded
            RepositoryState::Merge => String::from("merge"),
            RepositoryState::Revert | RepositoryState::RevertSequence => String::from("revert"),
            RepositoryState::CherryPick | RepositoryState::CherryPickSequence => String::from("cherry-pick"),
            RepositoryState::Bisect => String::from("bisect"),
            RepositoryState::Rebase |
                RepositoryState::RebaseInteractive |
                RepositoryState::RebaseMerge => String::from("rebase"),
            RepositoryState::ApplyMailbox | RepositoryState::ApplyMailboxOrRebase => String::from("apply"),
        }
    }

    pub fn get_file_status(&self) -> Option<HashMap<&str, u32>> {
        let mut d = HashMap::new();

        let changed = STATUS_WT_MODIFIED | STATUS_WT_DELETED | STATUS_WT_TYPECHANGE | STATUS_WT_RENAMED;
        let staged = STATUS_INDEX_MODIFIED | STATUS_INDEX_DELETED | STATUS_INDEX_TYPECHANGE | STATUS_INDEX_RENAMED | STATUS_INDEX_NEW;

        let statuses = match self.get_status() {
            Some(x) => x,
            None => return None,
        };

        for s in statuses.iter() {
            let file_status = s.status();
            log!(self, "{}", s.path().unwrap());

            if file_status.intersects(changed) {
                let counter = d.entry(CHANGED_KEY).or_insert(0);
                *counter += 1;
            };
            if file_status.contains(STATUS_WT_NEW) {
                let counter = d.entry(NEW_KEY).or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(staged) {
                let counter = d.entry(STAGED_KEY).or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(STATUS_CONFLICTED) {
                let counter = d.entry(CONFLICTS_KEY).or_insert(0);
                *counter += 1;
            };
        }
        Some(d)
    }
}
<|endoftext|>


<commit_before>extern crate termion;
extern crate rustc_serialize;

use rustc_serialize::base64::{self, ToBase64};
use rustc_serialize::hex::FromHex;

use std::fs::File;
use std::fs;
use std::io::{Error, ErrorKind};
use std::io::Read;

use termion::style;

pub fn imgcat(path: &str, width: usize) -> String {
    let mut f = match File::open(path) {
        Err(why) => panic!("couldn't open: {}", why),
        Ok(file) => file,
    };
    let mut buffer = Vec::new();
    f.read_to_end(&mut buffer);

    let e = buffer.as_slice().to_base64(base64::STANDARD);
    return String::from(format!("\x1b]1337;File=inline=1;width={width};:{code}\x07", width = width,  code = e));
}

pub fn reset_screen() {
    print!("{}{}{}", termion::clear::All, style::Reset, termion::cursor::Show);
}

pub fn clear_screen () {
    print!("{}", termion::clear::All);
}
<commit_msg>screen common - imgCatUrl utility<commit_after>extern crate termion;
extern crate rustc_serialize;
extern crate hyper;

use rustc_serialize::base64::{self, ToBase64};
use rustc_serialize::hex::FromHex;

use std::fs::File;
use std::fs;
use std::io::{Error, ErrorKind};
use std::io::Read;

use termion::style;

use self::hyper::Client;
use self::hyper::header::Connection;

pub fn imgcat(path: &str, width: usize) -> String {
    let mut f = match File::open(path) {
        Err(why) => panic!("couldn't open: {}", why),
        Ok(file) => file,
    };
    let mut buffer = Vec::new();
    f.read_to_end(&mut buffer);

    let e = buffer.as_slice().to_base64(base64::STANDARD);
    return String::from(format!("\x1b]1337;File=inline=1;width={width};:{code}\x07", width = width,  code = e));
}

pub fn imgcatUrl(url: &str, height: usize) -> String {
    let mut c = Client::new();
    return match c.get(url).send() {
        Ok(mut resp) => {
                let mut buffer = Vec::new();
                resp.read_to_end(&mut buffer);
                let e = buffer.as_slice().to_base64(base64::STANDARD);
                return String::from(format!("\x1b]1337;File=inline=1;height={height};:{code}\x07", height = height,  code = e));
            }
        Err(e) => String::from("[IMG FAIL]")
    }
}

pub fn reset_screen() {
    print!("{}{}{}", termion::clear::All, style::Reset, termion::cursor::Show);
}

pub fn clear_screen () {
    print!("{}", termion::clear::All);
}
<|endoftext|>