<commit_before>#![feature(default_type_params)]
#![feature(macro_rules)]

#[deriving(Show)]
pub struct Oid(u32);

#[deriving(Show)]
pub struct TransactionId(u32);

#[deriving(Show)]
pub struct CommandId(u32);

pub type Datum = uint;

#[deriving(Show)]
pub struct BlockNumber(u32);

#[deriving(Show)]
pub struct BlockIdData {
    bi_hi: u16,
    bi_lo: u16,
}

#[deriving(Show)]
pub struct OffsetNumber(u16);

#[deriving(Show)]
pub struct ItemPointerData {
    ip_blkid: BlockIdData,
    ip_posid: OffsetNumber,
}

#[deriving(Show)]
#[repr(packed)]
pub struct HeapTupleFields {
    t_xmin: TransactionId, // inserting xact ID
    t_xmax: TransactionId, // deleting or locking xact ID
    t_cid: CommandId, // inserting or deleting command ID, or both
}

#[deriving(Show)]
pub struct NormalTupleHeaderData {
    t_heap: HeapTupleFields,
    t_ctid: ItemPointerData, // current t_ctid of this or newer tuple
}

#[deriving(Show)]
pub struct MinimalTupleHeaderData; // unit struct

#[repr(C)]
pub struct HeapTupleHeaderData<T, Sized? D> {
    data_: T,
    // ^ - 18 bytes (normally) - ^
    t_infomask2: u16, // number of attributes + various flags
    t_infomask: u16, // various flag bits, see below
    t_hoff: u8, // sizeof header incl. bitmap, padding
    // ^ - 5 bytes, 23 bytes total (normally) - ^
    bits_: [u8, .. 0], // bitmap of NULLs -- VARIABLE LENGTH
    rest_: D, // More bits (if necessary) plus user data (suitably aligned)
}

impl<T, Sized? D> Deref<T> for HeapTupleHeaderData<T, D> {
    #[inline]
    fn deref(&self) -> &T { &self.data_ }
}

/*impl<T> DerefMut<T> for HeapTupleHeaderData<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T { &mut self.t_data_ }
}*/

#[repr(C)]
pub struct HeapTupleHeader<T, Sized? U> {
    t_len: u32, // length of *t_data
    header_: T,
    t_data: U, // -> tuple header and data
}

pub struct HeapTupleTemp;

pub struct HeapTupleDisk {
    t_self: ItemPointerData, // SelfItemPointer
    t_table_oid: Oid, // table the tuple came from
}

impl<T, U> Deref<T> for HeapTupleHeader<T, U> {
    fn deref(&self) -> &T {
        &self.header_
    }
}

impl<T, U> DerefMut<T> for HeapTupleHeader<T, U> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.header_
    }
}

pub type HeapTupleIndirectData<'a, T, U = NormalTupleHeaderData, D = [Datum]> = HeapTupleHeader<T, &'a HeapTupleHeaderData<U, D>>;

pub type HeapTupleContiguousData<T, U = NormalTupleHeaderData, D = [Datum]> = HeapTupleHeader<T, HeapTupleHeaderData<U, D>>;

pub const MAXIMUM_ALIGNOF: uint = 8;

macro_rules! with_offset(($ty:ty,$field:ident,$data:ident,$b:expr) => {
    unsafe {
        let $data = 0 as *const $ty;
        let $field = &(*$data).$field;
        let result = $b;
        result
    }
})

macro_rules! offset_of(($ty:ty,$field:ident) => {
    with_offset!($ty, $field, data, ($field as *const _ as uint) - (data as uint))
})

macro_rules! min_align_of_offset(($ty:ty,$field:ident) => {
    with_offset!($ty, $field, data, ::std::mem::min_align_of_val($field))
})

// (offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF
pub const MINIMAL_TUPLE_PADDING: uint = 6;

/*pub struct Version {
    version: uint,
}

pub struct Transaction {
    version: Version,
}

pub const BUFFER_SIZE: uint = 512;

struct Buffer {
    buffer: Arc<RwLock<[u8, .. BUFFER_SIZE]>>,
}

struct Page {
    : UnsafeCell<T>,
}

struct Database {
    pages: Pages,
}

pub struct TransactionManager {
    transactions: *T,
    database: Database,
}*/

#[cfg(test)]
mod tests {
    use std::mem;
    use std::u32;
    use super::{
        Datum,
        HeapTupleContiguousData,
        HeapTupleIndirectData,
        HeapTupleDisk,
        HeapTupleHeaderData,
        HeapTupleTemp,
        MinimalTupleHeaderData,
        NormalTupleHeaderData,
    };

    #[test]
    fn maximum_alignof() {
        assert_eq!(mem::align_of::<uint>(), super::MAXIMUM_ALIGNOF);
    }

    #[test]
    fn heap_form_tuple() {
        let tuple: &HeapTupleHeaderData<MinimalTupleHeaderData, [Datum]> = &HeapTupleHeaderData {
            data_: MinimalTupleHeaderData,
            // ^ - 18 bytes (normally) - ^
            t_infomask2: 0,
            t_infomask: 0,
            t_hoff: 0,
            bits_: [],
            rest_: [1],
        };
        println!("{}", &tuple.rest_);
        //assert_eq!(mem::align_of_val(&tuple.rest_), super::MAXIMUM_ALIGNOF);
    }

    #[test]
    // (offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF
    fn minimal_tuple_padding() {
        type C<T, U, D> = HeapTupleContiguousData<T, U, D>;
        type I<'a, T, U, D> = HeapTupleIndirectData<'a, T, U, D>;
        type T = HeapTupleTemp;
        type S = HeapTupleDisk;
        type M = MinimalTupleHeaderData;
        type N = NormalTupleHeaderData;
        type D = [Datum, .. 0];
        let offset = offset_of!(HeapTupleHeaderData<M, D>, rest_);
        let align = min_align_of_offset!(HeapTupleHeaderData<M, D>, rest_);
        println!("{} {} {}", offset, mem::size_of::<HeapTupleHeaderData<M, D>>(), align);
        assert_eq!(align, super::MAXIMUM_ALIGNOF);
        let offset = offset_of!(HeapTupleHeaderData<N, D>, rest_);
        let align = min_align_of_offset!(HeapTupleHeaderData<N, D>, rest_);
        println!("{} {} {}", offset, mem::size_of::<HeapTupleHeaderData<N, D>>(), align);
        assert_eq!(align, super::MAXIMUM_ALIGNOF);

        let offset = offset_of!(C<T, M, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<T, M, D>>());
        let offset = offset_of!(I<T, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<I<T, N, D>>());
        let offset = offset_of!(I<S, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<I<S, N, D>>());
        let offset = offset_of!(C<S, M, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<S, M, D>>());
        let offset = offset_of!(C<T, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<T, N, D>>());
        let offset = offset_of!(C<S, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<S, N, D>>());

        let offset = offset_of!(HeapTupleHeaderData<N, D>, t_infomask2);
        //println!("{} {}", offset, mem::size_of::<HeapTupleHeaderData<N, D>>());
        let minimal_tuple_padding = (offset - u32::BYTES) % super::MAXIMUM_ALIGNOF;
        assert_eq!(minimal_tuple_padding, super::MINIMAL_TUPLE_PADDING);
    }
}
<commit_msg>Adding typesafe bitflags.<commit_after>#![feature(default_type_params)]
#![feature(macro_rules)]

#[deriving(Show)]
pub struct Oid(u32);

#[deriving(Show)]
pub struct TransactionId(u32);

#[deriving(Show)]
pub struct CommandId(u32);

pub type Datum = uint;

#[deriving(Show)]
pub struct BlockNumber(u32);

#[deriving(Show)]
pub struct BlockIdData {
    bi_hi: u16,
    bi_lo: u16,
}

#[deriving(Show)]
pub struct OffsetNumber(u16);

#[deriving(Show)]
pub struct ItemPointerData {
    ip_blkid: BlockIdData,
    ip_posid: OffsetNumber,
}

#[deriving(Show)]
#[repr(packed)]
pub struct HeapTupleFields {
    t_xmin: TransactionId, // inserting xact ID
    t_xmax: TransactionId, // deleting or locking xact ID
    t_cid: CommandId, // inserting or deleting command ID, or both
}

#[deriving(Show)]
pub struct NormalTupleHeaderData {
    t_heap: HeapTupleFields,
    t_ctid: ItemPointerData, // current t_ctid of this or newer tuple
}

#[deriving(Show)]
pub struct MinimalTupleHeaderData; // unit struct

bitflags! {
    #[deriving(Show)]
    flags HeapInfoMask: u16 {
        const HEAP_HASNULL  =           0x0001, // has null attribute(s)
        const HEAP_HASVARWIDTH =        0x0002, // has variable-width attribute(s)
        const HEAP_HASEXTERNAL =        0x0004, // has external stored attribute(s)
        const HEAP_HASOID =             0x0008, // has an object-id field
        const HEAP_XMAX_KEYSHR_LOCK =   0x0010, // xmax is a key-shared locker
        const HEAP_COMBOCID =           0x0020, // t_cid is a combo cid
        const HEAP_XMAX_EXCL_LOCK =     0x0040, // xmax is exclusive locker
        const HEAP_XMAX_LOCK_ONLY =     0x0080, // xmax, if valid, is only a locker

        // xmax is a shared locker
        const HEAP_XMAX_SHR_LOCK = HEAP_XMAX_EXCL_LOCK.bits | HEAP_XMAX_KEYSHR_LOCK.bits,
        const HEAP_LOCK_MASK = HEAP_XMAX_SHR_LOCK.bits | HEAP_XMAX_EXCL_LOCK.bits |
                               HEAP_XMAX_KEYSHR_LOCK.bits,

        const HEAP_XMIN_COMMITTED =   0x0100,  /* t_xmin committed */
        const HEAP_XMIN_INVALID =     0x0200,  /* t_xmin invalid/aborted */
        const HEAP_XMIN_FROZEN=      HEAP_XMIN_COMMITTED.bits|HEAP_XMIN_INVALID.bits,
        const HEAP_XMAX_COMMITTED =   0x0400,  /* t_xmax committed */
        const HEAP_XMAX_INVALID =     0x0800,  /* t_xmax invalid/aborted */
        const HEAP_XMAX_IS_MULTI =    0x1000,  /* t_xmax is a MultiXactId */
        const HEAP_UPDATED =          0x2000,  /* this is UPDATEd version of row */
        const HEAP_MOVED_OFF =        0x4000,  /* moved to another place by pre-9.0
                                               * VACUUM FULL; kept for binary
                                               * upgrade support */
        const HEAP_MOVED_IN =         0x8000,  /* moved from another place by pre-9.0
                                               * VACUUM FULL; kept for binary
                                               * upgrade support */
        const HEAP_MOVED = HEAP_MOVED_OFF.bits | HEAP_MOVED_IN.bits,
        const HEAP_XACT_MASK = 0xFFF0,  /* visibility-related bits */
    }
}

