<commit_before>/*
Module: sort

Sorting methods
*/
import vec::{len, slice};

export merge_sort;
export quick_sort;
export quick_sort3;

/* Type: lteq */
type lteq<T> = fn(T, T) -> bool;

/*
Function: merge_sort

Merge sort. Returns a new vector containing the sorted list.

Has worst case O(n log n) performance, best case O(n), but
is not space efficient. This is a stable sort.
*/
fn merge_sort<T: copy>(le: lteq<T>, v: [const T]) -> [T] {
    fn merge<T: copy>(le: lteq<T>, a: [T], b: [T]) -> [T] {
        let rs: [T] = [];
        let a_len: uint = len::<T>(a);
        let a_ix: uint = 0u;
        let b_len: uint = len::<T>(b);
        let b_ix: uint = 0u;
        while a_ix < a_len && b_ix < b_len {
            if le(a[a_ix], b[b_ix]) {
                rs += [a[a_ix]];
                a_ix += 1u;
            } else { rs += [b[b_ix]]; b_ix += 1u; }
        }
        rs += slice::<T>(a, a_ix, a_len);
        rs += slice::<T>(b, b_ix, b_len);
        ret rs;
    }
    let v_len: uint = len::<T>(v);
    if v_len == 0u { ret []; }
    if v_len == 1u { ret [v[0]]; }
    let mid: uint = v_len / 2u;
    let a: [T] = slice::<T>(v, 0u, mid);
    let b: [T] = slice::<T>(v, mid, v_len);
    ret merge::<T>(le, merge_sort::<T>(le, a), merge_sort::<T>(le, b));
}

fn part<T: copy>(compare_func: lteq<T>, arr: [mutable T], left: uint,
                right: uint, pivot: uint) -> uint {
    let pivot_value = arr[pivot];
    arr[pivot] <-> arr[right];
    let storage_index: uint = left;
    let i: uint = left;
    while i < right {
        if compare_func(copy arr[i], pivot_value) {
            arr[i] <-> arr[storage_index];
            storage_index += 1u;
        }
        i += 1u;
    }
    arr[storage_index] <-> arr[right];
    ret storage_index;
}

fn qsort<T: copy>(compare_func: lteq<T>, arr: [mutable T], left: uint,
             right: uint) {
    if right > left {
        let pivot = (left + right) / 2u;
        let new_pivot = part::<T>(compare_func, arr, left, right, pivot);
        if new_pivot != 0u {
            // Need to do this check before recursing due to overflow
            qsort::<T>(compare_func, arr, left, new_pivot - 1u);
        }
        qsort::<T>(compare_func, arr, new_pivot + 1u, right);
    }
}

/*
Function: quick_sort

Quicksort. Sorts a mutable vector in place.

Has worst case O(n^2) performance, average case O(n log n).
This is an unstable sort.
*/
fn quick_sort<T: copy>(compare_func: lteq<T>, arr: [mutable T]) {
    if len::<T>(arr) == 0u { ret; }
    qsort::<T>(compare_func, arr, 0u, len::<T>(arr) - 1u);
}

fn qsort3<T: copy>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
                  arr: [mutable T], left: int, right: int) {
    if right <= left { ret; }
    let v: T = arr[right];
    let i: int = left - 1;
    let j: int = right;
    let p: int = i;
    let q: int = j;
    while true {
        i += 1;
        while compare_func_lt(copy arr[i], v) { i += 1; }
        j -= 1;
        while compare_func_lt(v, copy arr[j]) {
            if j == left { break; }
            j -= 1;
        }
        if i >= j { break; }
        arr[i] <-> arr[j];
        if compare_func_eq(copy arr[i], v) {
            p += 1;
            arr[p] <-> arr[i];
        }
        if compare_func_eq(v, copy arr[j]) {
            q -= 1;
            arr[j] <-> arr[q];
        }
    }
    arr[i] <-> arr[right];
    j = i - 1;
    i += 1;
    let k: int = left;
    while k < p {
        arr[k] <-> arr[j];
        k += 1;
        j -= 1;
        if k == len::<T>(arr) as int { break; }
    }
    k = right - 1;
    while k > q {
        arr[i] <-> arr[k];
        k -= 1;
        i += 1;
        if k == 0 { break; }
    }
    qsort3::<T>(compare_func_lt, compare_func_eq, arr, left, j);
    qsort3::<T>(compare_func_lt, compare_func_eq, arr, i, right);
}

// FIXME: This should take lt and eq types
/*
Function: quick_sort3

Fancy quicksort. Sorts a mutable vector in place.

Based on algorithm presented by Sedgewick and Bentley
<http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf>.
According to these slides this is the algorithm of choice for
'randomly ordered keys, abstract compare' & 'small number of key values'.

This is an unstable sort.
*/
fn quick_sort3<T: copy>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
                       arr: [mutable T]) {
    if len::<T>(arr) == 0u { ret; }
    qsort3::<T>(compare_func_lt, compare_func_eq, arr, 0,
                (len::<T>(arr) as int) - 1);
}

#[cfg(test)]
mod test_qsort3 {
    fn check_sort(v1: [mutable int], v2: [mutable int]) {
        let len = vec::len::<int>(v1);
        fn lt(&&a: int, &&b: int) -> bool { ret a < b; }
        fn equal(&&a: int, &&b: int) -> bool { ret a == b; }
        let f1 = lt;
        let f2 = equal;
        quick_sort3::<int>(f1, f2, v1);
        let i = 0u;
        while i < len {
            log(debug, v2[i]);
            assert (v2[i] == v1[i]);
            i += 1u;
        }
    }

    #[test]
    fn test() {
        {
            let v1 = [mutable 3, 7, 4, 5, 2, 9, 5, 8];
            let v2 = [mutable 2, 3, 4, 5, 5, 7, 8, 9];
            check_sort(v1, v2);
        }
        {
            let v1 = [mutable 1, 1, 1];
            let v2 = [mutable 1, 1, 1];
            check_sort(v1, v2);
        }
        {
            let v1: [mutable int] = [mutable];
            let v2: [mutable int] = [mutable];
            check_sort(v1, v2);
        }
        { let v1 = [mutable 9]; let v2 = [mutable 9]; check_sort(v1, v2); }
        {
            let v1 = [mutable 9, 3, 3, 3, 9];
            let v2 = [mutable 3, 3, 3, 9, 9];
            check_sort(v1, v2);
        }
    }
}

#[cfg(test)]
mod test_qsort {
    fn check_sort(v1: [mutable int], v2: [mutable int]) {
        let len = vec::len::<int>(v1);
        fn ltequal(&&a: int, &&b: int) -> bool { ret a <= b; }
        let f = ltequal;
        quick_sort::<int>(f, v1);
        let i = 0u;
        while i < len {
            log(debug, v2[i]);
            assert (v2[i] == v1[i]);
            i += 1u;
        }
    }

    #[test]
    fn test() {
        {
            let v1 = [mutable 3, 7, 4, 5, 2, 9, 5, 8];
            let v2 = [mutable 2, 3, 4, 5, 5, 7, 8, 9];
            check_sort(v1, v2);
        }
        {
            let v1 = [mutable 1, 1, 1];
            let v2 = [mutable 1, 1, 1];
            check_sort(v1, v2);
        }
        {
            let v1: [mutable int] = [mutable];
            let v2: [mutable int] = [mutable];
            check_sort(v1, v2);
        }
        { let v1 = [mutable 9]; let v2 = [mutable 9]; check_sort(v1, v2); }
        {
            let v1 = [mutable 9, 3, 3, 3, 9];
            let v2 = [mutable 3, 3, 3, 9, 9];
            check_sort(v1, v2);
        }
    }

    // Regression test for #750
    #[test]
    fn test_simple() {
        let names = [mutable 2, 1, 3];

        let expected = [1, 2, 3];

        fn lteq(&&a: int, &&b: int) -> bool { int::le(a, b) }
        sort::quick_sort(lteq, names);

        let immut_names = vec::from_mut(names);

        // Silly, but what else can we do?
        check (vec::same_length(expected, immut_names));
        let pairs = vec::zip(expected, immut_names);
        for (a, b) in pairs { #debug("%d %d", a, b); assert (a == b); }
    }
}

#[cfg(test)]
mod tests {

    fn check_sort(v1: [int], v2: [int]) {
        let len = vec::len::<int>(v1);
        fn lteq(&&a: int, &&b: int) -> bool { ret a <= b; }
        let f = lteq;
        let v3 = merge_sort::<int>(f, v1);
        let i = 0u;
        while i < len {
            log(debug, v3[i]);
            assert (v3[i] == v2[i]);
            i += 1u;
        }
    }

    #[test]
    fn test() {
        {
            let v1 = [3, 7, 4, 5, 2, 9, 5, 8];
            let v2 = [2, 3, 4, 5, 5, 7, 8, 9];
            check_sort(v1, v2);
        }
        { let v1 = [1, 1, 1]; let v2 = [1, 1, 1]; check_sort(v1, v2); }
        { let v1: [int] = []; let v2: [int] = []; check_sort(v1, v2); }
        { let v1 = [9]; let v2 = [9]; check_sort(v1, v2); }
        {
            let v1 = [9, 3, 3, 3, 9];
            let v2 = [3, 3, 3, 9, 9];
            check_sort(v1, v2);
        }
    }