bitflags! {
    #[deriving(Show)]
    flags HeapInfoMask2: u16 {
        const HEAP_NATTS_MASK =     0x07FF, // 11 bits for number of attributes
        // bits 0x1800 are available
        const HEAP_KEYS_UPDATED =   0x2000, // tuple was updated and key cols modified, or tuple
                                            // deleted
        const HEAP_HOT_UPDATED =    0x4000, // tuple was HOT-updated
        const HEAP_ONLY_TUPLE =     0x8000, // this is heap-only tuple
        const HEAP2_XACT_MASK =     0xE000, // visibility-related bits

        /*
        * HEAP_TUPLE_HAS_MATCH is a temporary flag used during hash joins.  It is
        * only used in tuples that are in the hash table, and those don't need
        * any visibility information, so we can overlay it on a visibility flag
        * instead of using up a dedicated bit.
        */
        const HEAP_TUPLE_HAS_MATCH = HEAP_ONLY_TUPLE.bits,
    }
}

#[repr(C)]
pub struct HeapTupleHeaderData<T, Sized? D> {
    data_: T,
    // ^ - 18 bytes (normally) - ^
    t_infomask2: HeapInfoMask2, // number of attributes + various flags
    t_infomask: HeapInfoMask, // various flag bits, see below
    //t_hoff: u8, // sizeof header incl. bitmap, padding
    // ^ - 5 bytes, 23 bytes total (normally) - ^
    //bits_: [u8, .. 0], // bitmap of NULLs -- VARIABLE LENGTH
    rest_: D, // More bits (if necessary) plus user data (suitably aligned)
}

impl<T, Sized? D> Deref<T> for HeapTupleHeaderData<T, D> {
    #[inline]
    fn deref(&self) -> &T { &self.data_ }
}

/*impl<T> DerefMut<T> for HeapTupleHeaderData<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T { &mut self.t_data_ }
}*/

#[repr(C)]
pub struct HeapTupleHeader<T, Sized? U> {
    t_len: u32, // length of *t_data
    header_: T,
    t_data: U, // -> tuple header and data
}

pub struct HeapTupleTemp;

pub struct HeapTupleDisk {
    t_self: ItemPointerData, // SelfItemPointer
    t_table_oid: Oid, // table the tuple came from
}

impl<T, U> Deref<T> for HeapTupleHeader<T, U> {
    fn deref(&self) -> &T {
        &self.header_
    }
}

impl<T, U> DerefMut<T> for HeapTupleHeader<T, U> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.header_
    }
}

pub type HeapTupleIndirectData<'a, T, U = NormalTupleHeaderData, D = [Datum]> = HeapTupleHeader<T, &'a HeapTupleHeaderData<U, D>>;

pub type HeapTupleContiguousData<T, U = NormalTupleHeaderData, D = [Datum]> = HeapTupleHeader<T, HeapTupleHeaderData<U, D>>;

pub const MAXIMUM_ALIGNOF: uint = 8;

macro_rules! with_offset(($ty:ty,$field:ident,$data:ident,$b:expr) => {
    unsafe {
        let $data = 0 as *const $ty;
        let $field = &(*$data).$field;
        let result = $b;
        result
    }
})

macro_rules! offset_of(($ty:ty,$field:ident) => {
    with_offset!($ty, $field, data, ($field as *const _ as uint) - (data as uint))
})

macro_rules! min_align_of_offset(($ty:ty,$field:ident) => {
    with_offset!($ty, $field, data, ::std::mem::min_align_of_val($field))
})

// (offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF
pub const MINIMAL_TUPLE_PADDING: uint = 6;

/*pub struct Version {
    version: uint,
}

pub struct Transaction {
    version: Version,
}

pub const BUFFER_SIZE: uint = 512;

struct Buffer {
    buffer: Arc<RwLock<[u8, .. BUFFER_SIZE]>>,
}

struct Page {
    : UnsafeCell<T>,
}

struct Database {
    pages: Pages,
}

pub struct TransactionManager {
    transactions: *T,
    database: Database,
}*/

#[cfg(test)]
mod tests {
    use std::mem;
    use std::u32;
    use super::{
        Datum,
        HeapTupleContiguousData,
        HeapTupleIndirectData,
        HeapTupleDisk,
        HeapTupleHeaderData,
        HeapTupleTemp,
        HeapInfoMask,
        HeapInfoMask2,
        MinimalTupleHeaderData,
        NormalTupleHeaderData,
    };

    #[test]
    fn maximum_alignof() {
        assert_eq!(mem::align_of::<uint>(), super::MAXIMUM_ALIGNOF);
    }

    #[test]
    fn heap_form_tuple() {
        let tuple: &HeapTupleHeaderData<MinimalTupleHeaderData, [Datum]> = &HeapTupleHeaderData {
            data_: MinimalTupleHeaderData,
            // ^ - 18 bytes (normally) - ^
            t_infomask2: HeapInfoMask2::empty(),
            t_infomask: super::HEAP_LOCK_MASK,
            //t_hoff: 0,
            //bits_: [],
            rest_: [1],
        };
        println!("{}: {}", &tuple.rest_, tuple.t_infomask);
        //assert_eq!(mem::align_of_val(&tuple.rest_), super::MAXIMUM_ALIGNOF);
    }

    #[test]
    // (offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF
    fn minimal_tuple_padding() {
        type C<T, U, D> = HeapTupleContiguousData<T, U, D>;
        type I<'a, T, U, D> = HeapTupleIndirectData<'a, T, U, D>;
        type T = HeapTupleTemp;
        type S = HeapTupleDisk;
        type M = MinimalTupleHeaderData;
        type N = NormalTupleHeaderData;
        type D = [Datum, .. 0];
        let offset = offset_of!(HeapTupleHeaderData<M, D>, rest_);
        let align = min_align_of_offset!(HeapTupleHeaderData<M, D>, rest_);
        println!("{} {} {}", offset, mem::size_of::<HeapTupleHeaderData<M, D>>(), align);
        assert_eq!(align, super::MAXIMUM_ALIGNOF);
        let offset = offset_of!(HeapTupleHeaderData<N, D>, rest_);
        let align = min_align_of_offset!(HeapTupleHeaderData<N, D>, rest_);
        println!("{} {} {}", offset, mem::size_of::<HeapTupleHeaderData<N, D>>(), align);
        assert_eq!(align, super::MAXIMUM_ALIGNOF);

        let offset = offset_of!(C<T, M, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<T, M, D>>());
        let offset = offset_of!(I<T, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<I<T, N, D>>());
        let offset = offset_of!(I<S, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<I<S, N, D>>());
        let offset = offset_of!(C<S, M, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<S, M, D>>());
        let offset = offset_of!(C<T, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<T, N, D>>());
        let offset = offset_of!(C<S, N, D>, t_data);
        println!("{} {}", offset, mem::size_of::<C<S, N, D>>());

        let offset = offset_of!(HeapTupleHeaderData<N, D>, t_infomask2);
        //println!("{} {}", offset, mem::size_of::<HeapTupleHeaderData<N, D>>());
        let minimal_tuple_padding = (offset - u32::BYTES) % super::MAXIMUM_ALIGNOF;
        assert_eq!(minimal_tuple_padding, super::MINIMAL_TUPLE_PADDING);
    }
}
<|endoftext|>


<commit_before>#![feature(rustc_private)]

#![allow(clippy::cast_lossless)]

#[macro_use]
extern crate log;
// From rustc.
extern crate syntax;
extern crate rustc_apfloat;
#[macro_use] extern crate rustc;
extern crate rustc_data_structures;
extern crate rustc_mir;
extern crate rustc_target;

mod fn_call;
mod operator;
mod intrinsic;
mod helpers;
mod tls;
mod range_map;
mod mono_hash_map;
mod stacked_borrows;
mod intptrcast;
mod machine;
mod eval;

// Make all those symbols available in the same place as our own.
pub use rustc_mir::interpret::*;
// Resolve ambiguity.
pub use rustc_mir::interpret::{self, AllocMap, PlaceTy};

pub use crate::fn_call::EvalContextExt as MissingFnsEvalContextExt;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::intrinsic::EvalContextExt as IntrinsicEvalContextExt;
pub use crate::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
pub use crate::range_map::RangeMap;
pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item};
pub use crate::machine::{MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt};
pub use crate::eval::{eval_main, create_ecx, MiriConfig};

// Some global facts about the emulated machine.
pub const PAGE_SIZE: u64 = 4*1024;
pub const STACK_ADDR: u64 = 16*PAGE_SIZE;
pub const NUM_CPUS: u64 = 1;

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub fn miri_default_args() -> &'static [&'static str] {
    // The flags here should be kept in sync with what bootstrap adds when `test-miri` is
    // set, which happens in `bootstrap/bin/rustc.rs` in the rustc sources.
    &["-Zalways-encode-mir", "-Zmir-emit-retag", "-Zmir-opt-level=0", "--cfg=miri"]
}
<commit_msg>comment on STACK_ADDR<commit_after>#![feature(rustc_private)]

#![allow(clippy::cast_lossless)]

#[macro_use]
extern crate log;
// From rustc.
extern crate syntax;
extern crate rustc_apfloat;
#[macro_use] extern crate rustc;
extern crate rustc_data_structures;
extern crate rustc_mir;
extern crate rustc_target;

mod fn_call;
mod operator;
mod intrinsic;
mod helpers;
mod tls;
mod range_map;
mod mono_hash_map;
mod stacked_borrows;
mod intptrcast;
mod machine;
mod eval;

// Make all those symbols available in the same place as our own.
pub use rustc_mir::interpret::*;
// Resolve ambiguity.
pub use rustc_mir::interpret::{self, AllocMap, PlaceTy};

pub use crate::fn_call::EvalContextExt as MissingFnsEvalContextExt;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::intrinsic::EvalContextExt as IntrinsicEvalContextExt;
pub use crate::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
pub use crate::range_map::RangeMap;
pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item};
pub use crate::machine::{MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt};
pub use crate::eval::{eval_main, create_ecx, MiriConfig};