    #[test]
    fn test_merge_sort_mutable() {
        fn lteq(&&a: int, &&b: int) -> bool { ret a <= b; }
        let v1 = [mutable 3, 2, 1];
        let v2 = merge_sort(lteq, v1);
        assert v2 == [1, 2, 3];
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>std: rename sort::lteq to sort::le.<commit_after>/*
Module: sort

Sorting methods
*/
import vec::{len, slice};

export merge_sort;
export quick_sort;
export quick_sort3;

/* Type: le */
type le<T> = fn(T, T) -> bool;

/*
Function: merge_sort

Merge sort. Returns a new vector containing the sorted list.

Has worst case O(n log n) performance, best case O(n), but
is not space efficient. This is a stable sort.
*/
fn merge_sort<T: copy>(le: le<T>, v: [const T]) -> [T] {
    fn merge<T: copy>(le: le<T>, a: [T], b: [T]) -> [T] {
        let rs: [T] = [];
        let a_len: uint = len::<T>(a);
        let a_ix: uint = 0u;
        let b_len: uint = len::<T>(b);
        let b_ix: uint = 0u;
        while a_ix < a_len && b_ix < b_len {
            if le(a[a_ix], b[b_ix]) {
                rs += [a[a_ix]];
                a_ix += 1u;
            } else { rs += [b[b_ix]]; b_ix += 1u; }
        }
        rs += slice::<T>(a, a_ix, a_len);
        rs += slice::<T>(b, b_ix, b_len);
        ret rs;
    }
    let v_len: uint = len::<T>(v);
    if v_len == 0u { ret []; }
    if v_len == 1u { ret [v[0]]; }
    let mid: uint = v_len / 2u;
    let a: [T] = slice::<T>(v, 0u, mid);
    let b: [T] = slice::<T>(v, mid, v_len);
    ret merge::<T>(le, merge_sort::<T>(le, a), merge_sort::<T>(le, b));
}

fn part<T: copy>(compare_func: le<T>, arr: [mutable T], left: uint,
                right: uint, pivot: uint) -> uint {
    let pivot_value = arr[pivot];
    arr[pivot] <-> arr[right];
    let storage_index: uint = left;
    let i: uint = left;
    while i < right {
        if compare_func(copy arr[i], pivot_value) {
            arr[i] <-> arr[storage_index];
            storage_index += 1u;
        }
        i += 1u;
    }
    arr[storage_index] <-> arr[right];
    ret storage_index;
}

fn qsort<T: copy>(compare_func: le<T>, arr: [mutable T], left: uint,
             right: uint) {
    if right > left {
        let pivot = (left + right) / 2u;
        let new_pivot = part::<T>(compare_func, arr, left, right, pivot);
        if new_pivot != 0u {
            // Need to do this check before recursing due to overflow
            qsort::<T>(compare_func, arr, left, new_pivot - 1u);
        }
        qsort::<T>(compare_func, arr, new_pivot + 1u, right);
    }
}

/*
Function: quick_sort

Quicksort. Sorts a mutable vector in place.

Has worst case O(n^2) performance, average case O(n log n).
This is an unstable sort.
*/
fn quick_sort<T: copy>(compare_func: le<T>, arr: [mutable T]) {
    if len::<T>(arr) == 0u { ret; }
    qsort::<T>(compare_func, arr, 0u, len::<T>(arr) - 1u);
}

fn qsort3<T: copy>(compare_func_lt: le<T>, compare_func_eq: le<T>,
                  arr: [mutable T], left: int, right: int) {
    if right <= left { ret; }
    let v: T = arr[right];
    let i: int = left - 1;
    let j: int = right;
    let p: int = i;
    let q: int = j;
    while true {
        i += 1;
        while compare_func_lt(copy arr[i], v) { i += 1; }
        j -= 1;
        while compare_func_lt(v, copy arr[j]) {
            if j == left { break; }
            j -= 1;
        }
        if i >= j { break; }
        arr[i] <-> arr[j];
        if compare_func_eq(copy arr[i], v) {
            p += 1;
            arr[p] <-> arr[i];
        }
        if compare_func_eq(v, copy arr[j]) {
            q -= 1;
            arr[j] <-> arr[q];
        }
    }
    arr[i] <-> arr[right];
    j = i - 1;
    i += 1;
    let k: int = left;
    while k < p {
        arr[k] <-> arr[j];
        k += 1;
        j -= 1;
        if k == len::<T>(arr) as int { break; }
    }
    k = right - 1;
    while k > q {
        arr[i] <-> arr[k];
        k -= 1;
        i += 1;
        if k == 0 { break; }
    }
    qsort3::<T>(compare_func_lt, compare_func_eq, arr, left, j);
    qsort3::<T>(compare_func_lt, compare_func_eq, arr, i, right);
}

// FIXME: This should take lt and eq types
/*
Function: quick_sort3

Fancy quicksort. Sorts a mutable vector in place.

Based on algorithm presented by Sedgewick and Bentley
<http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf>.
According to these slides this is the algorithm of choice for
'randomly ordered keys, abstract compare' & 'small number of key values'.

This is an unstable sort.
*/
fn quick_sort3<T: copy>(compare_func_lt: le<T>, compare_func_eq: le<T>,
                       arr: [mutable T]) {
    if len::<T>(arr) == 0u { ret; }
    qsort3::<T>(compare_func_lt, compare_func_eq, arr, 0,
                (len::<T>(arr) as int) - 1);
}

#[cfg(test)]
mod test_qsort3 {
    fn check_sort(v1: [mutable int], v2: [mutable int]) {
        let len = vec::len::<int>(v1);
        fn lt(&&a: int, &&b: int) -> bool { ret a < b; }
        fn equal(&&a: int, &&b: int) -> bool { ret a == b; }
        let f1 = lt;
        let f2 = equal;
        quick_sort3::<int>(f1, f2, v1);
        let i = 0u;
        while i < len {
            log(debug, v2[i]);
            assert (v2[i] == v1[i]);
            i += 1u;
        }
    }

    #[test]
    fn test() {
        {
            let v1 = [mutable 3, 7, 4, 5, 2, 9, 5, 8];
            let v2 = [mutable 2, 3, 4, 5, 5, 7, 8, 9];
            check_sort(v1, v2);
        }
        {
            let v1 = [mutable 1, 1, 1];
            let v2 = [mutable 1, 1, 1];
            check_sort(v1, v2);
        }
        {
            let v1: [mutable int] = [mutable];
            let v2: [mutable int] = [mutable];
            check_sort(v1, v2);
        }
        { let v1 = [mutable 9]; let v2 = [mutable 9]; check_sort(v1, v2); }
        {
            let v1 = [mutable 9, 3, 3, 3, 9];
            let v2 = [mutable 3, 3, 3, 9, 9];
            check_sort(v1, v2);
        }
    }
}

#[cfg(test)]
mod test_qsort {
    fn check_sort(v1: [mutable int], v2: [mutable int]) {
        let len = vec::len::<int>(v1);
        fn leual(&&a: int, &&b: int) -> bool { ret a <= b; }
        let f = leual;
        quick_sort::<int>(f, v1);
        let i = 0u;
        while i < len {
            log(debug, v2[i]);
            assert (v2[i] == v1[i]);
            i += 1u;
        }
    }

    #[test]
    fn test() {
        {
            let v1 = [mutable 3, 7, 4, 5, 2, 9, 5, 8];
            let v2 = [mutable 2, 3, 4, 5, 5, 7, 8, 9];
            check_sort(v1, v2);
        }
        {
            let v1 = [mutable 1, 1, 1];
            let v2 = [mutable 1, 1, 1];
            check_sort(v1, v2);
        }
        {
            let v1: [mutable int] = [mutable];
            let v2: [mutable int] = [mutable];
            check_sort(v1, v2);
        }
        { let v1 = [mutable 9]; let v2 = [mutable 9]; check_sort(v1, v2); }
        {
            let v1 = [mutable 9, 3, 3, 3, 9];
            let v2 = [mutable 3, 3, 3, 9, 9];
            check_sort(v1, v2);
        }
    }

    // Regression test for #750
    #[test]
    fn test_simple() {
        let names = [mutable 2, 1, 3];

        let expected = [1, 2, 3];

        fn le(&&a: int, &&b: int) -> bool { int::le(a, b) }
        sort::quick_sort(le, names);

        let immut_names = vec::from_mut(names);

        // Silly, but what else can we do?
        check (vec::same_length(expected, immut_names));
        let pairs = vec::zip(expected, immut_names);
        for (a, b) in pairs { #debug("%d %d", a, b); assert (a == b); }
    }
}

#[cfg(test)]
mod tests {

    fn check_sort(v1: [int], v2: [int]) {
        let len = vec::len::<int>(v1);
        fn le(&&a: int, &&b: int) -> bool { ret a <= b; }
        let f = le;
        let v3 = merge_sort::<int>(f, v1);
        let i = 0u;
        while i < len {
            log(debug, v3[i]);
            assert (v3[i] == v2[i]);
            i += 1u;
        }
    }

    #[test]
    fn test() {
        {
            let v1 = [3, 7, 4, 5, 2, 9, 5, 8];
            let v2 = [2, 3, 4, 5, 5, 7, 8, 9];
            check_sort(v1, v2);
        }
        { let v1 = [1, 1, 1]; let v2 = [1, 1, 1]; check_sort(v1, v2); }
        { let v1: [int] = []; let v2: [int] = []; check_sort(v1, v2); }
        { let v1 = [9]; let v2 = [9]; check_sort(v1, v2); }
        {
            let v1 = [9, 3, 3, 3, 9];
            let v2 = [3, 3, 3, 9, 9];
            check_sort(v1, v2);
        }
    }

    #[test]
    fn test_merge_sort_mutable() {
        fn le(&&a: int, &&b: int) -> bool { ret a <= b; }
        let v1 = [mutable 3, 2, 1];
        let v2 = merge_sort(le, v1);
        assert v2 == [1, 2, 3];
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate languageserver_types;
#[macro_use]
extern crate log;
extern crate simple_logging;
extern crate url;
extern crate plank_syntax;
extern crate plank_errors;

mod transport;
mod jsonrpc;

use std::cell::RefCell;
use std::io;
use std::io::{BufRead, Write};
use std::ops::DerefMut;
use languageserver_types as lst;
use url::Url;
use jsonrpc::{RpcHandler, Response};
use transport::Transport;

fn main() {
    simple_logging::log_to_stderr(log::LogLevelFilter::Trace)
        .expect("failed to initialize logging");

    let stdin = io::stdin();
    let stdin = stdin.lock();
    let stdout = io::stdout();
    let stdout = stdout.lock();

    let transport = RefCell::new(Transport::new(stdin, stdout));
    let mut rpc = RpcHandler::new();

    rpc.add_method("initialize", |_: lst::InitializeParams| {
        Response::Success::<_, ()>(lst::InitializeResult {
            capabilities: lst::ServerCapabilities {
                text_document_sync: Some(lst::TextDocumentSyncKind::Full),
                .. Default::default()
            },
        })
    });

    rpc.add_notification("initialized", |_: serde_json::Value| {
    });

    rpc.add_notification("textDocument/didOpen", |params: lst::DidOpenTextDocumentParams| {
        publish_diagnostics(
            &params.text_document.text,
            params.text_document.uri,
            transport.borrow_mut().deref_mut(),
        );
    });

    rpc.add_notification("textDocument/didSave", |_: lst::DidSaveTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didClose", |_: lst::DidCloseTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didChange", |params: lst::DidChangeTextDocumentParams| {
        if params.content_changes.len() != 1 ||
            params.content_changes[0].range.is_some() ||
            params.content_changes[0].range_length.is_some()
        {
            debug!("got bad edit with `didChange` event");
        } else {
            publish_diagnostics(
                &params.content_changes[0].text,
                params.text_document.uri,
                transport.borrow_mut().deref_mut(),
            );
        }
    });

    loop {
        let response = {
            let msg = transport
                .borrow_mut()
                .read_message()
                .expect("failed to read message");
            rpc.handle_call(&msg)
        };
        if let Some(response) = response {
            transport
                .borrow_mut()
                .send_message(&response)
                .expect("failed to send");
        }
    }
}

fn publish_diagnostics<R, W>(source: &str, doc: Url, transport: &mut Transport<R, W>)
    where R: BufRead, W: Write
{
    let diagnostics = make_diagnostics(source);
    let params = lst::PublishDiagnosticsParams {
        uri: doc,
        diagnostics,
    };
    #[derive(Serialize)]
    struct Notification {
        jsonrpc: &'static str,
        method: &'static str,
        params: lst::PublishDiagnosticsParams,
    }

    let notification = Notification {
        jsonrpc: "2.0",
        method: "textDocument/publishDiagnostics",
        params,
    };
    let string = serde_json::to_string(&notification)
        .expect("failed to serialize diagnostics");
    transport.send_message(&string).expect("failed to write message");
}

fn make_diagnostics(source: &str) -> Vec<lst::Diagnostic> {
    let reporter = plank_errors::Reporter::new();
    let tokens = plank_syntax::lex(source, reporter.clone());
    let _ = plank_syntax::parse(tokens, reporter.clone());
    reporter
        .get_diagnostics()
        .into_iter()
        .filter_map(convert_diagnostic)
        .collect()
}

fn convert_diagnostic(d: plank_errors::reporter::Diagnostic) -> Option<lst::Diagnostic> {
    fn convert_pos(pos: plank_errors::position::Position) -> lst::Position {
        lst::Position {
            line: u64::from(pos.line),
            character: u64::from(pos.column),
        }
    }
    fn convert_range(range: plank_errors::position::Span) -> lst::Range {
        lst::Range {
            start: convert_pos(range.start),
            end: convert_pos(range.end),
        }
    }
    let primary_span = match d.primary_span {
        Some(span) => span,
        None => return None,
    };
    let severity = match d.severity {
        plank_errors::reporter::Severity::Error => lst::DiagnosticSeverity::Error,
        plank_errors::reporter::Severity::Warning => lst::DiagnosticSeverity::Warning,
    };
    Some(lst::Diagnostic {
        range: convert_range(primary_span),
        severity: Some(severity),
        code: None,
        source: Some("plank".into()),
        message: d.message,
    })
}
<commit_msg>log less in language server<commit_after>#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate languageserver_types;
#[macro_use]
extern crate log;
extern crate simple_logging;
extern crate url;
extern crate plank_syntax;
extern crate plank_errors;

mod transport;
mod jsonrpc;

use std::cell::RefCell;
use std::io;
use std::io::{BufRead, Write};
use std::ops::DerefMut;
use languageserver_types as lst;
use url::Url;
use jsonrpc::{RpcHandler, Response};
use transport::Transport;

fn main() {
    simple_logging::log_to_stderr(log::LogLevelFilter::Info)
        .expect("failed to initialize logging");

    let stdin = io::stdin();
    let stdin = stdin.lock();
    let stdout = io::stdout();
    let stdout = stdout.lock();

    let transport = RefCell::new(Transport::new(stdin, stdout));
    let mut rpc = RpcHandler::new();

    rpc.add_method("initialize", |_: lst::InitializeParams| {
        Response::Success::<_, ()>(lst::InitializeResult {
            capabilities: lst::ServerCapabilities {
                text_document_sync: Some(lst::TextDocumentSyncKind::Full),
                .. Default::default()
            },
        })
    });

    rpc.add_notification("initialized", |_: serde_json::Value| {
    });

    rpc.add_notification("textDocument/didOpen", |params: lst::DidOpenTextDocumentParams| {
        publish_diagnostics(
            &params.text_document.text,
            params.text_document.uri,
            transport.borrow_mut().deref_mut(),
        );
    });

    rpc.add_notification("textDocument/didSave", |_: lst::DidSaveTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didClose", |_: lst::DidCloseTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didChange", |params: lst::DidChangeTextDocumentParams| {
        if params.content_changes.len() != 1 ||
            params.content_changes[0].range.is_some() ||
            params.content_changes[0].range_length.is_some()
        {
            debug!("got bad edit with `didChange` event");
        } else {
            publish_diagnostics(
                &params.content_changes[0].text,
                params.text_document.uri,
                transport.borrow_mut().deref_mut(),
            );
        }
    });

    loop {
        let response = {
            let msg = transport
                .borrow_mut()
                .read_message()
                .expect("failed to read message");
            rpc.handle_call(&msg)
        };
        if let Some(response) = response {
            transport
                .borrow_mut()
                .send_message(&response)
                .expect("failed to send");
        }
    }
}

fn publish_diagnostics<R, W>(source: &str, doc: Url, transport: &mut Transport<R, W>)
    where R: BufRead, W: Write
{
    let diagnostics = make_diagnostics(source);
    let params = lst::PublishDiagnosticsParams {
        uri: doc,
        diagnostics,
    };
    #[derive(Serialize)]
    struct Notification {
        jsonrpc: &'static str,
        method: &'static str,
        params: lst::PublishDiagnosticsParams,
    }

    let notification = Notification {
        jsonrpc: "2.0",
        method: "textDocument/publishDiagnostics",
        params,
    };
    let string = serde_json::to_string(&notification)
        .expect("failed to serialize diagnostics");
    transport.send_message(&string).expect("failed to write message");
}

fn make_diagnostics(source: &str) -> Vec<lst::Diagnostic> {
    let reporter = plank_errors::Reporter::new();
    let tokens = plank_syntax::lex(source, reporter.clone());
    let _ = plank_syntax::parse(tokens, reporter.clone());
    reporter
        .get_diagnostics()
        .into_iter()
        .filter_map(convert_diagnostic)
        .collect()
}

fn convert_diagnostic(d: plank_errors::reporter::Diagnostic) -> Option<lst::Diagnostic> {
    fn convert_pos(pos: plank_errors::position::Position) -> lst::Position {
        lst::Position {
            line: u64::from(pos.line),
            character: u64::from(pos.column),
        }
    }
    fn convert_range(range: plank_errors::position::Span) -> lst::Range {
        lst::Range {
            start: convert_pos(range.start),
            end: convert_pos(range.end),
        }
    }
    let primary_span = match d.primary_span {
        Some(span) => span,
        None => return None,
    };
    let severity = match d.severity {
        plank_errors::reporter::Severity::Error => lst::DiagnosticSeverity::Error,
        plank_errors::reporter::Severity::Warning => lst::DiagnosticSeverity::Warning,
    };
    Some(lst::Diagnostic {
        range: convert_range(primary_span),
        severity: Some(severity),
        code: None,
        source: Some("plank".into()),
        message: d.message,
    })
}
<|endoftext|>


<commit_before>use gemlab::geometry::is_point_inside_triangle;
use gemlab::util::GridSearchCell;
use gemlab::StrError;
use plotpy::{Canvas, Plot, PolyCode, Text};
use std::fs::File;
use std::io::{BufRead, BufReader};

fn brute_force_search(triangles: &Vec<Vec<Vec<f64>>>, x: &[f64]) -> Option<usize> {
    for i in 0..triangles.len() {
        let t = &triangles[i];
        if is_point_inside_triangle(&t[0], &t[1], &t[2], x) {
            return Some(i);
        }
    }
    None
}

fn main() -> Result<(), StrError> {
    // select mesh for testing
    let num_triangle = 20000;
    let path = format!("data/triangles/example_grid_search_gen_triangles_{}.dat", num_triangle);
    let tris = read_data(path.as_str())?;

    // closure that returns the number of nodes of a cell `t`
    let get_nnode = |_t| Ok(3);

    // closure that returns the coordinates of point `m` of cell `t`
    let get_x = |t: usize, m: usize| Ok(&tris[t][m][..]);

    // allocate grid search tool
    let ndim = 2;
    let grid = GridSearchCell::new(ndim, tris.len(), get_nnode, get_x, None, None)?;

    // print information
    // println!("{}", grid);
    grid.print_stat();

    // closure that tells whether the point is in the cell or not
    let is_in_cell = |t: usize, x: &[f64]| Ok(is_point_inside_triangle(&tris[t][0], &tris[t][1], &tris[t][2], x));

    // find triangle given coords
    let x = &[1.0, 0.5];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&tris, x));

    // find with another triangle
    let x = &[2.9, 1.6];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&tris, x));

    // maybe find with another triangle
    let x = &[3.0, 1.0];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&tris, x));

    // draw triangles and grid
    let mut plot = Plot::new();
    grid.draw(&mut plot, false)?;
    draw_triangles(&mut plot, &tris, false);
    let path = format!("/tmp/gemlab/example_grid_search_triangles_{}.svg", tris.len());
    plot.set_equal_axes(true)
        .set_figure_size_points(800.0, 800.0)
        .grid_and_labels("x", "y")
        .save(path.as_str())?;
    Ok(())
}

fn draw_triangles(plot: &mut Plot, triangles: &Vec<Vec<Vec<f64>>>, with_ids: bool) {
    let mut ids = Text::new();
    ids.set_color("#cd0000")
        .set_bbox(true)
        .set_bbox_style("circle,pad=0.3")
        .set_bbox_edgecolor("None")
        .set_bbox_facecolor("white")
        .set_bbox_alpha(0.8);
    let mut canvas = Canvas::new();
    let (mut xc, mut yc) = (0.0, 0.0);
    canvas.set_face_color("#fefddc").set_edge_color("#fcb827");
    for t in 0..triangles.len() {
        canvas.polycurve_begin();
        for m in 0..3 {
            let code = if m == 0 {
                xc = triangles[t][m][0];
                yc = triangles[t][m][1];
                PolyCode::MoveTo
            } else {
                xc += triangles[t][m][0];
                yc += triangles[t][m][1];
                PolyCode::LineTo
            };
            canvas.polycurve_add(&triangles[t][m][0], &triangles[t][m][1], code);
        }
        canvas.polycurve_end(true);
        xc /= 3.0;
        yc /= 3.0;
        if with_ids {
            ids.draw(xc, yc, format!("{}", t).as_str());
        }
    }
    plot.add(&canvas);
    if with_ids {
        plot.add(&ids);
    }
}

// Returns [num_triangle][nnode=3][ndim=2]
fn read_data(path: &str) -> Result<Vec<Vec<Vec<f64>>>, StrError> {
    let mut data = Vec::new();
    let input = File::open(path).map_err(|_| "cannot open file")?;
    let buffered = BufReader::new(input);
    let mut lines_iter = buffered.lines();
    let num_triangle: usize = match lines_iter.next() {
        Some(v) => {
            let line = v.unwrap();
            line.parse().map_err(|_| "cannot parse num_triangle")?
        }
        None => return Err("cannot read num_triangle"),
    };
    for _ in 0..num_triangle {
        let mut vertices = Vec::new();
        match lines_iter.next() {
            Some(v) => {
                let line = v.unwrap();
                let mut array = line.split_whitespace();
                for _ in 0..3 {
                    let mut x = vec![0.0; 2];
                    for i in 0..2 {
                        x[i] = match array.next() {
                            Some(w) => w.parse().map_err(|_| "cannot parse vertex coordinate")?,
                            None => return Err("cannot read vertex coordinate"),
                        };
                    }
                    vertices.push(x);
                }
            }
            None => return Err("cannot read num_triangle"),
        }
        data.push(vertices);
    }
    Ok(data)
}
<commit_msg>Use smaller mesh in example<commit_after>use gemlab::geometry::is_point_inside_triangle;
use gemlab::util::GridSearchCell;
use gemlab::StrError;
use plotpy::{Canvas, Plot, PolyCode, Text};
use std::fs::File;
use std::io::{BufRead, BufReader};

fn brute_force_search(triangles: &Vec<Vec<Vec<f64>>>, x: &[f64]) -> Option<usize> {
    for i in 0..triangles.len() {
        let t = &triangles[i];
        if is_point_inside_triangle(&t[0], &t[1], &t[2], x) {
            return Some(i);
        }
    }
    None
}

fn main() -> Result<(), StrError> {
    // select mesh for testing
    let num_triangle = 200;
    let path = format!("data/triangles/example_grid_search_gen_triangles_{}.dat", num_triangle);
    let tris = read_data(path.as_str())?;

    // closure that returns the number of nodes of a cell `t`
    let get_nnode = |_t| Ok(3);

    // closure that returns the coordinates of point `m` of cell `t`
    let get_x = |t: usize, m: usize| Ok(&tris[t][m][..]);

    // allocate grid search tool
    let ndim = 2;
    let grid = GridSearchCell::new(ndim, tris.len(), get_nnode, get_x, None, None)?;

    // print information
    // println!("{}", grid);
    grid.print_stat();

    // closure that tells whether the point is in the cell or not
    let is_in_cell = |t: usize, x: &[f64]| Ok(is_point_inside_triangle(&tris[t][0], &tris[t][1], &tris[t][2], x));

    // find triangle given coords
    let x = &[1.0, 0.5];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&tris, x));

    // find with another triangle
    let x = &[2.9, 1.6];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&tris, x));

    // maybe find with another triangle
    let x = &[3.0, 1.0];
    let id = grid.find_cell(x, is_in_cell)?;
    println!("\nwith x = {:?}", x);
    println!("found triangle with id = {:?} | {:?}", id, brute_force_search(&tris, x));

    // draw triangles and grid
    let mut plot = Plot::new();
    grid.draw(&mut plot, false)?;
    draw_triangles(&mut plot, &tris, false);
    let path = format!("/tmp/gemlab/example_grid_search_triangles_{}.svg", tris.len());
    plot.set_equal_axes(true)
        .set_figure_size_points(800.0, 800.0)
        .grid_and_labels("x", "y")
        .save(path.as_str())?;
    Ok(())
}

fn draw_triangles(plot: &mut Plot, triangles: &Vec<Vec<Vec<f64>>>, with_ids: bool) {
    let mut ids = Text::new();
    ids.set_color("#cd0000")
        .set_bbox(true)
        .set_bbox_style("circle,pad=0.3")
        .set_bbox_edgecolor("None")
        .set_bbox_facecolor("white")
        .set_bbox_alpha(0.8);
    let mut canvas = Canvas::new();
    let (mut xc, mut yc) = (0.0, 0.0);
    canvas.set_face_color("#fefddc").set_edge_color("#fcb827");
    for t in 0..triangles.len() {
        canvas.polycurve_begin();
        for m in 0..3 {
            let code = if m == 0 {
                xc = triangles[t][m][0];
                yc = triangles[t][m][1];
                PolyCode::MoveTo
            } else {
                xc += triangles[t][m][0];
                yc += triangles[t][m][1];
                PolyCode::LineTo
            };
            canvas.polycurve_add(&triangles[t][m][0], &triangles[t][m][1], code);
        }
        canvas.polycurve_end(true);
        xc /= 3.0;
        yc /= 3.0;
        if with_ids {
            ids.draw(xc, yc, format!("{}", t).as_str());
        }
    }
    plot.add(&canvas);
    if with_ids {
        plot.add(&ids);
    }
}