// Some global facts about the emulated machine.
pub const PAGE_SIZE: u64 = 4*1024;
pub const STACK_ADDR: u64 = 16*PAGE_SIZE; // not really about the "stack", but where we start assigning integer addresses to allocations
pub const NUM_CPUS: u64 = 1;

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub fn miri_default_args() -> &'static [&'static str] {
    // The flags here should be kept in sync with what bootstrap adds when `test-miri` is
    // set, which happens in `bootstrap/bin/rustc.rs` in the rustc sources.
    &["-Zalways-encode-mir", "-Zmir-emit-retag", "-Zmir-opt-level=0", "--cfg=miri"]
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::Read;

const LF: u8 = 10;
const CR: u8 = 13;
const QUOTE: u8 = 34;
const COMMA: u8 = 44;

enum CSVState {
    Start,
    NonQuotedValue,
    NonQuotedQuote,
    QuotedValue,
    QuoteQuote,
    ExpectLF,
    Error,
}

type CSVResult = Result<CSVState, ()>;

#[derive(Debug, PartialEq, Eq)]
pub struct CSVError {
    pub line: i32,
    pub col: i32,
}

fn parse_start(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::QuotedValue),
        COMMA => Ok(CSVState::Start),
        _ => Ok(CSVState::NonQuotedValue)
    }
}

fn parse_non_quoted(byte: u8) -> CSVResult {
    match byte {
        COMMA => Ok(CSVState::Start),
        CR    => Ok(CSVState::ExpectLF),
        LF    => Ok(CSVState::Start),
        QUOTE => Ok(CSVState::NonQuotedQuote),
        _     => Ok(CSVState::NonQuotedValue),
    }
}

fn parse_non_quoted_quote(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::NonQuotedValue),
        COMMA => Err(()),
        CR    => Err(()),
        LF    => Err(()),
        _     => Ok(CSVState::NonQuotedQuote),
    }
}

fn parse_quoted(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::QuoteQuote),
        CR    => Err(()),
        LF    => Err(()),
        _     => Ok(CSVState::QuotedValue),
    }
}

fn parse_quote_quote(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::QuotedValue),
        COMMA => Ok(CSVState::Start),
        CR    => Ok(CSVState::ExpectLF),
        LF    => Ok(CSVState::Start),
        _     => Err(()),
    }
}

fn parse_cr(byte: u8) -> CSVResult {
    match byte {
        LF => Ok(CSVState::Start),
        _  => Err(()),
    }
}

fn parse_err(byte: u8) -> CSVResult {
    match byte {
        LF => Ok(CSVState::Start),
        _  => Ok(CSVState::Error),
    }
}

fn next_state(state: CSVState, b: u8) -> CSVResult {
    match state {
        CSVState::Start          => parse_start(b),
        CSVState::NonQuotedValue => parse_non_quoted(b),
        CSVState::NonQuotedQuote => parse_non_quoted_quote(b),
        CSVState::QuotedValue    => parse_quoted(b),
        CSVState::QuoteQuote     => parse_quote_quote(b),
        CSVState::ExpectLF       => parse_cr(b),
        CSVState::Error          => parse_err(b),
    }
}

pub fn errors_for_csv(file: File) -> Vec<CSVError> {
    let mut state = CSVState::Start;
    let mut line = 1;
    let mut col = 0;

    let mut errors: Vec<CSVError> = Vec::new();

    for byte in file.bytes() {
        let b = byte.unwrap();

        state = match next_state(state, b) {
            Ok(new_state) => new_state,
            Err(_)        => {
                errors.push(CSVError { line: line, col: col });
                CSVState::Error
            },
        };

        if b == LF {
            line = line + 1;
            col = 0;
        } else {
            col = col + 1;
        }
    }

    errors
}
<commit_msg>Let byte be the byte and b be the wrapper<commit_after>use std::fs::File;
use std::io::Read;

const LF: u8 = 10;
const CR: u8 = 13;
const QUOTE: u8 = 34;
const COMMA: u8 = 44;

enum CSVState {
    Start,
    NonQuotedValue,
    NonQuotedQuote,
    QuotedValue,
    QuoteQuote,
    ExpectLF,
    Error,
}

type CSVResult = Result<CSVState, ()>;

#[derive(Debug, PartialEq, Eq)]
pub struct CSVError {
    pub line: i32,
    pub col: i32,
}

fn parse_start(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::QuotedValue),
        COMMA => Ok(CSVState::Start),
        _ => Ok(CSVState::NonQuotedValue)
    }
}

fn parse_non_quoted(byte: u8) -> CSVResult {
    match byte {
        COMMA => Ok(CSVState::Start),
        CR    => Ok(CSVState::ExpectLF),
        LF    => Ok(CSVState::Start),
        QUOTE => Ok(CSVState::NonQuotedQuote),
        _     => Ok(CSVState::NonQuotedValue),
    }
}

fn parse_non_quoted_quote(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::NonQuotedValue),
        COMMA => Err(()),
        CR    => Err(()),
        LF    => Err(()),
        _     => Ok(CSVState::NonQuotedQuote),
    }
}

fn parse_quoted(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::QuoteQuote),
        CR    => Err(()),
        LF    => Err(()),
        _     => Ok(CSVState::QuotedValue),
    }
}

fn parse_quote_quote(byte: u8) -> CSVResult {
    match byte {
        QUOTE => Ok(CSVState::QuotedValue),
        COMMA => Ok(CSVState::Start),
        CR    => Ok(CSVState::ExpectLF),
        LF    => Ok(CSVState::Start),
        _     => Err(()),
    }
}

fn parse_cr(byte: u8) -> CSVResult {
    match byte {
        LF => Ok(CSVState::Start),
        _  => Err(()),
    }
}

fn parse_err(byte: u8) -> CSVResult {
    match byte {
        LF => Ok(CSVState::Start),
        _  => Ok(CSVState::Error),
    }
}

fn next_state(state: CSVState, byte: u8) -> CSVResult {
    match state {
        CSVState::Start          => parse_start(byte),
        CSVState::NonQuotedValue => parse_non_quoted(byte),
        CSVState::NonQuotedQuote => parse_non_quoted_quote(byte),
        CSVState::QuotedValue    => parse_quoted(byte),
        CSVState::QuoteQuote     => parse_quote_quote(byte),
        CSVState::ExpectLF       => parse_cr(byte),
        CSVState::Error          => parse_err(byte),
    }
}

pub fn errors_for_csv(file: File) -> Vec<CSVError> {
    let mut state = CSVState::Start;
    let mut line = 1;
    let mut col = 0;

    let mut errors: Vec<CSVError> = Vec::new();

    for b in file.bytes() {
        let byte = b.unwrap();

        state = match next_state(state, byte) {
            Ok(new_state) => new_state,
            Err(_)        => {
                errors.push(CSVError { line: line, col: col });
                CSVState::Error
            },
        };

        if byte == LF {
            line = line + 1;
            col = 0;
        } else {
            col = col + 1;
        }
    }

    errors
}
<|endoftext|>


<commit_before>//! # Tick
//!
//! An implementation of Transports, Protocols, and Streams over mio.
//!
//! # Example
//!
//! ```rust
//! use tick::{Tick, Protocol, Transfer};
//!
//! struct Echo(Transfer);
//! impl Protocol<Tcp> for Echo {
//!     fn on_data(&mut self, data: &[u8]) {
//!         println!("data received: {:?}", data);
//!         self.0.write(data);
//!     }
//! }
//!
//! let mut tick = Tick::new(Echo);
//! tick.accept(listener);
//! tick.run();
//! ```

#![cfg_attr(test, deny(warnings))]
#![cfg_attr(test, deny(missing_docs))]

#[macro_use] extern crate log;
extern crate mio;
extern crate slab;

pub use tick::{Tick, Notify};
pub use protocol::Protocol;
pub use transfer::Transfer;
pub use transport::Transport;

mod handler;
mod protocol;
mod stream;
mod tick;
mod transfer;
mod transport;

#[derive(Clone, PartialEq, Debug)]
enum Action {
    Wait,
    Register(mio::EventSet),
    Queued,
    Remove,
}

#[derive(Clone, PartialEq)]
enum Queued {
    Resume,
    Pause,
    Write(Option<Vec<u8>>),
    Close,
}

impl ::std::fmt::Debug for Queued {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match *self {
            Queued::Resume => f.write_str("Queued::Resume"),
            Queued::Pause => f.write_str("Queued::Pause"),
            Queued::Write(Some(ref data)) => write!(f, "Queued::Write(Bytes({}))", data.len()),
            Queued::Write(None) => f.write_str("Queued::Write(Eof)"),
            Queued::Close => f.write_str("Queued::Close"),
        }
    }
}

enum Message {
    Timeout(Box<FnMut() + Send + 'static>, u64),
    Action(mio::Token, Action),
    Shutdown,
}

#[derive(Debug)]
pub enum Error {
    TooManySockets,
    Timeout,
    Io(::std::io::Error)
}

impl From<::std::io::Error> for Error {
    fn from(e: ::std::io::Error) -> Error {
        Error::Io(e)
    }
}

pub type Result<T> = std::result::Result<T, Error>;

/// Opaque ID returned when adding listeners and streams to the loop.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id(::mio::Token);

impl ::std::fmt::Debug for Id {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        f.debug_tuple("Id")
            .field(&(self.0).0)
            .finish()
    }
}

impl slab::Index for Id {
    fn from_usize(i: usize) -> Id {
        Id(::mio::Token(i))
    }

    fn as_usize(&self) -> usize {
        (self.0).0
    }
}
<commit_msg>add reexport of Slab<commit_after>//! # Tick
//!
//! An implementation of Transports, Protocols, and Streams over mio.
//!
//! # Example
//!
//! ```rust
//! use tick::{Tick, Protocol, Transfer};
//!
//! struct Echo(Transfer);
//! impl Protocol<Tcp> for Echo {
//!     fn on_data(&mut self, data: &[u8]) {
//!         println!("data received: {:?}", data);
//!         self.0.write(data);
//!     }
//! }
//!
//! let mut tick = Tick::new(Echo);
//! tick.accept(listener);
//! tick.run();
//! ```

#![cfg_attr(test, deny(warnings))]
#![cfg_attr(test, deny(missing_docs))]

#[macro_use] extern crate log;
extern crate mio;
extern crate slab;

pub use tick::{Tick, Notify};
pub use protocol::Protocol;
pub use transfer::Transfer;
pub use transport::Transport;

mod handler;
mod protocol;
mod stream;
mod tick;
mod transfer;
mod transport;

#[derive(Clone, PartialEq, Debug)]
enum Action {
    Wait,
    Register(mio::EventSet),
    Queued,
    Remove,
}

#[derive(Clone, PartialEq)]
enum Queued {
    Resume,
    Pause,
    Write(Option<Vec<u8>>),
    Close,
}

impl ::std::fmt::Debug for Queued {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match *self {
            Queued::Resume => f.write_str("Queued::Resume"),
            Queued::Pause => f.write_str("Queued::Pause"),
            Queued::Write(Some(ref data)) => write!(f, "Queued::Write(Bytes({}))", data.len()),
            Queued::Write(None) => f.write_str("Queued::Write(Eof)"),
            Queued::Close => f.write_str("Queued::Close"),
        }
    }
}