// Returns [num_triangle][nnode=3][ndim=2]
fn read_data(path: &str) -> Result<Vec<Vec<Vec<f64>>>, StrError> {
    let mut data = Vec::new();
    let input = File::open(path).map_err(|_| "cannot open file")?;
    let buffered = BufReader::new(input);
    let mut lines_iter = buffered.lines();
    let num_triangle: usize = match lines_iter.next() {
        Some(v) => {
            let line = v.unwrap();
            line.parse().map_err(|_| "cannot parse num_triangle")?
        }
        None => return Err("cannot read num_triangle"),
    };
    for _ in 0..num_triangle {
        let mut vertices = Vec::new();
        match lines_iter.next() {
            Some(v) => {
                let line = v.unwrap();
                let mut array = line.split_whitespace();
                for _ in 0..3 {
                    let mut x = vec![0.0; 2];
                    for i in 0..2 {
                        x[i] = match array.next() {
                            Some(w) => w.parse().map_err(|_| "cannot parse vertex coordinate")?,
                            None => return Err("cannot read vertex coordinate"),
                        };
                    }
                    vertices.push(x);
                }
            }
            None => return Err("cannot read num_triangle"),
        }
        data.push(vertices);
    }
    Ok(data)
}
<|endoftext|>


<commit_before>//! SCCS-style delta weave stores.

use Result;
use SureTree;
use std::cell::RefCell;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::rc::Rc;

use super::{Store, StoreTags, Version};
use weave::{DeltaWriter, SimpleNaming, NamingConvention, NewWeave, Parser, Sink};

pub struct WeaveStore {
    naming: SimpleNaming,
}

impl WeaveStore {
    pub fn new<P: AsRef<Path>>(path: P, base: &str, compressed: bool) -> WeaveStore {
        WeaveStore {
            naming: SimpleNaming::new(path, base, "weave", compressed),
        }
    }
}

impl Store for WeaveStore {
    fn write_new(&self, tree: &SureTree, tags: &StoreTags) -> Result<()> {
        let itags = tags.iter().map(|(k,v)| (k.as_ref(), v.as_ref()));
        match get_last_delta(&self.naming) {
            Ok(base) => {
                let mut wv = DeltaWriter::new(&self.naming, itags, base)?;
                tree.save_to(&mut wv)?;
                wv.close()?;
                Ok(())
            }
            Err(_) => {
                // Create a new weave file.
                let mut wv = NewWeave::new(&self.naming, itags)?;

                tree.save_to(&mut wv)?;

                wv.close()?;
                Ok(())
            }
        }
    }

    fn load(&self, version: Version) -> Result<SureTree> {
        panic!("TODO")
    }
}

/// Get the delta number of the most recent delta.
fn get_last_delta(naming: &NamingConvention) -> Result<usize> {
    let fd = File::open(naming.main_file())?;
    let lines = BufReader::new(fd).lines();
    let parser = Parser::new(lines, Rc::new(RefCell::new(NullSink)), 1)?;
    let base = parser.get_header().deltas.iter()
        .map(|x| x.number)
        .max().expect("At least one delta in weave file");
    Ok(base)
}

// The null sink does nothing.
struct NullSink;

impl Sink for NullSink {}
<commit_msg>Implement load from weave store<commit_after>//! SCCS-style delta weave stores.

use Result;
use SureTree;
use std::cell::RefCell;
use std::fs::File;
use std::io::{self, BufRead, BufReader, Read};
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::mpsc::{self, Receiver, Sender};
use std::thread;

use super::{Store, StoreTags, Version};
use weave::{self, DeltaWriter, SimpleNaming, NamingConvention, NewWeave, Parser, Sink};

pub struct WeaveStore {
    naming: SimpleNaming,
}

impl WeaveStore {
    pub fn new<P: AsRef<Path>>(path: P, base: &str, compressed: bool) -> WeaveStore {
        WeaveStore {
            naming: SimpleNaming::new(path, base, "weave", compressed),
        }
    }
}

impl Store for WeaveStore {
    fn write_new(&self, tree: &SureTree, tags: &StoreTags) -> Result<()> {
        let itags = tags.iter().map(|(k,v)| (k.as_ref(), v.as_ref()));
        match get_last_delta(&self.naming) {
            Ok(base) => {
                let mut wv = DeltaWriter::new(&self.naming, itags, base)?;
                tree.save_to(&mut wv)?;
                wv.close()?;
                Ok(())
            }
            Err(_) => {
                // Create a new weave file.
                let mut wv = NewWeave::new(&self.naming, itags)?;

                tree.save_to(&mut wv)?;

                wv.close()?;
                Ok(())
            }
        }
    }

    fn load(&self, version: Version) -> Result<SureTree> {
        let last = get_last_delta(&self.naming)?;
        let last = match version {
            Version::Latest => last,
            Version::Prior => last - 1,
        };

        let path = self.naming.main_file().to_path_buf();
        let (sender, receiver) = mpsc::channel();
        let child = thread::spawn(move || {
            if let Err(err) = read_parse(path, last, sender.clone()) {
                // Attempt to send the last error over.
                if let Err(inner) = sender.send(Some(Err(err))) {
                    warn!("Error sending error on channel {:?}",
                        inner);
                }
            }
        });
        let rd = ReadReceiver(receiver);
        let tree = SureTree::load_from(rd);
        match child.join() {
            Ok(()) => (),
            Err(e) => warn!("Problem joining child thread: {:?}", e),
        }
        tree
    }
}

/// Get the delta number of the most recent delta.
fn get_last_delta(naming: &NamingConvention) -> Result<usize> {
    let fd = File::open(naming.main_file())?;
    let lines = BufReader::new(fd).lines();
    let parser = Parser::new(lines, Rc::new(RefCell::new(NullSink)), 1)?;
    let base = parser.get_header().deltas.iter()
        .map(|x| x.number)
        .max().expect("At least one delta in weave file");
    Ok(base)
}

// The null sink does nothing.
struct NullSink;

impl Sink for NullSink {}

// Parse a given delta, emitting the lines to the given channel.  Finishes with Ok(()), or an error
// if something goes wrong.
fn read_parse(path: PathBuf, delta: usize, chan: Sender<Option<Result<String>>>) -> Result<()> {
    let fd = File::open(&path)?;
    let lines = BufReader::new(fd).lines();
    let sync = Rc::new(RefCell::new(ReadSync {
        chan: chan,
    }));
    let mut parser = Parser::new(lines, sync.clone(), delta)?;
    parser.parse_to(0)?;
    match sync.borrow().chan.send(None) {
        Ok(()) => (),
        Err(e) => return Err(format!("chan send error: {:?}", e).into()),
    }
    Ok(())
}

struct ReadSync {
    chan: Sender<Option<Result<String>>>,
}

impl Sink for ReadSync {
    fn plain(&mut self, text: &str, keep: bool) -> weave::Result<()> {
        if keep {
            match self.chan.send(Some(Ok(text.to_string()))) {
                Ok(()) => Ok(()),
                Err(e) => Err(format!("chan send error: {:?}", e).into()),
            }
        } else {
            Ok(())
        }
    }
}

struct ReadReceiver(Receiver<Option<Result<String>>>);

impl Read for ReadReceiver {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let line = match self.0.recv() {
            Ok(line) => line,
            Err(e) => return Err(io::Error::new(io::ErrorKind::Other, format!("channel error: {:?}", e))),
        };
        let line = match line {
            None => return Ok(0),
            Some(Ok(line)) => line,
            Some(Err(e)) =>
                return Err(io::Error::new(io::ErrorKind::Other, format!("channel error: {:?}", e))),
        };
        let chars = line.as_bytes();
        if chars.len() + 1 > buf.len() {
            panic!("TODO: Handle line longer than buffer");
        }
        buf[..chars.len()].copy_from_slice(chars);
        buf[chars.len()] = b'\n';
        Ok(chars.len() + 1)
    }
}
<|endoftext|>


<commit_before>/// Strongly borrowed from TypedArena
/// Differs in growth strategy (non-doubling)
/// And only for variable-sized strings

use std::borrow::Borrow;
use std::cell::{Cell,RefCell};
use std::cmp::max;
use std::collections::LinkedList;
use std::collections::hash_map::Entry::{Occupied,Vacant};
use std::collections::hash_map::HashMap;
use std::collections::hash_state::DefaultState;
use std::default::Default;
use std::ops::Deref;
use std::raw::Slice;
use std::rt::heap::{allocate, deallocate};
use std::{fmt,hash,mem,ptr,str};
use xxhash::XXHasher;

struct Chunk {
    start: *mut u8,
    capacity: usize,
}

impl Chunk {
    fn new(capacity: usize) -> Chunk {
        Chunk {
            start: unsafe { allocate(capacity, mem::min_align_of::<u8>()) },
            capacity: capacity,
        }
    }

    // Returns a pointer to the beginning of the allocated space.
    #[inline]
    fn start(&self) -> *const u8 {
        self.start as *const u8
    }

    // Returns a pointer to the end of the allocated space.
    #[inline]
    fn end(&self) -> *const u8 {
        unsafe { self.start().offset(self.capacity as isize) }
    }
}

impl Drop for Chunk {
    fn drop(&mut self) {
        unsafe {
            deallocate(self.start, self.capacity, mem::min_align_of::<u8>());
        }
    }
}

#[derive(Copy)]
pub struct InternedString {
    slice: Slice<u8>,
}

impl InternedString {
    fn from_parts(data: *const u8, len: usize) -> InternedString {
        InternedString {
            slice: Slice {
                data: data,
                len: len,
            },
        }
    }

    pub fn from_str(s: &str) -> InternedString {
        let bytes: &[u8] = s.as_bytes();
        let slice: Slice<u8> = unsafe { mem::transmute(bytes) };
        InternedString {
            slice: slice,
        }
    }

    pub fn as_slice<'s>(&self) -> &'s str {
        unsafe {
            let bytes: &[u8] = mem::transmute(self.slice);
            str::from_utf8_unchecked(bytes)
        }
    }
}

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

impl PartialEq for InternedString {
    fn eq(&self, other: &InternedString) -> bool {
        self.as_slice().eq(other.as_slice())
    }
}

impl PartialEq<str> for InternedString {
    fn eq(&self, other: &str) -> bool {
        self.as_slice().eq(other)
    }
}

impl Eq for InternedString {}

impl hash::Hash for InternedString {
    fn hash<H>(&self, state: &mut H)
        where H: hash::Hasher
    {
        self.as_slice().hash(state)
    }
}

impl Borrow<str> for InternedString {
    fn borrow(&self) -> &str {
        self.as_slice()
    }
}

impl Deref for InternedString {
    type Target = str;

    fn deref(&self) -> &str {
        self.as_slice()
    }
}

pub struct StringPool {
    start: Cell<*mut u8>,
    end: Cell<*const u8>,
    chunks: RefCell<LinkedList<Chunk>>,
    index: RefCell<HashMap<InternedString, InternedString, DefaultState<XXHasher>>>,
}

static CAPACITY: usize = 10240;

impl StringPool {
    pub fn new() -> StringPool {
        StringPool{
            start: Cell::new(ptr::null_mut()),
            end: Cell::new(ptr::null()),
            chunks: RefCell::new(LinkedList::new()),
            index: RefCell::new(Default::default()),
        }
    }

    pub fn intern<'s>(&'s self, s: &str) -> &'s str {
        if s == "" { return ""; }

        let search_string = InternedString::from_str(s);

        let interned_str = match self.index.borrow_mut().entry(search_string) {
            Occupied(entry) => *entry.get(),
            Vacant(entry) => *entry.insert(self.do_intern(s)),
        };

        // The lifetime is really matched to us
        unsafe { mem::transmute(interned_str) }
    }

    fn do_intern(&self, s: &str) -> InternedString {
        self.ensure_capacity(s.len());
        self.store(s)
    }

    fn ensure_capacity(&self, str_len: usize) {
        let remaining = self.end.get() as usize - self.start.get() as usize;
        if remaining < str_len {
            self.allocate_another(max(CAPACITY, str_len))
        }
    }

    fn allocate_another(&self, capacity: usize) {
        let chunk = Chunk::new(capacity);
        self.start.set(chunk.start() as *mut u8);
        self.end.set(chunk.end());
        self.chunks.borrow_mut().push_front(chunk);
    }

    fn store(&self, s: &str) -> InternedString {
        let str_start = s.as_bytes().as_ptr();
        let str_len = s.len();

        unsafe {
            ptr::copy_nonoverlapping(self.start.get(), str_start, str_len);

            // Rebuild the string from our buffer
            let interned_str = InternedString::from_parts(self.start.get() as *const u8, str_len);

            // Increase current pointer
            self.start.set(self.start.get().offset(str_len as isize));

            interned_str
        }
    }
}

#[cfg(test)]
mod test {
    use std::borrow::ToOwned;

    use super::StringPool;

    #[test]
    fn keeps_the_same_string() {
        let s = StringPool::new();

        let interned = s.intern("hello");

        assert_eq!(interned, "hello");
    }

    #[test]
    fn does_not_reuse_the_pointer_of_the_input() {
        let s = StringPool::new();
        let input = "hello";

        let interned = s.intern(input);

        assert!(
            input.as_bytes().as_ptr() !=
            interned.as_bytes().as_ptr()
        );
    }

    #[test]
    fn reuses_the_pointer_for_repeated_input() {
        let s = StringPool::new();

        let interned1 = s.intern("world");
        let interned2 = s.intern("world");

        assert_eq!(
            interned1.as_bytes().as_ptr(),
            interned2.as_bytes().as_ptr()
        );
    }

    #[test]
    #[cfg(feature = "compile_failure")]
    fn string_cannot_outlive_the_pool() {
        let z = {
            let s = StringPool::new();
            s.intern("hello")
        };
    }

    #[test]
    fn ignores_the_lifetime_of_the_input_string() {
        let s = StringPool::new();

        let interned = {
            let allocated_string = "green".to_owned();
            s.intern(&allocated_string)
        };

        // allocated_string is gone now, but we should be able to
        // access the result value until the storage goes away.

        assert_eq!(interned, "green");
    }

    #[test]
    fn can_be_dropped_immediately() {
        StringPool::new();
    }

    fn return_populated_storage() -> (StringPool, *const u8) {
        let s = StringPool::new();
        let ptr = {
            let interned = s.intern("hello");
            interned.as_ptr()
        };
        (s, ptr)
    }

    #[test]
    fn can_return_storage_populated_with_values() {
        let (s, ptr_val) = return_populated_storage();
        let interned = s.intern("hello");
        assert_eq!(interned.as_ptr(), ptr_val);
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;

    use super::StringPool;

    #[bench]
    fn single_string(b: &mut Bencher) {
        let s = StringPool::new();
        b.iter(|| s.intern("hello"));
        b.bytes = "hello".len() as u64;
    }

    #[bench]
    fn many_unique_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0, 1000)
            .map(|i| format!("str{}str", i))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss);
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }

    #[bench]
    fn many_repeated_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0, 1000)
            .map(|i| format!("str{}str", i % 100))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss);
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }
}
<commit_msg>Remove std::raw::Slice and some transmutes<commit_after>/// Strongly borrowed from TypedArena
/// Differs in growth strategy (non-doubling)
/// And only for variable-sized strings

use std::borrow::Borrow;
use std::cell::{Cell,RefCell};
use std::cmp::max;
use std::collections::LinkedList;
use std::collections::hash_map::Entry::{Occupied,Vacant};
use std::collections::hash_map::HashMap;
use std::collections::hash_state::DefaultState;
use std::default::Default;
use std::ops::Deref;
use std::rt::heap::{allocate, deallocate};
use std::slice;
use std::{fmt,hash,mem,ptr,str};

use xxhash::XXHasher;

struct Chunk {
    start: *mut u8,
    capacity: usize,
}

impl Chunk {
    fn new(capacity: usize) -> Chunk {
        Chunk {
            start: unsafe { allocate(capacity, mem::min_align_of::<u8>()) },
            capacity: capacity,
        }
    }

    // Returns a pointer to the beginning of the allocated space.
    #[inline]
    fn start(&self) -> *const u8 {
        self.start as *const u8
    }

    // Returns a pointer to the end of the allocated space.
    #[inline]
    fn end(&self) -> *const u8 {
        unsafe { self.start().offset(self.capacity as isize) }
    }
}

impl Drop for Chunk {
    fn drop(&mut self) {
        unsafe {
            deallocate(self.start, self.capacity, mem::min_align_of::<u8>());
        }
    }
}

#[derive(Copy)]
pub struct InternedString {
    data: *const u8,
    len: usize,
}

impl InternedString {
    fn from_parts(data: *const u8, len: usize) -> InternedString {
        InternedString {
            data: data,
            len: len,
        }
    }

    pub fn from_str(s: &str) -> InternedString {
        let bytes: &[u8] = s.as_bytes();
        InternedString {
            data: bytes.as_ptr(),
            len: bytes.len(),
        }
    }

    pub fn as_slice<'s>(&self) -> &'s str {
        unsafe {
            let bytes = slice::from_raw_parts(self.data, self.len);
            str::from_utf8_unchecked(bytes)
        }
    }
}

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

impl PartialEq for InternedString {
    fn eq(&self, other: &InternedString) -> bool {
        self.as_slice().eq(other.as_slice())
    }
}

impl PartialEq<str> for InternedString {
    fn eq(&self, other: &str) -> bool {
        self.as_slice().eq(other)
    }
}

impl Eq for InternedString {}

impl hash::Hash for InternedString {
    fn hash<H>(&self, state: &mut H)
        where H: hash::Hasher
    {
        self.as_slice().hash(state)
    }
}

impl Borrow<str> for InternedString {
    fn borrow(&self) -> &str {
        self.as_slice()
    }
}

impl Deref for InternedString {
    type Target = str;

    fn deref(&self) -> &str {
        self.as_slice()
    }
}

pub struct StringPool {
    start: Cell<*mut u8>,
    end: Cell<*const u8>,
    chunks: RefCell<LinkedList<Chunk>>,
    index: RefCell<HashMap<InternedString, InternedString, DefaultState<XXHasher>>>,
}

static CAPACITY: usize = 10240;

impl StringPool {
    pub fn new() -> StringPool {
        StringPool{
            start: Cell::new(ptr::null_mut()),
            end: Cell::new(ptr::null()),
            chunks: RefCell::new(LinkedList::new()),
            index: RefCell::new(Default::default()),
        }
    }

    pub fn intern<'s>(&'s self, s: &str) -> &'s str {
        if s == "" { return ""; }

        let search_string = InternedString::from_str(s);

        let interned_str = match self.index.borrow_mut().entry(search_string) {
            Occupied(entry) => *entry.get(),
            Vacant(entry) => *entry.insert(self.do_intern(s)),
        };

        // The lifetime is really matched to us
        unsafe { mem::transmute(interned_str) }
    }

    fn do_intern(&self, s: &str) -> InternedString {
        self.ensure_capacity(s.len());
        self.store(s)
    }

    fn ensure_capacity(&self, str_len: usize) {
        let remaining = self.end.get() as usize - self.start.get() as usize;
        if remaining < str_len {
            self.allocate_another(max(CAPACITY, str_len))
        }
    }

    fn allocate_another(&self, capacity: usize) {
        let chunk = Chunk::new(capacity);
        self.start.set(chunk.start() as *mut u8);
        self.end.set(chunk.end());
        self.chunks.borrow_mut().push_front(chunk);
    }

    fn store(&self, s: &str) -> InternedString {
        let str_start = s.as_bytes().as_ptr();
        let str_len = s.len();

        unsafe {
            ptr::copy_nonoverlapping(self.start.get(), str_start, str_len);

            // Rebuild the string from our buffer
            let interned_str = InternedString::from_parts(self.start.get() as *const u8, str_len);

            // Increase current pointer
            self.start.set(self.start.get().offset(str_len as isize));

            interned_str
        }
    }
}

#[cfg(test)]
mod test {
    use std::borrow::ToOwned;

    use super::StringPool;

    #[test]
    fn keeps_the_same_string() {
        let s = StringPool::new();

        let interned = s.intern("hello");

        assert_eq!(interned, "hello");
    }

    #[test]
    fn does_not_reuse_the_pointer_of_the_input() {
        let s = StringPool::new();
        let input = "hello";

        let interned = s.intern(input);

        assert!(
            input.as_bytes().as_ptr() !=
            interned.as_bytes().as_ptr()
        );
    }

    #[test]
    fn reuses_the_pointer_for_repeated_input() {
        let s = StringPool::new();

        let interned1 = s.intern("world");
        let interned2 = s.intern("world");

        assert_eq!(
            interned1.as_bytes().as_ptr(),
            interned2.as_bytes().as_ptr()
        );
    }

    #[test]
    #[cfg(feature = "compile_failure")]
    fn string_cannot_outlive_the_pool() {
        let z = {
            let s = StringPool::new();
            s.intern("hello")
        };
    }

    #[test]
    fn ignores_the_lifetime_of_the_input_string() {
        let s = StringPool::new();

        let interned = {
            let allocated_string = "green".to_owned();
            s.intern(&allocated_string)
        };

        // allocated_string is gone now, but we should be able to
        // access the result value until the storage goes away.

        assert_eq!(interned, "green");
    }

    #[test]
    fn can_be_dropped_immediately() {
        StringPool::new();
    }

    fn return_populated_storage() -> (StringPool, *const u8) {
        let s = StringPool::new();
        let ptr = {
            let interned = s.intern("hello");
            interned.as_ptr()
        };
        (s, ptr)
    }

    #[test]
    fn can_return_storage_populated_with_values() {
        let (s, ptr_val) = return_populated_storage();
        let interned = s.intern("hello");
        assert_eq!(interned.as_ptr(), ptr_val);
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;

    use super::StringPool;

    #[bench]
    fn single_string(b: &mut Bencher) {
        let s = StringPool::new();
        b.iter(|| s.intern("hello"));
        b.bytes = "hello".len() as u64;
    }

    #[bench]
    fn many_unique_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0, 1000)
            .map(|i| format!("str{}str", i))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss);
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }

    #[bench]
    fn many_repeated_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0, 1000)
            .map(|i| format!("str{}str", i % 100))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss);
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }
}
<|endoftext|>


<commit_before>//! String processing algorithms.
use std::cmp::{max, min};
use std::collections::{hash_map::Entry, HashMap, VecDeque};

/// Prefix trie, easily augmentable by adding more fields and/or methods
pub struct Trie<C: std::hash::Hash + Eq> {
    links: Vec<HashMap<C, usize>>,
}

impl<C: std::hash::Hash + Eq> Default for Trie<C> {
    /// Creates an empty trie with a root node.
    fn default() -> Self {
        Self {
            links: vec![HashMap::new()],
        }
    }
}

impl<C: std::hash::Hash + Eq> Trie<C> {
    /// Inserts a word into the trie, and returns the index of its node.
    pub fn insert(&mut self, word: impl IntoIterator<Item = C>) -> usize {
        let mut node = 0;

        for ch in word {
            let len = self.links.len();
            node = match self.links[node].entry(ch) {
                Entry::Occupied(entry) => *entry.get(),
                Entry::Vacant(entry) => {
                    entry.insert(len);
                    self.links.push(HashMap::new());
                    len
                }
            }
        }
        node
    }

    /// Finds a word in the trie, and returns the index of its node.
    pub fn get(&self, word: impl IntoIterator<Item = C>) -> Option<usize> {
        let mut node = 0;
        for ch in word {
            node = *self.links[node].get(&ch)?;
        }
        Some(node)
    }
}