enum Message {
    Timeout(Box<FnMut() + Send + 'static>, u64),
    Action(mio::Token, Action),
    Shutdown,
}

#[derive(Debug)]
pub enum Error {
    TooManySockets,
    Timeout,
    Io(::std::io::Error)
}

impl From<::std::io::Error> for Error {
    fn from(e: ::std::io::Error) -> Error {
        Error::Io(e)
    }
}

pub type Result<T> = std::result::Result<T, Error>;

/// Opaque ID returned when adding listeners and streams to the loop.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id(::mio::Token);

impl ::std::fmt::Debug for Id {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        f.debug_tuple("Id")
            .field(&(self.0).0)
            .finish()
    }
}

impl slab::Index for Id {
    fn from_usize(i: usize) -> Id {
        Id(::mio::Token(i))
    }

    fn as_usize(&self) -> usize {
        (self.0).0
    }
}

pub type Slab<T> = slab::Slab<T, Id>;
<|endoftext|>


<commit_before>#[macro_use]
extern crate exonum;
#[macro_use]
extern crate log;

extern crate serde;

use std::fmt;

use serde::{Serialize, Serializer};

use exonum::blockchain::{Service, Transaction, Schema, NodeState};
use exonum::crypto::{PublicKey, Hash, HexValue};
use exonum::messages::{RawMessage, Message, FromRaw, RawTransaction, Error as MessageError};
use exonum::storage::{MerkleTable, MemoryDB, Map, List, View, MapTable, MerklePatriciaTable,
                      Result as StorageResult};

pub const CONFIG_SERVICE: u16 = 1;
pub const CONFIG_PROPOSE_MESSAGE_ID: u16 = 0;
pub const CONFIG_VOTE_MESSAGE_ID: u16 = 1;

message! {
    TxConfigPropose {
        const TYPE = CONFIG_SERVICE;
        const ID = CONFIG_PROPOSE_MESSAGE_ID;
        const SIZE = 56;

        from:           &PublicKey  [00 => 32]
        height:         u64         [32 => 40]
        config:        &[u8]        [40 => 48] // serialized config bytes
        actual_from_height: u64     [48 => 56] // с какой высоты становится актуальным
    }
}

message! {
    TxConfigVote {
        const TYPE = CONFIG_SERVICE;
        const ID = CONFIG_VOTE_MESSAGE_ID;
        const SIZE = 81;

        from:           &PublicKey  [00 => 32]
        height:         u64         [32 => 40]
        hash_propose:   &Hash       [40 => 72] // hash of transacion we're voting for
        seed:           u64         [72 => 80] // incremental (1, 2, 3, 4, 5, 6, 7) проверять +1
        revoke:         bool        [80 => 81] // голос_за=false / отозвать=true
    }
}

#[derive(Clone, PartialEq)]
pub enum ConfigTx {
    ConfigPropose(TxConfigPropose),
    ConfigVote(TxConfigVote),
}

impl Serialize for TxConfigPropose {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let mut state;
        state = ser.serialize_struct("config_propose", 4)?;
        ser.serialize_struct_elt(&mut state, "from", self.from().to_hex())?;
        ser.serialize_struct_elt(&mut state, "height", self.height())?;
        ser.serialize_struct_elt(&mut state, "config", self.config())?;
        ser.serialize_struct_elt(&mut state, "actual_from_height", self.actual_from_height())?;
        ser.serialize_struct_end(state)
    }
}

impl Serialize for TxConfigVote {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let mut state;
        state = ser.serialize_struct("vote", 5)?;
        ser.serialize_struct_elt(&mut state, "from", self.from().to_hex())?;
        ser.serialize_struct_elt(&mut state, "height", self.height())?;
        ser.serialize_struct_elt(&mut state, "hash_propose", self.hash_propose().to_hex())?;
        ser.serialize_struct_elt(&mut state, "seed", self.seed())?;
        ser.serialize_struct_elt(&mut state, "revoke", self.revoke())?;
        ser.serialize_struct_end(state)
    }
}

impl Serialize for ConfigTx {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        match *self {
            ConfigTx::ConfigPropose(ref propose) => propose.serialize(ser),
            ConfigTx::ConfigVote(ref vote) => vote.serialize(ser),
        }
    }
}

#[derive(Default)]
pub struct ConfigurationService {}

pub struct ConfigurationSchema<'a> {
    view: &'a View,
}

impl ConfigTx {
    pub fn from(&self) -> &PublicKey {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.from(),
            ConfigTx::ConfigVote(ref msg) => msg.from(),
        }
    }

    pub fn height(&self) -> u64 {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.height(),
            ConfigTx::ConfigVote(ref msg) => msg.height(),
        }
    }
}

impl fmt::Debug for ConfigTx {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => write!(fmt, "{:?}", msg),
            ConfigTx::ConfigVote(ref msg) => write!(fmt, "{:?}", msg),
        }
    }
}

impl FromRaw for ConfigTx {
    fn from_raw(raw: RawMessage) -> Result<ConfigTx, MessageError> {
        match raw.message_type() {
            CONFIG_PROPOSE_MESSAGE_ID => {
                Ok(ConfigTx::ConfigPropose(TxConfigPropose::from_raw(raw)?))
            }
            CONFIG_VOTE_MESSAGE_ID => Ok(ConfigTx::ConfigVote(TxConfigVote::from_raw(raw)?)),
            _ => Err(MessageError::IncorrectMessageType { message_type: raw.message_type() }),
        }
    }
}

impl Message for ConfigTx {
    fn raw(&self) -> &RawMessage {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.raw(),
            ConfigTx::ConfigVote(ref msg) => msg.raw(),
        }
    }

    fn verify_signature(&self, public_key: &PublicKey) -> bool {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.verify_signature(public_key),
            ConfigTx::ConfigVote(ref msg) => msg.verify_signature(public_key),
        }
    }

    fn hash(&self) -> Hash {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.hash(),
            ConfigTx::ConfigVote(ref msg) => msg.hash(),
        }
    }
}

impl<'a> ConfigurationSchema<'a> {
    pub fn new(view: &'a View) -> ConfigurationSchema {
        ConfigurationSchema { view: view }
    }

    fn config_proposes
        (&self)
         -> MerklePatriciaTable<MapTable<View, [u8], Vec<u8>>, Hash, TxConfigPropose> {
        // config_propose paricia merkletree <hash_tx> транзакция пропоз
        MerklePatriciaTable::new(MapTable::new(vec![04], self.view))
    }

    fn config_votes
        (&self)
         -> MerklePatriciaTable<MapTable<View, [u8], Vec<u8>>, PublicKey, TxConfigVote> {
        // config_votes patricia merkletree <pub_key> последний голос
        MerklePatriciaTable::new(MapTable::new(vec![05], self.view))
    }

    pub fn state_hash(&self) -> StorageResult<Hash> {
        let db = MemoryDB::new();
        let hashes: MerkleTable<MemoryDB, u64, Hash> = MerkleTable::new(db);

        hashes.append(self.config_proposes().root_hash()?)?;
        hashes.append(self.config_votes().root_hash()?)?;
        hashes.root_hash()
    }
    pub fn get_config_propose(&self,
                              hash: &Hash)
                              -> Result<Option<TxConfigPropose>, exonum::storage::Error> {
        self.config_proposes().get(hash)
    }

    pub fn get_vote(&self,
                    pub_key: &PublicKey)
                    -> Result<Option<TxConfigVote>, exonum::storage::Error> {
        self.config_votes().get(pub_key)
    }
}

impl TxConfigPropose {
    fn execute(&self, view: &View) -> StorageResult<()> {
        let blockchain_schema = Schema::new(view);
        let config_schema = ConfigurationSchema::new(view);

        let config = blockchain_schema.get_actual_configuration()?;
        if !config.validators.contains(self.from()) {
            error!("ConfigPropose from unknown validator: {:?}", self.from());
            return Ok(());
        }

        let hash = self.hash();
        if config_schema.config_proposes().get(&hash)?.is_some() {
            error!("Received config_propose has already been handled, msg={:?}",
                   self);
            return Ok(());
        }

        trace!("Handle ConfigPropose");
        config_schema.config_proposes().put(&hash, self.clone())?;
        Ok(())
    }
}

impl TxConfigVote {
    fn execute(&self, view: &View) -> StorageResult<()> {
        let blockchain_schema = Schema::new(view);
        let config_schema = ConfigurationSchema::new(view);

        let config = blockchain_schema.get_actual_configuration()?;

        if !config.validators.contains(self.from()) {
            error!("ConfigVote from unknown validator: {:?}", self.from());
            return Ok(());
        }

        if config_schema.config_proposes().get(self.hash_propose())?.is_none() {
            error!("Received config_vote for unknown transaciton, msg={:?}",
                   self);
            return Ok(());
        }

        if let Some(vote) = config_schema.config_votes().get(self.from())? {
            if vote.seed() != self.seed() - 1 {
                error!("Received config_vote with wrong seed, msg={:?}", self);
                return Ok(());
            }
        }

        let msg = self.clone();
        config_schema.config_votes().put(msg.from(), self.clone())?;

        let mut votes_count = 0;
        for pub_key in config.validators.clone() {
            if let Some(vote) = config_schema.config_votes().get(&pub_key)? {
                if !vote.revoke() {
                    votes_count += 1;
                }
            }
        }

        if votes_count > 2 / 3 * config.validators.len() {
            if let Some(config_propose) =
                config_schema.config_proposes()
                    .get(self.hash_propose())? {
                blockchain_schema.commit_actual_configuration(config_propose.actual_from_height(),
                                                 config_propose.config())?;
            }
        }
        Ok(())
    }
}

impl Transaction for ConfigTx {
    fn verify(&self) -> bool {
        self.verify_signature(self.from())
    }

    fn execute(&self, view: &View) -> StorageResult<()> {
        match *self {
            ConfigTx::ConfigPropose(ref tx) => tx.execute(view),
            ConfigTx::ConfigVote(ref tx) => tx.execute(view),
        }
    }
}

impl ConfigurationService {
    pub fn new() -> ConfigurationService {
        ConfigurationService {}
    }
}

impl Service for ConfigurationService {
    fn service_id(&self) -> u16 {
        CONFIG_SERVICE
    }

    fn state_hash(&self, view: &View) -> Option<StorageResult<Hash>> {
        let schema = ConfigurationSchema::new(view);
        Some(schema.state_hash())
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError> {
        ConfigTx::from_raw(raw).map(|tx| Box::new(tx) as Box<Transaction>)
    }

    fn handle_commit(&self, state: &mut NodeState) -> StorageResult<()> {
        let actual_config = {
            let schema = Schema::new(state.view());
            let height = state.height();
            schema.get_configuration_at_height(height)?
        };

        if let Some(config) = actual_config {
            info!("Updated node config={:#?}", config);
            state.update_config(config);
        }
        Ok(())
    }
}<commit_msg>Implemented aggregation of sevice tables root hashes into block's state hash. Changed <Hash as StorageValue>::hash() to hash(Hash_byte_array) instead of noop, so that there's no special case to handle on client.<commit_after>#[macro_use]
extern crate exonum;
#[macro_use]
extern crate log;

extern crate serde;

use std::fmt;

use serde::{Serialize, Serializer};

use exonum::blockchain::{Service, Transaction, Schema, NodeState};
use exonum::crypto::{PublicKey, Hash, HexValue};
use exonum::messages::{RawMessage, Message, FromRaw, RawTransaction, Error as MessageError};
use exonum::storage::{MerkleTable, MemoryDB, Map, List, View, MapTable, MerklePatriciaTable,
                      Result as StorageResult};

pub const CONFIG_SERVICE: u16 = 1;
pub const CONFIG_PROPOSE_MESSAGE_ID: u16 = 0;
pub const CONFIG_VOTE_MESSAGE_ID: u16 = 1;

message! {
    TxConfigPropose {
        const TYPE = CONFIG_SERVICE;
        const ID = CONFIG_PROPOSE_MESSAGE_ID;
        const SIZE = 56;

        from:           &PublicKey  [00 => 32]
        height:         u64         [32 => 40]
        config:        &[u8]        [40 => 48] // serialized config bytes
        actual_from_height: u64     [48 => 56] // с какой высоты становится актуальным
    }
}

message! {
    TxConfigVote {
        const TYPE = CONFIG_SERVICE;
        const ID = CONFIG_VOTE_MESSAGE_ID;
        const SIZE = 81;

        from:           &PublicKey  [00 => 32]
        height:         u64         [32 => 40]
        hash_propose:   &Hash       [40 => 72] // hash of transacion we're voting for
        seed:           u64         [72 => 80] // incremental (1, 2, 3, 4, 5, 6, 7) проверять +1
        revoke:         bool        [80 => 81] // голос_за=false / отозвать=true
    }
}

#[derive(Clone, PartialEq)]
pub enum ConfigTx {
    ConfigPropose(TxConfigPropose),
    ConfigVote(TxConfigVote),
}

impl Serialize for TxConfigPropose {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let mut state;
        state = ser.serialize_struct("config_propose", 4)?;
        ser.serialize_struct_elt(&mut state, "from", self.from().to_hex())?;
        ser.serialize_struct_elt(&mut state, "height", self.height())?;
        ser.serialize_struct_elt(&mut state, "config", self.config())?;
        ser.serialize_struct_elt(&mut state, "actual_from_height", self.actual_from_height())?;
        ser.serialize_struct_end(state)
    }
}

impl Serialize for TxConfigVote {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let mut state;
        state = ser.serialize_struct("vote", 5)?;
        ser.serialize_struct_elt(&mut state, "from", self.from().to_hex())?;
        ser.serialize_struct_elt(&mut state, "height", self.height())?;
        ser.serialize_struct_elt(&mut state, "hash_propose", self.hash_propose().to_hex())?;
        ser.serialize_struct_elt(&mut state, "seed", self.seed())?;
        ser.serialize_struct_elt(&mut state, "revoke", self.revoke())?;
        ser.serialize_struct_end(state)
    }
}

impl Serialize for ConfigTx {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        match *self {
            ConfigTx::ConfigPropose(ref propose) => propose.serialize(ser),
            ConfigTx::ConfigVote(ref vote) => vote.serialize(ser),
        }
    }
}

#[derive(Default)]
pub struct ConfigurationService {}

pub struct ConfigurationSchema<'a> {
    view: &'a View,
}

impl ConfigTx {
    pub fn from(&self) -> &PublicKey {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.from(),
            ConfigTx::ConfigVote(ref msg) => msg.from(),
        }
    }

    pub fn height(&self) -> u64 {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.height(),
            ConfigTx::ConfigVote(ref msg) => msg.height(),
        }
    }
}

impl fmt::Debug for ConfigTx {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => write!(fmt, "{:?}", msg),
            ConfigTx::ConfigVote(ref msg) => write!(fmt, "{:?}", msg),
        }
    }
}

impl FromRaw for ConfigTx {
    fn from_raw(raw: RawMessage) -> Result<ConfigTx, MessageError> {
        match raw.message_type() {
            CONFIG_PROPOSE_MESSAGE_ID => {
                Ok(ConfigTx::ConfigPropose(TxConfigPropose::from_raw(raw)?))
            }
            CONFIG_VOTE_MESSAGE_ID => Ok(ConfigTx::ConfigVote(TxConfigVote::from_raw(raw)?)),
            _ => Err(MessageError::IncorrectMessageType { message_type: raw.message_type() }),
        }
    }
}

impl Message for ConfigTx {
    fn raw(&self) -> &RawMessage {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.raw(),
            ConfigTx::ConfigVote(ref msg) => msg.raw(),
        }
    }

    fn verify_signature(&self, public_key: &PublicKey) -> bool {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.verify_signature(public_key),
            ConfigTx::ConfigVote(ref msg) => msg.verify_signature(public_key),
        }
    }

    fn hash(&self) -> Hash {
        match *self {
            ConfigTx::ConfigPropose(ref msg) => msg.hash(),
            ConfigTx::ConfigVote(ref msg) => msg.hash(),
        }
    }
}

impl<'a> ConfigurationSchema<'a> {
    pub fn new(view: &'a View) -> ConfigurationSchema {
        ConfigurationSchema { view: view }
    }

    fn config_proposes
        (&self)
         -> MerklePatriciaTable<MapTable<View, [u8], Vec<u8>>, Hash, TxConfigPropose> {
        // config_propose paricia merkletree <hash_tx> транзакция пропоз
        MerklePatriciaTable::new(MapTable::new(vec![04], self.view))
    }

    fn config_votes
        (&self)
         -> MerklePatriciaTable<MapTable<View, [u8], Vec<u8>>, PublicKey, TxConfigVote> {
        // config_votes patricia merkletree <pub_key> последний голос
        MerklePatriciaTable::new(MapTable::new(vec![05], self.view))
    }

    pub fn state_hash(&self) -> StorageResult<Vec<Hash>> {
        Ok(vec![self.config_proposes().root_hash()?, self.config_votes().root_hash()?])
    }

    pub fn get_config_propose(&self,
                              hash: &Hash)
                              -> Result<Option<TxConfigPropose>, exonum::storage::Error> {
        self.config_proposes().get(hash)
    }

    pub fn get_vote(&self,
                    pub_key: &PublicKey)
                    -> Result<Option<TxConfigVote>, exonum::storage::Error> {
        self.config_votes().get(pub_key)
    }
}

impl TxConfigPropose {
    fn execute(&self, view: &View) -> StorageResult<()> {
        let blockchain_schema = Schema::new(view);
        let config_schema = ConfigurationSchema::new(view);

        let config = blockchain_schema.get_actual_configuration()?;
        if !config.validators.contains(self.from()) {
            error!("ConfigPropose from unknown validator: {:?}", self.from());
            return Ok(());
        }

        let hash = self.hash();
        if config_schema.config_proposes().get(&hash)?.is_some() {
            error!("Received config_propose has already been handled, msg={:?}",
                   self);
            return Ok(());
        }

        trace!("Handle ConfigPropose");
        config_schema.config_proposes().put(&hash, self.clone())?;
        Ok(())
    }
}

impl TxConfigVote {
    fn execute(&self, view: &View) -> StorageResult<()> {
        let blockchain_schema = Schema::new(view);
        let config_schema = ConfigurationSchema::new(view);

        let config = blockchain_schema.get_actual_configuration()?;

        if !config.validators.contains(self.from()) {
            error!("ConfigVote from unknown validator: {:?}", self.from());
            return Ok(());
        }

        if config_schema.config_proposes().get(self.hash_propose())?.is_none() {
            error!("Received config_vote for unknown transaciton, msg={:?}",
                   self);
            return Ok(());
        }

        if let Some(vote) = config_schema.config_votes().get(self.from())? {
            if vote.seed() != self.seed() - 1 {
                error!("Received config_vote with wrong seed, msg={:?}", self);
                return Ok(());
            }
        }

        let msg = self.clone();
        config_schema.config_votes().put(msg.from(), self.clone())?;

        let mut votes_count = 0;
        for pub_key in config.validators.clone() {
            if let Some(vote) = config_schema.config_votes().get(&pub_key)? {
                if !vote.revoke() {
                    votes_count += 1;
                }
            }
        }

        if votes_count > 2 / 3 * config.validators.len() {
            if let Some(config_propose) =
                config_schema.config_proposes()
                    .get(self.hash_propose())? {
                blockchain_schema.commit_actual_configuration(config_propose.actual_from_height(),
                                                 config_propose.config())?;
            }
        }
        Ok(())
    }
}

impl Transaction for ConfigTx {
    fn verify(&self) -> bool {
        self.verify_signature(self.from())
    }

    fn execute(&self, view: &View) -> StorageResult<()> {
        match *self {
            ConfigTx::ConfigPropose(ref tx) => tx.execute(view),
            ConfigTx::ConfigVote(ref tx) => tx.execute(view),
        }
    }
}

impl ConfigurationService {
    pub fn new() -> ConfigurationService {
        ConfigurationService {}
    }
}

impl Service for ConfigurationService {
    fn service_id(&self) -> u16 {
        CONFIG_SERVICE
    }

    fn state_hash(&self, view: &View) -> StorageResult<Vec<Hash>> {
        let schema = ConfigurationSchema::new(view);
        schema.state_hash()
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError> {
        ConfigTx::from_raw(raw).map(|tx| Box::new(tx) as Box<Transaction>)
    }

    fn handle_commit(&self, state: &mut NodeState) -> StorageResult<()> {
        let actual_config = {
            let schema = Schema::new(state.view());
            let height = state.height();
            schema.get_configuration_at_height(height)?
        };

        if let Some(config) = actual_config {
            info!("Updated node config={:#?}", config);
            state.update_config(config);
        }
        Ok(())
    }
}<|endoftext|>


<commit_before>extern crate prettytable;
use prettytable::Table;
use prettytable::row::Row;
use prettytable::cell::Cell;

use std::ops::{Index, IndexMut};
use self::Direction::{Down, Left, Right, Up};
use self::Error::*;

#[cfg(test)]
mod test;
// Possible directions for cycle
#[derive(Clone,Copy,PartialEq,Debug)]
enum Direction {
    Up,
    Down,
    Left,
    Right,
    None,
}
// The structure for emulation a two-dimensional array
struct Matrix<T> {
    cols: usize,
    data: Vec<T>,
}

impl<T> Index<usize> for Matrix<T> {
    type Output = [T];

    #[inline]
    fn index(&self, index: usize) -> &Self::Output {
        let i = index * self.cols;
        &self.data[i..i + self.cols]
    }
}

impl<T> IndexMut<usize> for Matrix<T> {
    #[inline]
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        let i = index * self.cols;
        &mut self.data[i..i + self.cols]
    }
}