/// Single-pattern matching with the Knuth-Morris-Pratt algorithm
pub struct Matcher<'a, C: Eq> {
    /// The string pattern to search for.
    pub pattern: &'a [C],
    /// KMP match failure automaton. fail[i] is the length of the longest
    /// proper prefix-suffix of pattern[0..=i].
    pub fail: Vec<usize>,
}

impl<'a, C: Eq> Matcher<'a, C> {
    /// Precomputes the automaton that allows linear-time string matching.
    ///
    /// # Example
    ///
    /// ```
    /// use contest_algorithms::string_proc::Matcher;
    /// let byte_string: &[u8] = b"hello";
    /// let utf8_string: &str = "hello";
    /// let vec_char: Vec<char> = utf8_string.chars().collect();
    ///
    /// let match_from_byte_literal = Matcher::new(byte_string);
    /// let match_from_utf8 = Matcher::new(utf8_string.as_bytes());
    /// let match_from_chars = Matcher::new(&vec_char);
    ///
    /// let vec_int = vec![4, -3, 1];
    /// let match_from_ints = Matcher::new(&vec_int);
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if pattern is empty.
    pub fn new(pattern: &'a [C]) -> Self {
        let mut fail = Vec::with_capacity(pattern.len());
        fail.push(0);
        let mut len = 0;
        for ch in &pattern[1..] {
            while len > 0 && pattern[len] != *ch {
                len = fail[len - 1];
            }
            if pattern[len] == *ch {
                len += 1;
            }
            fail.push(len);
        }
        Self { pattern, fail }
    }

    /// KMP algorithm, sets @return[i] = length of longest prefix of pattern
    /// matching a suffix of text[0..=i].
    pub fn kmp_match(&self, text: impl IntoIterator<Item = C>) -> Vec<usize> {
        let mut len = 0;
        text.into_iter()
            .map(|ch| {
                if len == self.pattern.len() {
                    len = self.fail[len - 1];
                }
                while len > 0 && self.pattern[len] != ch {
                    len = self.fail[len - 1];
                }
                if self.pattern[len] == ch {
                    len += 1;
                }
                len
            })
            .collect()
    }
}

/// Multi-pattern matching with the Aho-Corasick algorithm
pub struct MultiMatcher<C: std::hash::Hash + Eq> {
    /// A prefix trie storing the string patterns to search for.
    pub trie: Trie<C>,
    /// Stores which completed pattern string each node corresponds to.
    pub pat_id: Vec<Option<usize>>,
    /// Aho-Corasick failure automaton. fail[i] is the node corresponding to the
    /// longest prefix-suffix of the node corresponding to i.
    pub fail: Vec<usize>,
    /// Shortcut to the next match along the failure chain, or to the root.
    pub fast: Vec<usize>,
}

impl<C: std::hash::Hash + Eq> MultiMatcher<C> {
    fn next(trie: &Trie<C>, fail: &[usize], mut node: usize, ch: &C) -> usize {
        loop {
            if let Some(&child) = trie.links[node].get(ch) {
                return child;
            } else if node == 0 {
                return 0;
            }
            node = fail[node];
        }
    }

    /// Precomputes the automaton that allows linear-time string matching.
    /// If there are duplicate patterns, all but one copy will be ignored.
    pub fn new(patterns: impl IntoIterator<Item = impl IntoIterator<Item = C>>) -> Self {
        let mut trie = Trie::default();
        let pat_nodes: Vec<usize> = patterns.into_iter().map(|pat| trie.insert(pat)).collect();

        let mut pat_id = vec![None; trie.links.len()];
        for (i, node) in pat_nodes.into_iter().enumerate() {
            pat_id[node] = Some(i);
        }

        let mut fail = vec![0; trie.links.len()];
        let mut fast = vec![0; trie.links.len()];
        let mut q: VecDeque<usize> = trie.links[0].values().cloned().collect();

        while let Some(node) = q.pop_front() {
            for (ch, &child) in &trie.links[node] {
                let nx = Self::next(&trie, &fail, fail[node], &ch);
                fail[child] = nx;
                fast[child] = if pat_id[nx].is_some() { nx } else { fast[nx] };
                q.push_back(child);
            }
        }

        Self {
            trie,
            pat_id,
            fail,
            fast,
        }
    }

    /// Aho-Corasick algorithm, sets @return[i] = node corresponding to
    /// longest prefix of some pattern matching a suffix of text[0..=i].
    pub fn ac_match(&self, text: impl IntoIterator<Item = C>) -> Vec<usize> {
        let mut node = 0;
        text.into_iter()
            .map(|ch| {
                node = Self::next(&self.trie, &self.fail, node, &ch);
                node
            })
            .collect()
    }

    /// For each non-empty match, returns where in the text it ends, and the index
    /// of the corresponding pattern.
    pub fn get_end_pos_and_pat_id(&self, match_nodes: &[usize]) -> Vec<(usize, usize)> {
        let mut res = vec![];
        for (text_pos, &(mut node)) in match_nodes.iter().enumerate() {
            while node != 0 {
                if let Some(id) = self.pat_id[node] {
                    res.push((text_pos + 1, id));
                }
                node = self.fast[node];
            }
        }
        res
    }
}

/// Suffix array data structure, useful for a variety of string queries.
pub struct SuffixArray {
    /// The suffix array itself, holding suffix indices in sorted order.
    pub sfx: Vec<usize>,
    /// rank[i][j] = rank of the j'th suffix, considering only 2^i chars.
    /// In other words, rank[i] is a ranking of the substrings text[j..j+2^i].
    pub rank: Vec<Vec<usize>>,
}

impl SuffixArray {
    /// O(n + max_key) stable sort on the items generated by vals.
    /// Items v in vals are sorted according to val_to_key[v].
    fn counting_sort(
        vals: impl Iterator<Item = usize> + Clone,
        val_to_key: &[usize],
        max_key: usize,
    ) -> Vec<usize> {
        let mut counts = vec![0; max_key];
        for v in vals.clone() {
            counts[val_to_key[v]] += 1;
        }
        let mut total = 0;
        for c in counts.iter_mut() {
            total += *c;
            *c = total - *c;
        }
        let mut result = vec![0; total];
        for v in vals {
            let c = &mut counts[val_to_key[v]];
            result[*c] = v;
            *c += 1;
        }
        result
    }

    /// Suffix array construction in O(n log n) time.
    pub fn new(text: impl IntoIterator<Item = u8>) -> Self {
        let init_rank = text.into_iter().map(|ch| ch as usize).collect::<Vec<_>>();
        let n = init_rank.len();
        let mut sfx = Self::counting_sort(0..n, &init_rank, 256);
        let mut rank = vec![init_rank];
        // Invariant at the start of every loop iteration:
        // suffixes are sorted according to the first skip characters.
        for skip in (0..).map(|i| 1 << i).take_while(|&skip| skip < n) {
            let prev_rank = rank.last().unwrap();
            let mut cur_rank = prev_rank.clone();

            let pos = (n - skip..n).chain(sfx.into_iter().filter_map(|p| p.checked_sub(skip)));
            sfx = Self::counting_sort(pos, &prev_rank, max(n, 256));

            let mut prev = sfx[0];
            cur_rank[prev] = 0;
            for &cur in sfx.iter().skip(1) {
                if max(prev, cur) + skip < n
                    && prev_rank[prev] == prev_rank[cur]
                    && prev_rank[prev + skip] == prev_rank[cur + skip]
                {
                    cur_rank[cur] = cur_rank[prev];
                } else {
                    cur_rank[cur] = cur_rank[prev] + 1;
                }
                prev = cur;
            }
            rank.push(cur_rank);
        }
        Self { sfx, rank }
    }

    /// Computes the length of longest common prefix of text[i..] and text[j..].
    pub fn longest_common_prefix(&self, mut i: usize, mut j: usize) -> usize {
        let mut len = 0;
        for (k, rank) in self.rank.iter().enumerate().rev() {
            if rank[i] == rank[j] {
                i += 1 << k;
                j += 1 << k;
                len += 1 << k;
                if max(i, j) >= self.sfx.len() {
                    break;
                }
            }
        }
        len
    }
}

/// Manacher's algorithm for computing palindrome substrings in linear time.
/// pal[2*i] = odd length of palindrome centred at text[i].
/// pal[2*i+1] = even length of palindrome centred at text[i+0.5].
///
/// # Panics
///
/// Panics if text is empty.
pub fn palindromes(text: &[impl Eq]) -> Vec<usize> {
    let mut pal = Vec::with_capacity(2 * text.len() - 1);
    pal.push(1);
    while pal.len() < pal.capacity() {
        let i = pal.len() - 1;
        let max_len = min(i + 1, pal.capacity() - i);
        while pal[i] < max_len && text[(i - pal[i] - 1) / 2] == text[(i + pal[i] + 1) / 2] {
            pal[i] += 2;
        }
        if let Some(a) = 1usize.checked_sub(pal[i]) {
            pal.push(a);
        } else {
            for d in 1.. {
                let (a, b) = (pal[i - d], pal[i] - d);
                if a < b {
                    pal.push(a);
                } else {
                    pal.push(b);
                    break;
                }
            }
        }
    }
    pal
}

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

    #[test]
    fn test_trie() {
        let dict = vec!["banana", "benefit", "banapple", "ban"];

        let trie = dict.into_iter().fold(Trie::default(), |mut trie, word| {
            trie.insert(word.bytes());
            trie
        });

        assert_eq!(trie.get("".bytes()), Some(0));
        assert_eq!(trie.get("b".bytes()), Some(1));
        assert_eq!(trie.get("banana".bytes()), Some(6));
        assert_eq!(trie.get("be".bytes()), Some(7));
        assert_eq!(trie.get("bane".bytes()), None);
    }

    #[test]
    fn test_kmp_matching() {
        let pattern = "ana";
        let text = "banana";

        let matches = Matcher::new(pattern.as_bytes()).kmp_match(text.bytes());

        assert_eq!(matches, vec![0, 1, 2, 3, 2, 3]);
    }

    #[test]
    fn test_ac_matching() {
        let dict = vec!["banana", "benefit", "banapple", "ban", "fit"];
        let text = "banana bans, apple benefits.";

        let matcher = MultiMatcher::new(dict.iter().map(|s| s.bytes()));
        let match_nodes = matcher.ac_match(text.bytes());
        let end_pos_and_id = matcher.get_end_pos_and_pat_id(&match_nodes);

        assert_eq!(
            end_pos_and_id,
            vec![(3, 3), (6, 0), (10, 3), (26, 1), (26, 4)]
        );
    }

    #[test]
    fn test_suffix_array() {
        let text1 = "bobocel";
        let text2 = "banana";

        let sfx1 = SuffixArray::new(text1.bytes());
        let sfx2 = SuffixArray::new(text2.bytes());

        assert_eq!(sfx1.sfx, vec![0, 2, 4, 5, 6, 1, 3]);
        assert_eq!(sfx2.sfx, vec![5, 3, 1, 0, 4, 2]);

        assert_eq!(sfx1.longest_common_prefix(0, 2), 2);
        assert_eq!(sfx2.longest_common_prefix(1, 3), 3);

        // Check that sfx and rank.last() are essentially inverses of each other.
        for (p, &r) in sfx1.rank.last().unwrap().iter().enumerate() {
            assert_eq!(sfx1.sfx[r], p);
        }
        for (p, &r) in sfx2.rank.last().unwrap().iter().enumerate() {
            assert_eq!(sfx2.sfx[r], p);
        }
    }

    #[test]
    fn test_palindrome() {
        let text = "banana";

        let pal_len = palindromes(text.as_bytes());

        assert_eq!(pal_len, vec![1, 0, 1, 0, 3, 0, 5, 0, 3, 0, 1]);
    }
}
<commit_msg>Add Z algorithm implementation and test (#19)<commit_after>//! String processing algorithms.
use std::cmp::{max, min};
use std::collections::{hash_map::Entry, HashMap, VecDeque};

/// Prefix trie, easily augmentable by adding more fields and/or methods
pub struct Trie<C: std::hash::Hash + Eq> {
    links: Vec<HashMap<C, usize>>,
}

impl<C: std::hash::Hash + Eq> Default for Trie<C> {
    /// Creates an empty trie with a root node.
    fn default() -> Self {
        Self {
            links: vec![HashMap::new()],
        }
    }
}

impl<C: std::hash::Hash + Eq> Trie<C> {
    /// Inserts a word into the trie, and returns the index of its node.
    pub fn insert(&mut self, word: impl IntoIterator<Item = C>) -> usize {
        let mut node = 0;

        for ch in word {
            let len = self.links.len();
            node = match self.links[node].entry(ch) {
                Entry::Occupied(entry) => *entry.get(),
                Entry::Vacant(entry) => {
                    entry.insert(len);
                    self.links.push(HashMap::new());
                    len
                }
            }
        }
        node
    }

    /// Finds a word in the trie, and returns the index of its node.
    pub fn get(&self, word: impl IntoIterator<Item = C>) -> Option<usize> {
        let mut node = 0;
        for ch in word {
            node = *self.links[node].get(&ch)?;
        }
        Some(node)
    }
}

/// Single-pattern matching with the Knuth-Morris-Pratt algorithm
pub struct Matcher<'a, C: Eq> {
    /// The string pattern to search for.
    pub pattern: &'a [C],
    /// KMP match failure automaton. fail[i] is the length of the longest
    /// proper prefix-suffix of pattern[0..=i].
    pub fail: Vec<usize>,
}

impl<'a, C: Eq> Matcher<'a, C> {
    /// Precomputes the automaton that allows linear-time string matching.
    ///
    /// # Example
    ///
    /// ```
    /// use contest_algorithms::string_proc::Matcher;
    /// let byte_string: &[u8] = b"hello";
    /// let utf8_string: &str = "hello";
    /// let vec_char: Vec<char> = utf8_string.chars().collect();
    ///
    /// let match_from_byte_literal = Matcher::new(byte_string);
    /// let match_from_utf8 = Matcher::new(utf8_string.as_bytes());
    /// let match_from_chars = Matcher::new(&vec_char);
    ///
    /// let vec_int = vec![4, -3, 1];
    /// let match_from_ints = Matcher::new(&vec_int);
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if pattern is empty.
    pub fn new(pattern: &'a [C]) -> Self {
        let mut fail = Vec::with_capacity(pattern.len());
        fail.push(0);
        let mut len = 0;
        for ch in &pattern[1..] {
            while len > 0 && pattern[len] != *ch {
                len = fail[len - 1];
            }
            if pattern[len] == *ch {
                len += 1;
            }
            fail.push(len);
        }
        Self { pattern, fail }
    }

    /// KMP algorithm, sets @return[i] = length of longest prefix of pattern
    /// matching a suffix of text[0..=i].
    pub fn kmp_match(&self, text: impl IntoIterator<Item = C>) -> Vec<usize> {
        let mut len = 0;
        text.into_iter()
            .map(|ch| {
                if len == self.pattern.len() {
                    len = self.fail[len - 1];
                }
                while len > 0 && self.pattern[len] != ch {
                    len = self.fail[len - 1];
                }
                if self.pattern[len] == ch {
                    len += 1;
                }
                len
            })
            .collect()
    }
}

/// Multi-pattern matching with the Aho-Corasick algorithm
pub struct MultiMatcher<C: std::hash::Hash + Eq> {
    /// A prefix trie storing the string patterns to search for.
    pub trie: Trie<C>,
    /// Stores which completed pattern string each node corresponds to.
    pub pat_id: Vec<Option<usize>>,
    /// Aho-Corasick failure automaton. fail[i] is the node corresponding to the
    /// longest prefix-suffix of the node corresponding to i.
    pub fail: Vec<usize>,
    /// Shortcut to the next match along the failure chain, or to the root.
    pub fast: Vec<usize>,
}

impl<C: std::hash::Hash + Eq> MultiMatcher<C> {
    fn next(trie: &Trie<C>, fail: &[usize], mut node: usize, ch: &C) -> usize {
        loop {
            if let Some(&child) = trie.links[node].get(ch) {
                return child;
            } else if node == 0 {
                return 0;
            }
            node = fail[node];
        }
    }

    /// Precomputes the automaton that allows linear-time string matching.
    /// If there are duplicate patterns, all but one copy will be ignored.
    pub fn new(patterns: impl IntoIterator<Item = impl IntoIterator<Item = C>>) -> Self {
        let mut trie = Trie::default();
        let pat_nodes: Vec<usize> = patterns.into_iter().map(|pat| trie.insert(pat)).collect();

        let mut pat_id = vec![None; trie.links.len()];
        for (i, node) in pat_nodes.into_iter().enumerate() {
            pat_id[node] = Some(i);
        }

        let mut fail = vec![0; trie.links.len()];
        let mut fast = vec![0; trie.links.len()];
        let mut q: VecDeque<usize> = trie.links[0].values().cloned().collect();

        while let Some(node) = q.pop_front() {
            for (ch, &child) in &trie.links[node] {
                let nx = Self::next(&trie, &fail, fail[node], &ch);
                fail[child] = nx;
                fast[child] = if pat_id[nx].is_some() { nx } else { fast[nx] };
                q.push_back(child);
            }
        }

        Self {
            trie,
            pat_id,
            fail,
            fast,
        }
    }

    /// Aho-Corasick algorithm, sets @return[i] = node corresponding to
    /// longest prefix of some pattern matching a suffix of text[0..=i].
    pub fn ac_match(&self, text: impl IntoIterator<Item = C>) -> Vec<usize> {
        let mut node = 0;
        text.into_iter()
            .map(|ch| {
                node = Self::next(&self.trie, &self.fail, node, &ch);
                node
            })
            .collect()
    }

    /// For each non-empty match, returns where in the text it ends, and the index
    /// of the corresponding pattern.
    pub fn get_end_pos_and_pat_id(&self, match_nodes: &[usize]) -> Vec<(usize, usize)> {
        let mut res = vec![];
        for (text_pos, &(mut node)) in match_nodes.iter().enumerate() {
            while node != 0 {
                if let Some(id) = self.pat_id[node] {
                    res.push((text_pos + 1, id));
                }
                node = self.fast[node];
            }
        }
        res
    }
}

/// Suffix array data structure, useful for a variety of string queries.
pub struct SuffixArray {
    /// The suffix array itself, holding suffix indices in sorted order.
    pub sfx: Vec<usize>,
    /// rank[i][j] = rank of the j'th suffix, considering only 2^i chars.
    /// In other words, rank[i] is a ranking of the substrings text[j..j+2^i].
    pub rank: Vec<Vec<usize>>,
}

impl SuffixArray {
    /// O(n + max_key) stable sort on the items generated by vals.
    /// Items v in vals are sorted according to val_to_key[v].
    fn counting_sort(
        vals: impl Iterator<Item = usize> + Clone,
        val_to_key: &[usize],
        max_key: usize,
    ) -> Vec<usize> {
        let mut counts = vec![0; max_key];
        for v in vals.clone() {
            counts[val_to_key[v]] += 1;
        }
        let mut total = 0;
        for c in counts.iter_mut() {
            total += *c;
            *c = total - *c;
        }
        let mut result = vec![0; total];
        for v in vals {
            let c = &mut counts[val_to_key[v]];
            result[*c] = v;
            *c += 1;
        }
        result
    }

    /// Suffix array construction in O(n log n) time.
    pub fn new(text: impl IntoIterator<Item = u8>) -> Self {
        let init_rank = text.into_iter().map(|ch| ch as usize).collect::<Vec<_>>();
        let n = init_rank.len();
        let mut sfx = Self::counting_sort(0..n, &init_rank, 256);
        let mut rank = vec![init_rank];
        // Invariant at the start of every loop iteration:
        // suffixes are sorted according to the first skip characters.
        for skip in (0..).map(|i| 1 << i).take_while(|&skip| skip < n) {
            let prev_rank = rank.last().unwrap();
            let mut cur_rank = prev_rank.clone();

            let pos = (n - skip..n).chain(sfx.into_iter().filter_map(|p| p.checked_sub(skip)));
            sfx = Self::counting_sort(pos, &prev_rank, max(n, 256));

            let mut prev = sfx[0];
            cur_rank[prev] = 0;
            for &cur in sfx.iter().skip(1) {
                if max(prev, cur) + skip < n
                    && prev_rank[prev] == prev_rank[cur]
                    && prev_rank[prev + skip] == prev_rank[cur + skip]
                {
                    cur_rank[cur] = cur_rank[prev];
                } else {
                    cur_rank[cur] = cur_rank[prev] + 1;
                }
                prev = cur;
            }
            rank.push(cur_rank);
        }
        Self { sfx, rank }
    }

    /// Computes the length of longest common prefix of text[i..] and text[j..].
    pub fn longest_common_prefix(&self, mut i: usize, mut j: usize) -> usize {
        let mut len = 0;
        for (k, rank) in self.rank.iter().enumerate().rev() {
            if rank[i] == rank[j] {
                i += 1 << k;
                j += 1 << k;
                len += 1 << k;
                if max(i, j) >= self.sfx.len() {
                    break;
                }
            }
        }
        len
    }
}

/// Manacher's algorithm for computing palindrome substrings in linear time.
/// pal[2*i] = odd length of palindrome centred at text[i].
/// pal[2*i+1] = even length of palindrome centred at text[i+0.5].
///
/// # Panics
///
/// Panics if text is empty.
pub fn palindromes(text: &[impl Eq]) -> Vec<usize> {
    let mut pal = Vec::with_capacity(2 * text.len() - 1);
    pal.push(1);
    while pal.len() < pal.capacity() {
        let i = pal.len() - 1;
        let max_len = min(i + 1, pal.capacity() - i);
        while pal[i] < max_len && text[(i - pal[i] - 1) / 2] == text[(i + pal[i] + 1) / 2] {
            pal[i] += 2;
        }
        if let Some(a) = 1usize.checked_sub(pal[i]) {
            pal.push(a);
        } else {
            for d in 1.. {
                let (a, b) = (pal[i - d], pal[i] - d);
                if a < b {
                    pal.push(a);
                } else {
                    pal.push(b);
                    break;
                }
            }
        }
    }
    pal
}