impl<T> Matrix<T> {
    fn new(columns: usize) -> Matrix<T> {
        Matrix {
            cols: columns,
            data: Vec::new(),
        }
    }
    // Add a line to the matrix
    fn push(&mut self, mut vector: Vec<T>) {
        assert_eq!(self.cols, vector.len());
        self.data.append(&mut vector);
    }
    // The number of rows in the matrix
    fn rows(&self) -> usize {
        self.data.len() / self.cols
    }
    // The number of columns in the matrix
    fn cols(&self) -> usize {
        self.cols
    }
}

impl Matrix<Direction> {
    fn iter<'a>(&'a self, i: usize, j: usize) -> MatrixIter<'a> {
        MatrixIter {
            state: self,
            start_i: i,
            start_j: j,
            i: i,
            j: j,
            f: false,
        }
    }
}

struct MatrixIter<'a> {
    state: &'a Matrix<Direction>,
    start_i: usize,
    start_j: usize,
    i: usize,
    j: usize,
    f: bool,
}

impl<'a> MatrixIter<'a> {
    fn move_by(&mut self, d: Direction) {
        match d {
            Up => self.i += 1,
            Down => self.i -= 1,
            Left => self.j += 1,
            Right => self.j -= 1,
            Direction::None => unreachable!(),
        }
    }
}

impl<'a> Iterator for MatrixIter<'a> {
    type Item = (usize,usize);
    fn next(&mut self) -> Option<Self::Item> {
        if self.i == self.start_i && self.j == self.start_j {
            if self.f {
                return None;
            }
            self.f = true;
        }

        let buf = (self.i, self.j);
        let d = self.state[self.i][self.j];
        while self.state[self.i][self.j] == d || self.state[self.i][self.j] == Direction::None {
            self.move_by(d);
        }
        Some(buf)
    }
}

// Initialization errors
#[derive(Debug)]
pub enum Error {
    NumOfSupOrCust,
    NumOfRows,
    NumOfCols,
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        use std::error::Error;
        f.write_str(self.description())
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            NumOfSupOrCust => "invalid number of suppliers or customers",
            NumOfRows => "invalid number of rows in the matrix of costs",
            NumOfCols => "invalid number of columns in the matrix of costs",
        }
    }
}

// The main structure
pub struct Transportation {
    supply: Vec<u64>,
    demand: Vec<u64>,
    cost: Matrix<u64>,
    trans: Matrix<Option<u64>>,
}