/// Z algorithm for computing an array Z[..], where Z[i] is the length of the
/// longest text substring starting from index i that is **also a prefix** of
/// the text.
///
/// This runs in O(n) time. It can be embedded in a larger algorithm, or used
/// for string searching as an alternative to KMP above.
///
/// # Example
///
/// ```
/// use contest_algorithms::string_proc::z_algorithm;
/// let z = z_algorithm("ababbababbabababbabababbababbaba".as_bytes());
/// assert_eq!(
///     z,
///     vec![
///         32, 0, 2, 0, 0, 9, 0, 2, 0, 0, 4, 0, 9, 0, 2, 0, 0, 4, 0, 13, 0, 2,
///         0, 0, 8, 0, 2, 0, 0, 3, 0, 1,
///     ],
/// );
/// ```
pub fn z_algorithm(text: &[impl Eq]) -> Vec<usize> {
    let n = text.len();
    let (mut l, mut r) = (0, 0);
    let mut z = vec![0; n];
    z[0] = n;
    for i in 1..n {
        if i < r {
            z[i] = min(r - i, z[i - l]);
        }
        while i + z[i] < n && text[i + z[i]] == text[z[i]] {
            z[i] += 1;
        }
        if i + z[i] > r {
            l = i;
            r = i + z[i];
        }
    }
    z
}

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

    #[test]
    fn test_trie() {
        let dict = vec!["banana", "benefit", "banapple", "ban"];

        let trie = dict.into_iter().fold(Trie::default(), |mut trie, word| {
            trie.insert(word.bytes());
            trie
        });

        assert_eq!(trie.get("".bytes()), Some(0));
        assert_eq!(trie.get("b".bytes()), Some(1));
        assert_eq!(trie.get("banana".bytes()), Some(6));
        assert_eq!(trie.get("be".bytes()), Some(7));
        assert_eq!(trie.get("bane".bytes()), None);
    }

    #[test]
    fn test_kmp_matching() {
        let pattern = "ana";
        let text = "banana";

        let matches = Matcher::new(pattern.as_bytes()).kmp_match(text.bytes());

        assert_eq!(matches, vec![0, 1, 2, 3, 2, 3]);
    }

    #[test]
    fn test_ac_matching() {
        let dict = vec!["banana", "benefit", "banapple", "ban", "fit"];
        let text = "banana bans, apple benefits.";

        let matcher = MultiMatcher::new(dict.iter().map(|s| s.bytes()));
        let match_nodes = matcher.ac_match(text.bytes());
        let end_pos_and_id = matcher.get_end_pos_and_pat_id(&match_nodes);

        assert_eq!(
            end_pos_and_id,
            vec![(3, 3), (6, 0), (10, 3), (26, 1), (26, 4)]
        );
    }

    #[test]
    fn test_suffix_array() {
        let text1 = "bobocel";
        let text2 = "banana";

        let sfx1 = SuffixArray::new(text1.bytes());
        let sfx2 = SuffixArray::new(text2.bytes());

        assert_eq!(sfx1.sfx, vec![0, 2, 4, 5, 6, 1, 3]);
        assert_eq!(sfx2.sfx, vec![5, 3, 1, 0, 4, 2]);

        assert_eq!(sfx1.longest_common_prefix(0, 2), 2);
        assert_eq!(sfx2.longest_common_prefix(1, 3), 3);

        // Check that sfx and rank.last() are essentially inverses of each other.
        for (p, &r) in sfx1.rank.last().unwrap().iter().enumerate() {
            assert_eq!(sfx1.sfx[r], p);
        }
        for (p, &r) in sfx2.rank.last().unwrap().iter().enumerate() {
            assert_eq!(sfx2.sfx[r], p);
        }
    }

    #[test]
    fn test_palindrome() {
        let text = "banana";

        let pal_len = palindromes(text.as_bytes());

        assert_eq!(pal_len, vec![1, 0, 1, 0, 3, 0, 5, 0, 3, 0, 1]);
    }
}
<|endoftext|>


<commit_before>
///
/// Systems are a set of event handlers and optionally some associated state.
///
/// The event handlers are invoked with a list of event data and have access to component
/// lists. This access can be immutable or mutable which is made explicit so that
/// the event handler scheduler might parallelize handler invocations.
///
/// To properly enforce this I guess the scheduler would acquire the locks on the component
/// lists.
///
/// So the context of the handler function would consist of:
///
///   The handler state
///   The event data list
///   Immutable components lists
///   Mutable components lists
///
/// For example the following invocation:
///
/// system! my_system {
///   state! { i: i64 }
///   on!(event_name, { positions: Position}, { descriptions: Description }) {
///     state.i += 1;
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
/// }
///
/// Expands to:
///
/// pub mod my_system {
///   struct State { i: i64 }
///
///   pub fn event_name(state: &mut State, data: &Vec<event_name::Data>, positions: &Vec<Position>, descriptions: &mut Vec<Description> ) {
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
///
///   pub fn register() {
///      events::register_handler(event_name); // etc..
///   }
/// }
///
/// How are we going to register this handler at the event loop?
///
/// Ideally we would have just one 'register' call per system. But to have that the register call should enable
/// all nested handlers. We could also just have one handler per system. That would make things easier..
/// Maybe there's some scheme using recursive macros that we could use to generate a register_system that collects
/// all on! calls. Ok this is definitely a possibility. We could simply match the on! macro in the system! macro
/// and use that to populate the register function.
///
/// How are we going to store/invoke these handlers.
///
/// To invoke the handler it will require the state, the components and the data list passed in the right order.
/// we could have a separate invoker function that invokes event_name with the arguments passed in. Its arguments
/// would be the component lists in two vecs, as well as the event data list.
///
/// This could work!
///

#[macro_export]
macro_rules! system {
	( $system_name:ident { $($contents:tt)* } ) => {
		pub mod $system_name {
			use std::collections::HashMap;
			use std::any::Any;
			use shared_mutex::{ SharedMutex, MappedSharedMutexReadGuard };

			system_contents!{ ( $($contents)* ) [ ] }
		}
	}
}

#[macro_export]
macro_rules! system_contents {
	// Consume on! invocations
	(
		(
			on! (
				$event_name:ident, $($event_declaration:tt)*
			) $event_body:block $($rest:tt)*
		) [
			$($event_decls:tt)*
		]
	) => (
		on! { ($event_name, $( $event_declaration)* ) $event_body }

		system_contents!{( $($rest)* ) [ ( $event_name, $($event_declaration)* ) , $($event_decls)* ] }
	);

	(
		(
			state! { $($state_declaration:tt)* } $($rest:tt)*
		) [ $($event_decls:tt)* ]
	) => (
		state! { $($state_declaration)* }

		system_contents!{( $($rest)* ) [ $($event_decls)* ] }
	);

	// When all content has been consumed emit register macro
	(
		() [ $($event_decls:tt)* ]
	) => (
		system_register!{ $($event_decls)* }
	)
}

#[macro_export]
macro_rules! on {
	( ($event_name:ident, { $( $mut_name:ident : $mut_typ:ty )* } , { $($name:ident : $typ:ty)* } ) $event_body:block ) => (

		use super::$event_name;

		impl State {
			pub fn $event_name(&mut self,
				data: &Vec<$event_name::Data>,
				$( $name : &Vec<$typ>),*
				$( $mut_name : &mut Vec<$mut_typ> ),* ) $event_body

		}

		pub fn $event_name(data: Vec<$event_name::Data>, components: Vec<&Any>, mut_components: Vec<&mut Any>) {
			let components_iter = components.iter();
			let components_iter = mut_components.iter_mut();

			$(
				let $name : &Vec<$typ> = components_iter
					.next().expect("Event components list too short.")
					.downcast_ref().expect("Event component not of expected type.");
			)*

			$(
				let $mut_name: &mut Vec<$mut_name> = components_iter
					.next().expect("Event components list too short.")
					.downcast_ref().expect("Event component not of expected type.");
			)*

			state.write().expect("Event state corrupted").$event_name(
				data,
				$($name),*
				$($mut_name),*
			);
		}
	)
}

#[macro_export]
macro_rules! state {
	( $( $name:ident : $field:ty )* ) => (
		#[derive(Default)]
		pub struct State {
			pub $($name : $field),*
		}

		lazy_static! {
			pub static ref state: SharedMutex<State> = SharedMutex::new(State::default());
		}
	)
}

#[macro_export]
macro_rules! system_register {
	( $($event_decls:tt)* )=> (
		pub fn register() {

		}
	)
}

pub mod example_event {
	pub struct Data {
		x: i64
	}
}

system!( example_system {
	state! { x: i64 }

	on!( example_event, { positions: State }, {}) {
		self.x += 1;
	}

});

<commit_msg>explicitly bind self<commit_after>
///
/// Systems are a set of event handlers and optionally some associated state.
///
/// The event handlers are invoked with a list of event data and have access to component
/// lists. This access can be immutable or mutable which is made explicit so that
/// the event handler scheduler might parallelize handler invocations.
///
/// To properly enforce this I guess the scheduler would acquire the locks on the component
/// lists.
///
/// So the context of the handler function would consist of:
///
///   The handler state
///   The event data list
///   Immutable components lists
///   Mutable components lists
///
/// For example the following invocation:
///
/// system! my_system {
///   state! { i: i64 }
///   on!(event_name, { positions: Position}, { descriptions: Description }) {
///     state.i += 1;
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
/// }
///
/// Expands to:
///
/// pub mod my_system {
///   struct State { i: i64 }
///
///   pub fn event_name(state: &mut State, data: &Vec<event_name::Data>, positions: &Vec<Position>, descriptions: &mut Vec<Description> ) {
///     let position = positions[0];
///     descriptions[0].set(format!("Position = {},{}", position.x, position.y));
///   }
///
///   pub fn register() {
///      events::register_handler(event_name); // etc..
///   }
/// }
///
/// How are we going to register this handler at the event loop?
///
/// Ideally we would have just one 'register' call per system. But to have that the register call should enable
/// all nested handlers. We could also just have one handler per system. That would make things easier..
/// Maybe there's some scheme using recursive macros that we could use to generate a register_system that collects
/// all on! calls. Ok this is definitely a possibility. We could simply match the on! macro in the system! macro
/// and use that to populate the register function.
///
/// How are we going to store/invoke these handlers.
///
/// To invoke the handler it will require the state, the components and the data list passed in the right order.
/// we could have a separate invoker function that invokes event_name with the arguments passed in. Its arguments
/// would be the component lists in two vecs, as well as the event data list.
///
/// This could work!
///

#[macro_export]
macro_rules! system {
	( $system_name:ident { $($contents:tt)* } ) => {
		pub mod $system_name {
			use std::collections::HashMap;
			use std::any::Any;
			use shared_mutex::{ SharedMutex, MappedSharedMutexReadGuard };

			system_contents!{ ( $($contents)* ) [ ] }
		}
	}
}

#[macro_export]
macro_rules! system_contents {
	// Consume on! invocations
	(
		(
			on! (
				$event_name:ident, $($event_declaration:tt)*
			) $_self:ident => $event_body:block $($rest:tt)*
		) [
			$($event_decls:tt)*
		]
	) => (
		on! { ($event_name, $( $event_declaration)* ) $_self => $event_body }

		system_contents!{( $($rest)* ) [ ( $event_name, $($event_declaration)* ) , $($event_decls)* ] }
	);

	(
		(
			state! { $($state_declaration:tt)* } $($rest:tt)*
		) [ $($event_decls:tt)* ]
	) => (
		state! { $($state_declaration)* }

		system_contents!{( $($rest)* ) [ $($event_decls)* ] }
	);

	// When all content has been consumed emit register macro
	(
		() [ $($event_decls:tt)* ]
	) => (
		system_register!{ $($event_decls)* }
	)
}

#[macro_export]
macro_rules! on {
	( ($event_name:ident, { $( $mut_name:ident : $mut_typ:ty )* } , { $($name:ident : $typ:ty)* } ) $_self:ident => $event_body:block ) => (

		use super::$event_name;

		impl State {
			pub fn $event_name(&mut $_self,
				data: Vec<$event_name::Data>,
				$( $name : &Vec<$typ>),*
				$( $mut_name : &mut Vec<$mut_typ> ),* ) $event_body

		}

		pub fn $event_name(data: Vec<$event_name::Data>, components: Vec<&Any>, mut_components: Vec<&mut Any>) {
			let components_iter = components.iter();
			let components_iter = mut_components.iter_mut();

			$(
				let $name : &Vec<$typ> = components_iter
					.next().expect("Event components list too short.")
					.downcast_ref().expect("Event component not of expected type.");
			)*

			$(
				let $mut_name: &mut Vec<$mut_name> = components_iter
					.next().expect("Event components list too short.")
					.downcast_ref().expect("Event component not of expected type.");
			)*

			state.write().expect("Event state corrupted").$event_name(
				data,
				$($name),*
				$($mut_name),*
			);
		}
	)
}

#[macro_export]
macro_rules! state {
	( $( $name:ident : $field:ty )* ) => (
		#[derive(Default)]
		pub struct State {
			pub $($name : $field),*
		}

		lazy_static! {
			pub static ref state: SharedMutex<State> = SharedMutex::new(State::default());
		}
	)
}

#[macro_export]
macro_rules! system_register {
	( $($event_decls:tt)* )=> (
		pub fn register() {

		}
	)
}

pub mod example_event {
	pub struct Data {
		x: i64
	}
}

system!( example_system {
	state! { x: i64 }

	on!( example_event, { positions: State }, {}) self => {
		self.x += 1;
	}

});

<|endoftext|>