impl Transportation {
    fn least_cost_method(&mut self) {
        let mut a = self.supply.to_vec();
        let mut b = self.demand.to_vec();
        let mut min;

        loop {
            min = None;

            for i in 0..self.cost.rows() {
                if a[i] == 0 {
                    continue;
                }
                for j in 0..self.cost.cols() {
                    if b[j] == 0 {
                        continue;
                    }
                    if let Some((_, _, v)) = min {
                        if v > self.cost[i][j] {
                            min = Some((i, j, self.cost[i][j]));
                        }
                    } else {
                        min = Some((i, j, self.cost[i][j]));
                    }
                }
            }

            if let Some((i, j, _)) = min {
                if a[i] >= b[j] {
                    self.trans[i][j] = Some(b[j]);
                    a[i] -= b[j];
                    b[j] = 0;
                } else {
                    self.trans[i][j] = Some(a[i]);
                    b[j] -= a[i];
                    a[i] = 0;
                }
            } else {
                return;
            }
        }
    }
    // Detect cycle via dfs and build a matrix of directions
    // If the direction of the trans_state[i][j] isn't None, the cycle is found
    fn cycle_detection(&self, i: usize, j: usize) -> Matrix<Direction> {
        let mut trans_state = Matrix::new(self.trans.cols());
        for _ in 0..self.trans.rows() {
            trans_state.push(vec![Direction::None;self.trans.cols()]);
        }

        fn _cycle_detection(x: &Matrix<Option<u64>>, x_state: &mut Matrix<Direction>, i: usize, j: usize) {
            if x_state[i][j] != Down {
                for k in (0..i).rev() {
                    if x[k][j] != None {
                        if x_state[k][j] == Direction::None {
                            x_state[k][j] = Up;
                            _cycle_detection(x, x_state, k, j);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
            if x_state[i][j] != Up {
                for k in i + 1..x.rows() {
                    if x[k][j] != None {
                        if x_state[k][j] == Direction::None {
                            x_state[k][j] = Down;
                            _cycle_detection(x, x_state, k, j);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
            if x_state[i][j] != Right {
                for k in (0..j).rev() {
                    if x[i][k] != None {
                        if x_state[i][k] == Direction::None {
                            x_state[i][k] = Left;
                            _cycle_detection(x, x_state, i, k);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
            if x_state[i][j] != Left {
                for k in j + 1..x.cols() {
                    if x[i][k] != None {
                        if x_state[i][k] == Direction::None {
                            x_state[i][k] = Right;
                            _cycle_detection(x, x_state, i, k);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
        }

        _cycle_detection(&self.trans, &mut trans_state, i, j);

        trans_state
    }
    // If the number of basic cells in the transportation plan is less then
    // m + n - 1, it must be replenished
    fn replenish(&mut self) {
        let number = self.trans.data.iter().filter(|&&a| a != None).count();

        if number < self.trans.rows() + self.trans.cols() - 1 {
            for i in 0..self.trans.rows() {
                for j in 0..self.trans.cols() {
                    if self.trans[i][j] == None {
                        self.trans[i][j] = Some(0);
                        if self.cycle_detection(i, j)[i][j] != Direction::None {
                            self.trans[i][j] = None;
                        } else {
                            return;
                        }
                    }
                }
            }
        }
    }
    // Recursive calculation of potentials
    fn calculation_of_potentials(&self) -> (Vec<i64>, Vec<i64>) {
        let mut u = vec![0;self.trans.rows()];
        let mut v = vec![0;self.trans.cols()];

        fn calculation_of_potentials_h(c: &Matrix<u64>, x: &Matrix<Option<u64>>, u: &mut [i64], v: &mut [i64], i: usize, j: usize) {
            for k in 0..x.cols() {
                if x[i][k] != None {
                    v[k] = c[i][k] as i64 - u[i];
                    if k != j {
                        calculation_of_potentials_v(c, x, u, v, i, k);
                    }
                }
            }
        }

        fn calculation_of_potentials_v(c: &Matrix<u64>, x: &Matrix<Option<u64>>, u: &mut [i64], v: &mut [i64], i: usize, j: usize) {
            for k in 0..x.rows() {
                if x[k][j] != None {
                    u[k] = c[k][j] as i64 - v[j];
                    if k != i {
                        calculation_of_potentials_h(c, x, u, v, k, j);
                    }
                }
            }
        }

        calculation_of_potentials_h(&self.cost, &self.trans, &mut u, &mut v, 0, 0);
        calculation_of_potentials_v(&self.cost, &self.trans, &mut u, &mut v, 0, 0);

        (u, v)
    }
    // Check for optimality
    // If the transportation plan is not optimal, then return the minimum of difference
    fn check(&self) -> Option<(usize, usize, i64)> {
        let mut min = None;
        let (u, v) = self.calculation_of_potentials();

        for i in 0..self.cost.rows() {
            for j in 0..self.cost.cols() {
                let d = self.cost[i][j] as i64 - u[i] - v[j];
                if d < 0 {
                    if let Some((_, _, m)) = min {
                        if m > d {
                            min = Some((i, j, d));
                        }
                    } else {
                        min = Some((i, j, d));
                    }
                }
            }
        }
        min
    }
    // Calculate the total cost
    fn total_cost(&self) -> u64 {
        let mut z = 0;
        for (t, c) in self.trans.data.iter().zip(self.cost.data.iter()) {
            if !t.is_none() {
                z += t.unwrap() * c;
            }
        }
        z
    }

    pub fn potential_method(&mut self) {
        self.least_cost_method();
        self.replenish();

        while let Some((i, j, _)) = self.check() {
            self.trans[i][j] = Some(0);
            let trans_state = self.cycle_detection(i, j);

            let mut min = std::u64::MAX;
            let mut f = true;
            for x in trans_state.iter(i, j) {
                if f {
                    f = false;
                } else {
                    if min > self.trans[x.0][x.1].unwrap() {
                        min = self.trans[x.0][x.1].unwrap();
                    }
                    f = true;
                }
            }

            f = true;
            for x in trans_state.iter(i, j) {
                if f {
                    self.trans[x.0][x.1] = Some(self.trans[x.0][x.1].unwrap() + min);
                    f = false;
                } else {
                    self.trans[x.0][x.1] = Some(self.trans[x.0][x.1].unwrap() - min);
                    f = true;
                }
            }

            let mut max = (0, 0, 0);
            for x in trans_state.iter(i, j) {
                if self.trans[x.0][x.1].unwrap() == 0 && max.2 <= self.cost[x.0][x.1] {
                    max = (x.0, x.1, self.cost[x.0][x.1]);
                }
            }
            self.trans[max.0][max.1] = None;
        }
    }

    pub fn printstd(&self) {
        let mut table = Table::new();
        table.add_row(Row::new(vec![Cell::new("")]));
        for i in 0..self.demand.len() {
            table[0].add_cell(Cell::new(&format!("B{}", i + 1)));
        }
        table[0].add_cell(Cell::new("Запасы"));
        for (i, s) in self.supply.iter().enumerate() {
            table.add_row(Row::new(vec![Cell::new(&format!("A{}", i + 1))]));
            for m in self.trans[i].iter() {
                if m.is_none() {
                    table[i + 1].add_cell(Cell::new("0"));
                } else {
                    table[i + 1].add_cell(Cell::new(&format!("{}", m.unwrap())));
                }
            }
            table[i + 1].add_cell(Cell::new(&format!("{}", s)));
        }
        table.add_row(Row::new(vec![Cell::new("Потребности")]));
        for d in self.demand.iter() {
            table[self.supply.len() + 1].add_cell(Cell::new(&format!("{}", d)));
        }
        table.add_row(Row::new(vec![Cell::new("Общая стоимость"), Cell::new(&format!("{}", self.total_cost()))]));
        table.printstd();
    }

    pub fn new(mut a: Vec<u64>, mut b: Vec<u64>, mut c: Vec<Vec<u64>>) -> Result<Transportation, Error> {
        if a.is_empty() || b.is_empty() {
            return Err(NumOfSupOrCust);
        }
        if a.len() != c.len() {
            return Err(NumOfRows);
        }
        for i in &c {
            if b.len() != i.len() {
                return Err(NumOfCols);
            }
        }

        let sum_s = a.iter().fold(0, std::ops::Add::add); //a.iter().sum();
        let sum_d = b.iter().fold(0, std::ops::Add::add); //b.iter().sum();
        if sum_s > sum_d {
            b.push(sum_s - sum_d);
            for i in &mut c {
                i.push(0);
            }
        }
        if sum_s < sum_d {
            a.push(sum_d - sum_s);
            c.push(vec![0;b.len()]);
        }
        let mut cost = Matrix::new(c[0].len());
        for i in c {
            cost.push(i);
        }

        Ok(Transportation {
            trans: Matrix {
                cols: b.len(),
                data: vec![None;a.len()*b.len()],
            },
            supply: a,
            demand: b,
            cost: cost,
        })
    }
}
<commit_msg>fix comment<commit_after>extern crate prettytable;
use prettytable::Table;
use prettytable::row::Row;
use prettytable::cell::Cell;

use std::ops::{Index, IndexMut};
use self::Direction::{Down, Left, Right, Up};
use self::Error::*;

#[cfg(test)]
mod test;
// Possible directions for cycle
#[derive(Clone,Copy,PartialEq,Debug)]
enum Direction {
    Up,
    Down,
    Left,
    Right,
    None,
}
// The structure for emulation a two-dimensional array
struct Matrix<T> {
    cols: usize,
    data: Vec<T>,
}

impl<T> Index<usize> for Matrix<T> {
    type Output = [T];

    #[inline]
    fn index(&self, index: usize) -> &Self::Output {
        let i = index * self.cols;
        &self.data[i..i + self.cols]
    }
}

impl<T> IndexMut<usize> for Matrix<T> {
    #[inline]
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        let i = index * self.cols;
        &mut self.data[i..i + self.cols]
    }
}

impl<T> Matrix<T> {
    fn new(columns: usize) -> Matrix<T> {
        Matrix {
            cols: columns,
            data: Vec::new(),
        }
    }
    // Add a line to the matrix
    fn push(&mut self, mut vector: Vec<T>) {
        assert_eq!(self.cols, vector.len());
        self.data.append(&mut vector);
    }
    // The number of rows in the matrix
    fn rows(&self) -> usize {
        self.data.len() / self.cols
    }
    // The number of columns in the matrix
    fn cols(&self) -> usize {
        self.cols
    }
}

impl Matrix<Direction> {
    fn iter<'a>(&'a self, i: usize, j: usize) -> MatrixIter<'a> {
        MatrixIter {
            state: self,
            start_i: i,
            start_j: j,
            i: i,
            j: j,
            f: false,
        }
    }
}

struct MatrixIter<'a> {
    state: &'a Matrix<Direction>,
    start_i: usize,
    start_j: usize,
    i: usize,
    j: usize,
    f: bool,
}

impl<'a> MatrixIter<'a> {
    fn move_by(&mut self, d: Direction) {
        match d {
            Up => self.i += 1,
            Down => self.i -= 1,
            Left => self.j += 1,
            Right => self.j -= 1,
            Direction::None => unreachable!(),
        }
    }
}

impl<'a> Iterator for MatrixIter<'a> {
    type Item = (usize,usize);
    fn next(&mut self) -> Option<Self::Item> {
        if self.i == self.start_i && self.j == self.start_j {
            if self.f {
                return None;
            }
            self.f = true;
        }

        let buf = (self.i, self.j);
        let d = self.state[self.i][self.j];
        while self.state[self.i][self.j] == d || self.state[self.i][self.j] == Direction::None {
            self.move_by(d);
        }
        Some(buf)
    }
}

// Initialization errors
#[derive(Debug)]
pub enum Error {
    NumOfSupOrCust,
    NumOfRows,
    NumOfCols,
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        use std::error::Error;
        f.write_str(self.description())
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            NumOfSupOrCust => "invalid number of suppliers or customers",
            NumOfRows => "invalid number of rows in the matrix of costs",
            NumOfCols => "invalid number of columns in the matrix of costs",
        }
    }
}

// The main structure
pub struct Transportation {
    supply: Vec<u64>,
    demand: Vec<u64>,
    cost: Matrix<u64>,
    trans: Matrix<Option<u64>>,
}

impl Transportation {
    fn least_cost_method(&mut self) {
        let mut a = self.supply.to_vec();
        let mut b = self.demand.to_vec();
        let mut min;

        loop {
            min = None;

            for i in 0..self.cost.rows() {
                if a[i] == 0 {
                    continue;
                }
                for j in 0..self.cost.cols() {
                    if b[j] == 0 {
                        continue;
                    }
                    if let Some((_, _, v)) = min {
                        if v > self.cost[i][j] {
                            min = Some((i, j, self.cost[i][j]));
                        }
                    } else {
                        min = Some((i, j, self.cost[i][j]));
                    }
                }
            }

            if let Some((i, j, _)) = min {
                if a[i] >= b[j] {
                    self.trans[i][j] = Some(b[j]);
                    a[i] -= b[j];
                    b[j] = 0;
                } else {
                    self.trans[i][j] = Some(a[i]);
                    b[j] -= a[i];
                    a[i] = 0;
                }
            } else {
                return;
            }
        }
    }
    // Detect cycle via dfs and build a matrix of directions
    // If the direction of the trans_state[i][j] isn't None, the cycle is found
    fn cycle_detection(&self, i: usize, j: usize) -> Matrix<Direction> {
        let mut trans_state = Matrix::new(self.trans.cols());
        for _ in 0..self.trans.rows() {
            trans_state.push(vec![Direction::None;self.trans.cols()]);
        }

        fn _cycle_detection(x: &Matrix<Option<u64>>, x_state: &mut Matrix<Direction>, i: usize, j: usize) {
            if x_state[i][j] != Down {
                for k in (0..i).rev() {
                    if x[k][j] != None {
                        if x_state[k][j] == Direction::None {
                            x_state[k][j] = Up;
                            _cycle_detection(x, x_state, k, j);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
            if x_state[i][j] != Up {
                for k in i + 1..x.rows() {
                    if x[k][j] != None {
                        if x_state[k][j] == Direction::None {
                            x_state[k][j] = Down;
                            _cycle_detection(x, x_state, k, j);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
            if x_state[i][j] != Right {
                for k in (0..j).rev() {
                    if x[i][k] != None {
                        if x_state[i][k] == Direction::None {
                            x_state[i][k] = Left;
                            _cycle_detection(x, x_state, i, k);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
            if x_state[i][j] != Left {
                for k in j + 1..x.cols() {
                    if x[i][k] != None {
                        if x_state[i][k] == Direction::None {
                            x_state[i][k] = Right;
                            _cycle_detection(x, x_state, i, k);
                        } else {
                            return;
                        }
                        break;
                    }
                }
            }
        }

        _cycle_detection(&self.trans, &mut trans_state, i, j);

        trans_state
    }
    // If the number of basic cells in the transportation plan is less then
    // m + n - 1, it needs to replenish
    fn replenish(&mut self) {
        let number = self.trans.data.iter().filter(|&&a| a != None).count();

        if number < self.trans.rows() + self.trans.cols() - 1 {
            for i in 0..self.trans.rows() {
                for j in 0..self.trans.cols() {
                    if self.trans[i][j] == None {
                        self.trans[i][j] = Some(0);
                        if self.cycle_detection(i, j)[i][j] != Direction::None {
                            self.trans[i][j] = None;
                        } else {
                            return;
                        }
                    }
                }
            }
        }
    }
    // Recursive calculation of potentials
    fn calculation_of_potentials(&self) -> (Vec<i64>, Vec<i64>) {
        let mut u = vec![0;self.trans.rows()];
        let mut v = vec![0;self.trans.cols()];

        fn calculation_of_potentials_h(c: &Matrix<u64>, x: &Matrix<Option<u64>>, u: &mut [i64], v: &mut [i64], i: usize, j: usize) {
            for k in 0..x.cols() {
                if x[i][k] != None {
                    v[k] = c[i][k] as i64 - u[i];
                    if k != j {
                        calculation_of_potentials_v(c, x, u, v, i, k);
                    }
                }
            }
        }

        fn calculation_of_potentials_v(c: &Matrix<u64>, x: &Matrix<Option<u64>>, u: &mut [i64], v: &mut [i64], i: usize, j: usize) {
            for k in 0..x.rows() {
                if x[k][j] != None {
                    u[k] = c[k][j] as i64 - v[j];
                    if k != i {
                        calculation_of_potentials_h(c, x, u, v, k, j);
                    }
                }
            }
        }

        calculation_of_potentials_h(&self.cost, &self.trans, &mut u, &mut v, 0, 0);
        calculation_of_potentials_v(&self.cost, &self.trans, &mut u, &mut v, 0, 0);

        (u, v)
    }
    // Check for optimality
    // If the transportation plan is not optimal, then return the minimum of difference
    fn check(&self) -> Option<(usize, usize, i64)> {
        let mut min = None;
        let (u, v) = self.calculation_of_potentials();

        for i in 0..self.cost.rows() {
            for j in 0..self.cost.cols() {
                let d = self.cost[i][j] as i64 - u[i] - v[j];
                if d < 0 {
                    if let Some((_, _, m)) = min {
                        if m > d {
                            min = Some((i, j, d));
                        }
                    } else {
                        min = Some((i, j, d));
                    }
                }
            }
        }
        min
    }
    // Calculate the total cost
    fn total_cost(&self) -> u64 {
        let mut z = 0;
        for (t, c) in self.trans.data.iter().zip(self.cost.data.iter()) {
            if !t.is_none() {
                z += t.unwrap() * c;
            }
        }
        z
    }

    pub fn potential_method(&mut self) {
        self.least_cost_method();
        self.replenish();

        while let Some((i, j, _)) = self.check() {
            self.trans[i][j] = Some(0);
            let trans_state = self.cycle_detection(i, j);

            let mut min = std::u64::MAX;
            let mut f = true;
            for x in trans_state.iter(i, j) {
                if f {
                    f = false;
                } else {
                    if min > self.trans[x.0][x.1].unwrap() {
                        min = self.trans[x.0][x.1].unwrap();
                    }
                    f = true;
                }
            }

            f = true;
            for x in trans_state.iter(i, j) {
                if f {
                    self.trans[x.0][x.1] = Some(self.trans[x.0][x.1].unwrap() + min);
                    f = false;
                } else {
                    self.trans[x.0][x.1] = Some(self.trans[x.0][x.1].unwrap() - min);
                    f = true;
                }
            }

            let mut max = (0, 0, 0);
            for x in trans_state.iter(i, j) {
                if self.trans[x.0][x.1].unwrap() == 0 && max.2 <= self.cost[x.0][x.1] {
                    max = (x.0, x.1, self.cost[x.0][x.1]);
                }
            }
            self.trans[max.0][max.1] = None;
        }
    }

    pub fn printstd(&self) {
        let mut table = Table::new();
        table.add_row(Row::new(vec![Cell::new("")]));
        for i in 0..self.demand.len() {
            table[0].add_cell(Cell::new(&format!("B{}", i + 1)));
        }
        table[0].add_cell(Cell::new("Запасы"));
        for (i, s) in self.supply.iter().enumerate() {
            table.add_row(Row::new(vec![Cell::new(&format!("A{}", i + 1))]));
            for m in self.trans[i].iter() {
                if m.is_none() {
                    table[i + 1].add_cell(Cell::new("0"));
                } else {
                    table[i + 1].add_cell(Cell::new(&format!("{}", m.unwrap())));
                }
            }
            table[i + 1].add_cell(Cell::new(&format!("{}", s)));
        }
        table.add_row(Row::new(vec![Cell::new("Потребности")]));
        for d in self.demand.iter() {
            table[self.supply.len() + 1].add_cell(Cell::new(&format!("{}", d)));
        }
        table.add_row(Row::new(vec![Cell::new("Общая стоимость"), Cell::new(&format!("{}", self.total_cost()))]));
        table.printstd();
    }

    pub fn new(mut a: Vec<u64>, mut b: Vec<u64>, mut c: Vec<Vec<u64>>) -> Result<Transportation, Error> {
        if a.is_empty() || b.is_empty() {
            return Err(NumOfSupOrCust);
        }
        if a.len() != c.len() {
            return Err(NumOfRows);
        }
        for i in &c {
            if b.len() != i.len() {
                return Err(NumOfCols);
            }
        }

        let sum_s = a.iter().fold(0, std::ops::Add::add); //a.iter().sum();
        let sum_d = b.iter().fold(0, std::ops::Add::add); //b.iter().sum();
        if sum_s > sum_d {
            b.push(sum_s - sum_d);
            for i in &mut c {
                i.push(0);
            }
        }
        if sum_s < sum_d {
            a.push(sum_d - sum_s);
            c.push(vec![0;b.len()]);
        }
        let mut cost = Matrix::new(c[0].len());
        for i in c {
            cost.push(i);
        }

        Ok(Transportation {
            trans: Matrix {
                cols: b.len(),
                data: vec![None;a.len()*b.len()],
            },
            supply: a,
            demand: b,
            cost: cost,
        })
    }
}
<|endoftext|>


<commit_before>//! A library for interacting with Twitter.
//!
//! Please see [the repository][] and its enclosed examples for tips on working with this library
//! while it's still in progress.
//!
//! [the repository]: https://github.com/icesoldier/twitter-rs
//!
//! ## Getting Started
//!
//! The very first thing you'll need to do to get access to the Twitter API is to head to
//! [Twitter's Application Manager][twitter-apps] and create an app. Once you've done that, there
//! are two sets of keys immediately available to you. First are the "consumer key" and "consumer
//! secret", that are used to represent you as the application author when signing requests. These
//! keys are given to every single API call regardless of permission level. Related are an "access
//! token" and "access token secret", that can be used to skip the authentication steps if you're
//! only interacting with your own account or with no account in particular. Generally, if you want
//! to read or write to a particular user's stream, you'll need to request authorization and get an
//! access token to work on their behalf.
//!
//! [twitter-apps]: https://apps.twitter.com/
//!
//! The process to get an access token for a specific user (with this library) has three basic
//! steps:
//!
//! 1. Log your request with Twitter by getting a [request token][].
//! 2. Direct the user to grant permission to your application by sending them to an
//!    [authenticate][] or [authorize][] URL, depending on the nature of your app.
//! 3. Convert the verifier given by the permission request into an [access token][].
//!
//! [request token]: fn.request_token.html
//! [authorize]: fn.authorize_url.html
//! [authenticate]: fn.authenticate_url.html
//! [access token]: fn.access_token.html
//!
//! The process changes some smaller details depending on whether your application is web- or
//! mobile-based, as opposed to desktop-based or in another situation where redirecting users to a
//! web browser and back automatically is difficult or impossible. In the former case where URLs
//! can be used to direct the user into and out of your app, give Twitter a "callback URL" when
//! setting up your request token, and redirect the user to an [authenticate][] URL to grant your
//! app permissions. When the user accepts the request, they will be redirected back to this URL to
//! get back to your app, with the original request token and a verifier given to your app to
//! signify their acceptance.
//!
//! On the other hand, if you can't use the callback URL in this fashion, you can instead use the
//! "PIN-based Auth" version of the flow. In this version, give a "callback URL" of "oob" when
//! setting up your request token, and use an [authorize][] URL. When the user grants the
//! permissions request in this fashion, they are given a numeric PIN that can be given back to
//! your app to use as a verifier.
//!
//! Either way, when you have a "verifier" from either of these methods, you can use your Tokens
//! from earlier in the process with that verifier to request an [access token][]. This access
//! token can then be saved and cached for future use.

#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![warn(unused_qualifications)]

#[macro_use] extern crate hyper;
extern crate url;
extern crate time;
extern crate rand;
extern crate crypto;
extern crate rustc_serialize;
extern crate mime;

mod auth;
pub mod error;
pub mod user;
mod links;
mod common;

pub use auth::{Token, request_token, authorize_url, authenticate_url, access_token};
pub use common::{Response, TwitterErrors, TwitterErrorCode, UserID};
<commit_msg>add doc blurb about Response<commit_after>//! A library for interacting with Twitter.
//!
//! Please see [the repository][] and its enclosed examples for tips on working with this library
//! while it's still in progress.
//!
//! [the repository]: https://github.com/icesoldier/twitter-rs
//!
//! ## Getting Started
//!
//! The very first thing you'll need to do to get access to the Twitter API is to head to
//! [Twitter's Application Manager][twitter-apps] and create an app. Once you've done that, there
//! are two sets of keys immediately available to you. First are the "consumer key" and "consumer
//! secret", that are used to represent you as the application author when signing requests. These
//! keys are given to every single API call regardless of permission level. Related are an "access
//! token" and "access token secret", that can be used to skip the authentication steps if you're
//! only interacting with your own account or with no account in particular. Generally, if you want
//! to read or write to a particular user's stream, you'll need to request authorization and get an
//! access token to work on their behalf.
//!
//! [twitter-apps]: https://apps.twitter.com/
//!
//! The process to get an access token for a specific user (with this library) has three basic
//! steps:
//!
//! 1. Log your request with Twitter by getting a [request token][].
//! 2. Direct the user to grant permission to your application by sending them to an
//!    [authenticate][] or [authorize][] URL, depending on the nature of your app.
//! 3. Convert the verifier given by the permission request into an [access token][].
//!
//! [request token]: fn.request_token.html
//! [authorize]: fn.authorize_url.html
//! [authenticate]: fn.authenticate_url.html
//! [access token]: fn.access_token.html
//!
//! The process changes some smaller details depending on whether your application is web- or
//! mobile-based, as opposed to desktop-based or in another situation where redirecting users to a
//! web browser and back automatically is difficult or impossible. In the former case where URLs
//! can be used to direct the user into and out of your app, give Twitter a "callback URL" when
//! setting up your request token, and redirect the user to an [authenticate][] URL to grant your
//! app permissions. When the user accepts the request, they will be redirected back to this URL to
//! get back to your app, with the original request token and a verifier given to your app to
//! signify their acceptance.
//!
//! On the other hand, if you can't use the callback URL in this fashion, you can instead use the
//! "PIN-based Auth" version of the flow. In this version, give a "callback URL" of "oob" when
//! setting up your request token, and use an [authorize][] URL. When the user grants the
//! permissions request in this fashion, they are given a numeric PIN that can be given back to
//! your app to use as a verifier.
//!
//! Either way, when you have a "verifier" from either of these methods, you can use your Tokens
//! from earlier in the process with that verifier to request an [access token][]. This access
//! token can then be saved and cached for future use.
//!
//! ## `Response<T>`
//!
//! Every method that calls Twitter and carries rate-limit information wraps its return value in a
//! `[Response][]` struct, that transmits this information to your app. From there, you can handle
//! the rate-limit information to hold off on that kind of request, or simply grab its `response`
//! field to get the output of whatever method you called.
//!
//! [Response]: struct.Response.html

#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![warn(unused_qualifications)]

#[macro_use] extern crate hyper;
extern crate url;
extern crate time;
extern crate rand;
extern crate crypto;
extern crate rustc_serialize;
extern crate mime;

mod auth;
pub mod error;
pub mod user;
mod links;
mod common;

pub use auth::{Token, request_token, authorize_url, authenticate_url, access_token};
pub use common::{Response, TwitterErrors, TwitterErrorCode, UserID};
<|endoftext|>


<commit_before>extern crate byteorder;

pub mod ber;
pub mod bind;
pub mod error;
mod connection;

pub use connection::LDAP;

pub type Result<T> = std::result::Result<T, error::LDAPError>;
<commit_msg>Flatten module structure<commit_after>extern crate byteorder;

pub mod ber;
pub mod bind;
pub mod error;

use std::net::{ToSocketAddrs, TcpStream};
use std::thread;

use std::sync::mpsc::{Sender, Receiver, channel};

use ber::common;

pub type Result<T> = std::result::Result<T, error::LDAPError>;

#[derive(Debug)]
pub struct LDAP
{
    // TODO: Later abstract over io::Read / io::Write
    stream: TcpStream,

    msgid: u32,

    encoder_channel: Sender<common::Tag>,
    decoder_channel: Receiver<common::Tag>,
}

impl LDAP
{
    pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<LDAP>
    {
        let stream = try!(TcpStream::connect(addr));
        let enc_str = try!(stream.try_clone());
        let dec_str = try!(stream.try_clone());

        let (encoder_tx, enc_rx) = channel();
        let (decoder_tx, dec_rx) = channel();

        println!("Spawning Encoder");
        let enc_child = thread::spawn(move || {
            let mut enc = ber::Encoder::from_writer_raw(enc_str);

            loop {
                let tag = enc_rx.recv().unwrap();
                println!("{:?}", &tag);
                enc.encode(&tag);
                enc.flush();
            }
        });

        println!("Spawning Decoder");
        let dec_child = thread::spawn(move || {
            let mut dec = ber::Decoder::from_reader_raw(dec_str);

            // loop {
            //     let tag = dec.decode().unwrap();
            //     decoder_tx.send(tag).unwrap();
            // }
        });

        Ok(LDAP
        {
            stream: stream,
            msgid: 0,
            encoder_channel: encoder_tx,
            decoder_channel: dec_rx,
        })
    }

    pub fn send(&self, tag: common::Tag) -> Result<()>
    {
        match self.encoder_channel.send(tag)
        {
            Ok(_) => Ok(()),
            Err(e) => Err(error::LDAPError::Other)
        }
    }

    pub fn recv(&self) -> ()
    {
        let tag = self.decoder_channel.recv().unwrap();
        println!("{:?}", tag);
    }
}
<|endoftext|>