<commit_before>use bifrost::raft::client::RaftClient;
use bifrost::raft::state_machine::master::ExecError;
use bifrost_hasher::hash_str;

use dovahkiin::types::Type;
use parking_lot::{RwLock, RwLockReadGuard};
use std::collections::HashMap;
use std::mem;

use super::types;
use core::borrow::Borrow;
use std::string::String;
use std::sync::Arc;

use futures::prelude::*;
use futures::FutureExt;
use std::ops::Deref;

pub mod sm;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Schema {
    pub id: u32,
    pub name: String,
    pub key_field: Option<Vec<u64>>,
    pub str_key_field: Option<Vec<String>>,
    pub fields: Field,
    pub static_bound: usize,
    pub is_dynamic: bool,
    pub is_scannable: bool
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub enum IndexType {
    Ranged,
    Hashed,
    Vectorized,
    Statistics,
}

impl Schema {
    pub fn new(
        name: &str,
        key_field: Option<Vec<String>>,
        mut fields: Field,
        is_dynamic: bool,
        is_scannable: bool,
    ) -> Schema {
        let mut bound = 0;
        fields.assign_offsets(&mut bound);
        Schema {
            id: 0,
            name: name.to_string(),
            key_field: match key_field {
                None => None,
                Some(ref keys) => Some(keys.iter().map(|f| hash_str(f)).collect()), // field list into field ids
            },
            str_key_field: key_field,
            static_bound: bound,
            fields,
            is_dynamic,
            is_scannable,
        }
    }
    pub fn new_with_id(
        id: u32,
        name: &str,
        key_field: Option<Vec<String>>,
        fields: Field,
        dynamic: bool,
        scannable: bool,
    ) -> Schema {
        let mut schema = Schema::new(name, key_field, fields, dynamic, scannable);
        schema.id = id;
        schema
    }
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Field {
    pub data_type: Type,
    pub nullable: bool,
    pub is_array: bool,
    pub sub_fields: Option<Vec<Field>>,
    pub name: String,
    pub name_id: u64,
    pub indices: Vec<IndexType>,
    pub offset: Option<usize>,
}

impl Field {
    pub fn new(
        name: &str,
        data_type: Type,
        nullable: bool,
        is_array: bool,
        sub_fields: Option<Vec<Field>>,
        indices: Vec<IndexType>,
    ) -> Field {
        Field {
            name: name.to_string(),
            name_id: types::key_hash(name),
            data_type,
            nullable,
            is_array,
            sub_fields,
            indices,
            offset: None
        }
    }
    fn assign_offsets(&mut self, offset: &mut usize) {
        self.offset = Some(*offset);
        if self.nullable {
            *offset += 1;
        }
        if self.is_array {
            // u32 as indication of the offset to the actual data
            *offset += mem::size_of::<u32>();
        } else if let Some(ref mut subs) = self.sub_fields {
            subs.iter_mut().for_each(|f| f.assign_offsets(offset));
        } else {
            *offset += types::size_of_type(self.data_type);
        }
    }
}

pub struct SchemasMap {
    schema_map: HashMap<u32, Schema>,
    name_map: HashMap<String, u32>,
    id_counter: u32,
}

pub struct LocalSchemasCache {
    map: Arc<RwLock<SchemasMap>>,
}

impl LocalSchemasCache {
    pub async fn new(
        group: &str,
        raft_client: &Arc<RaftClient>,
    ) -> Result<LocalSchemasCache, ExecError> {
        info!("Initializing local schema cache");
        let map = Arc::new(RwLock::new(SchemasMap::new()));
        let m1 = map.clone();
        let m2 = map.clone();
        let sm = sm::client::SMClient::new(sm::generate_sm_id(group), raft_client);
        let sm_data = sm.get_all().await?;
        {
            let mut map = map.write();
            debug!("Importing {} schemas from cluster", sm_data.len());
            for schema in sm_data {
                trace!("Importing schema {}", schema.name);
                map.new_schema(schema);
            }
        }
        debug!("Subscribing schema events...");
        let _ = sm
            .on_schema_added(move |schema| {
                debug!("Add schema {} from subscription", schema.id);
                let mut m1 = m1.write();
                m1.new_schema(schema);
                future::ready(()).boxed()
            })
            .await?;
        let _ = sm
            .on_schema_deleted(move |schema| {
                let mut m2 = m2.write();
                m2.del_schema(&schema).unwrap();
                future::ready(()).boxed()
            })
            .await?;
        let schemas = LocalSchemasCache { map };
        info!("Local schema initialization completed");
        return Ok(schemas);
    }
    pub fn new_local(_group: &str) -> Self {
        let map = Arc::new(RwLock::new(SchemasMap::new()));
        LocalSchemasCache { map }
    }
    pub fn get(&self, id: &u32) -> Option<ReadingSchema> {
        let m = self.map.read();
        let so = m.get(id).map(|s| s as *const Schema);
        so.map(|s| ReadingSchema {
            _owner: m,
            reference: s,
        })
    }
    pub fn new_schema(&self, schema: Schema) {
        // for debug only
        let mut m = self.map.write();
        m.new_schema(schema)
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        let m = self.map.read();
        m.name_to_id(name)
    }
}

impl SchemasMap {
    pub fn new() -> SchemasMap {
        SchemasMap {
            schema_map: HashMap::new(),
            name_map: HashMap::new(),
            id_counter: 0,
        }
    }
    pub fn new_schema(&mut self, schema: Schema) {
        let name = schema.name.clone();
        let id = schema.id;
        self.schema_map.insert(id, schema);
        self.name_map.insert(name, id);
    }
    pub fn del_schema(&mut self, name: &str) -> Result<(), ()> {
        if let Some(id) = self.name_to_id(name) {
            self.schema_map.remove(&id);
        }
        self.name_map.remove(&name.to_string());
        Ok(())
    }
    pub fn get_by_name(&self, name: &str) -> Option<&Schema> {
        if let Some(id) = self.name_to_id(name) {
            return self.get(&id);
        }
        return None;
    }
    pub fn get(&self, id: &u32) -> Option<&Schema> {
        if let Some(schema) = self.schema_map.get(id) {
            return Some(schema);
        }
        return None;
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        self.name_map.get(&name.to_string()).cloned()
    }
    fn next_id(&mut self) -> u32 {
        self.id_counter += 1;
        while self.schema_map.contains_key(&self.id_counter) {
            self.id_counter += 1;
        }
        self.id_counter
    }
    fn get_all(&self) -> Vec<Schema> {
        self.schema_map
            .values()
            .map(|s_ref| {
                let arc = s_ref.clone();
                let r: &Schema = arc.borrow();
                r.clone()
            })
            .collect()
    }
    fn load_from_list(&mut self, data: Vec<Schema>) {
        for schema in data {
            let id = schema.id;
            self.name_map.insert(schema.name.clone(), id);
            self.schema_map.insert(id, schema);
        }
    }
}

pub struct ReadingRef<O, T: ?Sized> {
    _owner: O,
    reference: *const T,
}

pub type ReadingSchema<'a> = ReadingRef<RwLockReadGuard<'a, SchemasMap>, Schema>;

impl<O, T: ?Sized> Deref for ReadingRef<O, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.reference }
    }
}
<commit_msg>fixed all compilation problems<commit_after>use bifrost::raft::client::RaftClient;
use bifrost::raft::state_machine::master::ExecError;
use bifrost_hasher::hash_str;

use dovahkiin::types::Type;
use parking_lot::{RwLock, RwLockReadGuard};
use std::collections::HashMap;
use std::mem;

use super::types;
use core::borrow::Borrow;
use std::string::String;
use std::sync::Arc;

use futures::prelude::*;
use futures::FutureExt;
use std::ops::Deref;

pub mod sm;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Schema {
    pub id: u32,
    pub name: String,
    pub key_field: Option<Vec<u64>>,
    pub str_key_field: Option<Vec<String>>,
    pub fields: Field,
    pub static_bound: usize,
    pub is_dynamic: bool,
    pub is_scannable: bool
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub enum IndexType {
    Ranged,
    Hashed,
    Vectorized,
    Statistics,
}

impl Schema {
    pub fn new(
        name: &str,
        key_field: Option<Vec<String>>,
        mut fields: Field,
        is_dynamic: bool,
        is_scannable: bool,
    ) -> Schema {
        let mut bound = 0;
        fields.assign_offsets(&mut bound);
        Schema {
            id: 0,
            name: name.to_string(),
            key_field: match key_field {
                None => None,
                Some(ref keys) => Some(keys.iter().map(|f| hash_str(f)).collect()), // field list into field ids
            },
            str_key_field: key_field,
            static_bound: bound,
            fields,
            is_dynamic,
            is_scannable,
        }
    }
    pub fn new_with_id(
        id: u32,
        name: &str,
        key_field: Option<Vec<String>>,
        fields: Field,
        dynamic: bool,
        scannable: bool,
    ) -> Schema {
        let mut schema = Schema::new(name, key_field, fields, dynamic, scannable);
        schema.id = id;
        schema
    }
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Field {
    pub data_type: Type,
    pub nullable: bool,
    pub is_array: bool,
    pub sub_fields: Option<Vec<Field>>,
    pub name: String,
    pub name_id: u64,
    pub indices: Vec<IndexType>,
    pub offset: Option<usize>,
}

impl Field {
    pub fn new(
        name: &str,
        data_type: Type,
        nullable: bool,
        is_array: bool,
        sub_fields: Option<Vec<Field>>,
        indices: Vec<IndexType>,
    ) -> Field {
        Field {
            name: name.to_string(),
            name_id: types::key_hash(name),
            data_type,
            nullable,
            is_array,
            sub_fields,
            indices,
            offset: None
        }
    }
    fn assign_offsets(&mut self, offset: &mut usize) {
        self.offset = Some(*offset);
        if self.nullable {
            *offset += 1;
        }
        if self.is_array {
            // u32 as indication of the offset to the actual data
            *offset += mem::size_of::<u32>();
        } else if let Some(ref mut subs) = self.sub_fields {
            subs.iter_mut().for_each(|f| f.assign_offsets(offset));
        } else {
            if types::fixed_size(self.data_type) {
                *offset += types::size_of_type(self.data_type);
            } else {
                *offset += mem::size_of::<u32>();
            }
        }
    }
}

pub struct SchemasMap {
    schema_map: HashMap<u32, Schema>,
    name_map: HashMap<String, u32>,
    id_counter: u32,
}

pub struct LocalSchemasCache {
    map: Arc<RwLock<SchemasMap>>,
}

impl LocalSchemasCache {
    pub async fn new(
        group: &str,
        raft_client: &Arc<RaftClient>,
    ) -> Result<LocalSchemasCache, ExecError> {
        info!("Initializing local schema cache");
        let map = Arc::new(RwLock::new(SchemasMap::new()));
        let m1 = map.clone();
        let m2 = map.clone();
        let sm = sm::client::SMClient::new(sm::generate_sm_id(group), raft_client);
        let sm_data = sm.get_all().await?;
        {
            let mut map = map.write();
            debug!("Importing {} schemas from cluster", sm_data.len());
            for schema in sm_data {
                trace!("Importing schema {}", schema.name);
                map.new_schema(schema);
            }
        }
        debug!("Subscribing schema events...");
        let _ = sm
            .on_schema_added(move |schema| {
                debug!("Add schema {} from subscription", schema.id);
                let mut m1 = m1.write();
                m1.new_schema(schema);
                future::ready(()).boxed()
            })
            .await?;
        let _ = sm
            .on_schema_deleted(move |schema| {
                let mut m2 = m2.write();
                m2.del_schema(&schema).unwrap();
                future::ready(()).boxed()
            })
            .await?;
        let schemas = LocalSchemasCache { map };
        info!("Local schema initialization completed");
        return Ok(schemas);
    }
    pub fn new_local(_group: &str) -> Self {
        let map = Arc::new(RwLock::new(SchemasMap::new()));
        LocalSchemasCache { map }
    }
    pub fn get(&self, id: &u32) -> Option<ReadingSchema> {
        let m = self.map.read();
        let so = m.get(id).map(|s| s as *const Schema);
        so.map(|s| ReadingSchema {
            _owner: m,
            reference: s,
        })
    }
    pub fn new_schema(&self, schema: Schema) {
        // for debug only
        let mut m = self.map.write();
        m.new_schema(schema)
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        let m = self.map.read();
        m.name_to_id(name)
    }
}

impl SchemasMap {
    pub fn new() -> SchemasMap {
        SchemasMap {
            schema_map: HashMap::new(),
            name_map: HashMap::new(),
            id_counter: 0,
        }
    }
    pub fn new_schema(&mut self, schema: Schema) {
        let name = schema.name.clone();
        let id = schema.id;
        self.schema_map.insert(id, schema);
        self.name_map.insert(name, id);
    }
    pub fn del_schema(&mut self, name: &str) -> Result<(), ()> {
        if let Some(id) = self.name_to_id(name) {
            self.schema_map.remove(&id);
        }
        self.name_map.remove(&name.to_string());
        Ok(())
    }
    pub fn get_by_name(&self, name: &str) -> Option<&Schema> {
        if let Some(id) = self.name_to_id(name) {
            return self.get(&id);
        }
        return None;
    }
    pub fn get(&self, id: &u32) -> Option<&Schema> {
        if let Some(schema) = self.schema_map.get(id) {
            return Some(schema);
        }
        return None;
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        self.name_map.get(&name.to_string()).cloned()
    }
    fn next_id(&mut self) -> u32 {
        self.id_counter += 1;
        while self.schema_map.contains_key(&self.id_counter) {
            self.id_counter += 1;
        }
        self.id_counter
    }
    fn get_all(&self) -> Vec<Schema> {
        self.schema_map
            .values()
            .map(|s_ref| {
                let arc = s_ref.clone();
                let r: &Schema = arc.borrow();
                r.clone()
            })
            .collect()
    }
    fn load_from_list(&mut self, data: Vec<Schema>) {
        for schema in data {
            let id = schema.id;
            self.name_map.insert(schema.name.clone(), id);
            self.schema_map.insert(id, schema);
        }
    }
}

pub struct ReadingRef<O, T: ?Sized> {
    _owner: O,
    reference: *const T,
}

pub type ReadingSchema<'a> = ReadingRef<RwLockReadGuard<'a, SchemasMap>, Schema>;

impl<O, T: ?Sized> Deref for ReadingRef<O, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.reference }
    }
}
<|endoftext|>


<commit_before>// rustfmt/rustfmt.rs

use std::io::Writer;

use syntax::parse::lexer::{StringReader, TokenAndSpan};
use syntax::parse::token::Token;
use syntax::parse::token::keywords;
use syntax::parse::token;

macro_rules! try_io(
    ($e:expr) => (match $e {
        Ok(_) => {},
        Err(err) => return Err(
                format!("Err in Formatter: {}: '{}' details: {}", err.to_str(), err.desc, err.detail))
    })
)

static TAB_WIDTH: i32 = 4;

pub type FormatterResult<T> = Result<T, String>;

enum ProductionToParse {
    MatchProduction,
    UseProduction,
    BracesProduction,
    ParenthesesProduction,
    AttributeProduction
}

struct LineToken {
    token_and_span: TokenAndSpan,
    x_pos: i32,
}

impl LineToken {
    fn new(token_and_span: TokenAndSpan) -> LineToken {
        LineToken {
            token_and_span: token_and_span,
            x_pos: 0,
        }
    }

    fn whitespace_needed_after(&self, next: &LineToken) -> bool {
        match (&self.token_and_span.tok, &next.token_and_span.tok) {
            (&token::IDENT(..), &token::IDENT(..)) => true,
            (&token::IDENT(..), &token::NOT)
                    if !token::is_any_keyword(&self.token_and_span.tok) => {
                // Macros.
                false
            }

            (&token::IDENT(..), _) if
                    token::is_keyword(keywords::If, &self.token_and_span.tok) ||
                    token::is_keyword(keywords::As, &self.token_and_span.tok) ||
                    token::is_keyword(keywords::Match, &self.token_and_span.tok) => {
                true
            }
            (_, &token::IDENT(..))
                    if token::is_keyword(keywords::If, &next.token_and_span.tok) => {
                true
            }

            (&token::COLON, _) => true,
            (&token::COMMA, _) => true,
            (&token::EQ, _) | (_, &token::EQ) => true,
            (&token::LT, _) | (_, &token::LT) => true,
            (&token::LE, _) | (_, &token::LE) => true,
            (&token::EQEQ, _) | (_, &token::EQEQ) => true,
            (&token::NE, _) | (_, &token::NE) => true,
            (&token::GE, _) | (_, &token::GE) => true,
            (&token::GT, _) | (_, &token::GT) => true,
            (&token::ANDAND, _) | (_, &token::ANDAND) => true,
            (&token::OROR, _) | (_, &token::OROR) => true,
            (&token::TILDE, _) | (_, &token::TILDE) => true,

            (&token::LPAREN, _) => false,
            (_, &token::RPAREN) => false,
            (&token::BINOP(token::AND), _) => false,

            (&token::BINOP(_), _) | (_, &token::BINOP(_)) => true,
            (&token::BINOPEQ(_), _) | (_, &token::BINOPEQ(_)) => true,

            (&token::MOD_SEP, _) | (_, &token::MOD_SEP) => false,

            (&token::RARROW, _) | (_, &token::RARROW) => true,
            (&token::FAT_ARROW, _) | (_, &token::FAT_ARROW) => true,
            (&token::LBRACE, _) | (_, &token::LBRACE) => true,
            (&token::RBRACE, _) | (_, &token::RBRACE) => true,
            _ => false,
        }
    }

    fn length(&self) -> i32 {
        token::to_str(&self.token_and_span.tok).len() as i32
    }

    fn preindentation(&self) -> i32 {
        match self.token_and_span.tok {
            token::RBRACE => -TAB_WIDTH,
            _ => 0,
        }
    }
}

struct LogicalLine {
    tokens: Vec<LineToken>,
}

impl LogicalLine {
    fn new() -> LogicalLine {
        LogicalLine {
            tokens: Vec::new(),
        }
    }

    fn layout(&mut self, mut x_pos: i32) {
        if self.tokens.len() == 0 {
            return
        }

        for i in range(0, self.tokens.len()) {
            self.tokens.get_mut(i).x_pos = x_pos;
            x_pos += self.tokens.get(i).length();

            if i < self.tokens.len() - 1 &&
                    self.tokens.get(i).whitespace_needed_after(self.tokens.get(i + 1)) {
                x_pos += 1;
            }
        }
    }

    fn whitespace_after(&self, index: uint) -> i32 {
        if self.tokens.len() <= 1 || index >= self.tokens.len() - 1 {
            return 0
        }

        self.tokens.get(index + 1).x_pos - (self.tokens.get(index).x_pos +
                                            self.tokens.get(index).length())
    }

    fn postindentation(&self) -> i32 {
        match self.tokens.as_slice().last() {
            None => 0,
            Some(line_token) => {
                match line_token.token_and_span.tok {
                    token::LBRACE => TAB_WIDTH,
                    _ => 0,
                }
            }
        }
    }
}

pub struct Formatter<'a> {
    lexer: StringReader<'a>,
    indent: i32,
    logical_line: LogicalLine,
    last_token: Token,
    second_previous_token: Token,
    newline_after_comma: bool,
    newline_after_brace: bool,
    output: &'a mut Writer
}

impl<'a> Formatter<'a> {
    pub fn new<'a>(lexer: StringReader<'a>, output: &'a mut Writer) -> Formatter<'a> {
        Formatter {
            lexer: lexer,
            indent: 0,
            logical_line: LogicalLine::new(),
            last_token: token::SEMI,
            second_previous_token: token::SEMI,
            newline_after_comma: false,
            newline_after_brace: true,
            output: output
        }
    }

    fn token_ends_logical_line(&self, line_token: &LineToken) -> bool {
        use syntax::parse::lexer::Reader;

        match line_token.token_and_span.tok {
            token::SEMI => true,
            token::RBRACE => {
                match self.lexer.peek() {
                    TokenAndSpan { tok: token::COMMA, sp: _ } => {
                        false
                    }
                    _ => true
                }
            },
            token::COMMA => self.newline_after_comma,
            token::LBRACE => {
                match self.lexer.peek() {
                    TokenAndSpan { tok: token::RBRACE, sp: _ } => {
                        false
                    }
                    _ => self.newline_after_brace
                }
            },
            _ => false,
        }
    }

    fn token_starts_logical_line(&self, line_token: &LineToken) -> bool {
        match line_token.token_and_span.tok {
            token::RBRACE => {
                match (&self.second_previous_token, &self.last_token) {
                    // suppress newline separating braces in empty match arms
                    (&token::FAT_ARROW, &token::LBRACE) => false,
                    _ => self.newline_after_brace
                }
            },
            _ => false,
        }
    }

    fn parse_tokens_up_to(&mut self, pred: |&token::Token| -> bool) -> FormatterResult<bool> {
        while try!(self.next_token()) {
            if pred(&self.last_token) {
                return Ok(true);
            }
        }
        return Ok(false);
    }

    fn parse_productions_up_to(&mut self, pred: |&token::Token| -> bool) -> FormatterResult<bool> {
        while try!(self.next_token()) {
            if pred(&self.last_token) {
                return Ok(true);
            }
            try!(self.parse_production());
        }
        return Ok(false);
    }

    fn parse_match(&mut self) -> FormatterResult<bool> {
        // We've already parsed the keyword. Parse until we find a `{`.
        if !try!(self.parse_tokens_up_to(|token| *token == token::LBRACE)) {
            return Ok(false);
        }

        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;

        if !try!(self.parse_productions_up_to(|token| *token == token::RBRACE)) {
            return Ok(false);
        }

        self.newline_after_comma = old_newline_after_comma_setting;
        return Ok(true);
    }

    fn parse_use(&mut self) -> FormatterResult<bool> {
        let old_newline_after_brace_setting = self.newline_after_brace;
        self.newline_after_brace = false;

        // We've already parsed the keyword. Parse until we find a `{`.
        if !try!(self.parse_tokens_up_to(|token| *token == token::LBRACE || *token == token::SEMI)) {
            return Ok(false);
        }

        if self.last_token == token::LBRACE {
            let old_newline_after_comma_setting = self.newline_after_comma;
            self.newline_after_comma = false;

            if !try!(self.parse_productions_up_to(|token| *token == token::RBRACE)) {
                return Ok(false);
            }

            self.newline_after_comma = old_newline_after_comma_setting;
        }

        self.newline_after_brace = old_newline_after_brace_setting;
        return Ok(true);
    }

    fn parse_braces(&mut self) -> FormatterResult<bool> {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;
        // We've already parsed the '{'. Parse until we find a '}'.
        let result = try!(self.parse_productions_up_to(|token| *token == token::RBRACE));

        self.newline_after_comma = old_newline_after_comma_setting;
        return Ok(result);
    }

    fn parse_parentheses(&mut self) -> FormatterResult<bool> {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = false;

        // We've already parsed the '('. Parse until we find a ')'.
        let result = try!(self.parse_productions_up_to(|token| *token == token::RPAREN));

        self.newline_after_comma = old_newline_after_comma_setting;
        return Ok(result);
    }

    fn parse_attribute(&mut self) -> FormatterResult<bool> {
        // Parse until we find a ']'.
        let result = try!(self.parse_productions_up_to(|token| *token == token::RBRACKET));
        try!(self.flush_line());
        return Ok(result);
    }

    pub fn parse_production(&mut self) -> FormatterResult<bool> {
        let production_to_parse;
        match self.last_token {
            token::IDENT(..) if token::is_keyword(keywords::Match, &self.last_token) => {
                production_to_parse = MatchProduction;
            }
            token::IDENT(..) if token::is_keyword(keywords::Use, &self.last_token) => {
                production_to_parse = UseProduction;
            }
            token::LBRACE => production_to_parse = BracesProduction,
            token::LPAREN => production_to_parse = ParenthesesProduction,
            token::POUND => production_to_parse = AttributeProduction,
            token::DOC_COMMENT(_) => {
                try!(self.flush_line());
                return Ok(true);
            },
            _ => return Ok(true),
        }

        match production_to_parse {
            MatchProduction => return self.parse_match(),
            UseProduction => return self.parse_use(),
            BracesProduction => return self.parse_braces(),
            ParenthesesProduction => return self.parse_parentheses(),
            AttributeProduction => return self.parse_attribute()
        }
    }

    pub fn next_token(&mut self) -> FormatterResult<bool> {
        use syntax::parse::lexer::Reader;

        loop {
            if self.lexer.is_eof() {
                return Ok(false);
            }

            let next_token = self.lexer.peek();
            let next_tok_copy = next_token.tok.clone();
            let line_token = LineToken::new(next_token);
            if self.token_starts_logical_line(&line_token) && self.logical_line.tokens.len() > 0 {
                try!(self.flush_line());
                continue;
            }
            self.second_previous_token = self.last_token.clone();
            self.last_token = next_tok_copy;

            if self.logical_line.tokens.len() == 0 {
                self.indent += line_token.preindentation();
            }

            drop(self.lexer.next_token());
            let token_ends_logical_line = self.token_ends_logical_line(&line_token);
            self.logical_line.tokens.push(line_token);
            if token_ends_logical_line {
                try!(self.flush_line());
            }

            return Ok(true);
        }
    }

    fn flush_line(&mut self) -> FormatterResult<()> {

        self.logical_line.layout(self.indent);

        for _ in range(0, self.indent) {
            try_io!(self.output.write_str(" "));
        }
        for i in range(0, self.logical_line.tokens.len()) {
            let curr_tok = &self.logical_line.tokens.get(i).token_and_span.tok;
            try_io!(self.output.write_str(format!("{}", token::to_str(curr_tok)).as_slice()));

            // collapse empty blocks in match arms
            if (curr_tok == &token::LBRACE && i != self.logical_line.tokens.len() -1) &&
                &self.logical_line.tokens.get(i+1).token_and_span.tok == &token::RBRACE {
                continue;
            }
            // no whitespace after right-brackets, before comma in match arm
            if (curr_tok == &token::RBRACE && i != self.logical_line.tokens.len() -1) &&
                &self.logical_line.tokens.get(i+1).token_and_span.tok == &token::COMMA {
                continue;
            }
            for _ in range(0, self.logical_line.whitespace_after(i)) {
                try_io!(self.output.write_str(" "));
            }
        }
        try_io!(self.output.write_line(""));

        self.indent += self.logical_line.postindentation();
        self.logical_line = LogicalLine::new();
        Ok(())
    }
}

<commit_msg>token::to_str -> token::to_string<commit_after>// rustfmt/rustfmt.rs

use std::io::Writer;

use syntax::parse::lexer::{StringReader, TokenAndSpan};
use syntax::parse::token::Token;
use syntax::parse::token::keywords;
use syntax::parse::token;

macro_rules! try_io(
    ($e:expr) => (match $e {
        Ok(_) => {},
        Err(err) => return Err(
                format!("Err in Formatter: {}: '{}' details: {}", err.to_string(), err.desc, err.detail))
    })
)

static TAB_WIDTH: i32 = 4;

pub type FormatterResult<T> = Result<T, String>;

enum ProductionToParse {
    MatchProduction,
    UseProduction,
    BracesProduction,
    ParenthesesProduction,
    AttributeProduction
}

struct LineToken {
    token_and_span: TokenAndSpan,
    x_pos: i32,
}

impl LineToken {
    fn new(token_and_span: TokenAndSpan) -> LineToken {
        LineToken {
            token_and_span: token_and_span,
            x_pos: 0,
        }
    }

    fn whitespace_needed_after(&self, next: &LineToken) -> bool {
        match (&self.token_and_span.tok, &next.token_and_span.tok) {
            (&token::IDENT(..), &token::IDENT(..)) => true,
            (&token::IDENT(..), &token::NOT)
                    if !token::is_any_keyword(&self.token_and_span.tok) => {
                // Macros.
                false
            }

            (&token::IDENT(..), _) if
                    token::is_keyword(keywords::If, &self.token_and_span.tok) ||
                    token::is_keyword(keywords::As, &self.token_and_span.tok) ||
                    token::is_keyword(keywords::Match, &self.token_and_span.tok) => {
                true
            }
            (_, &token::IDENT(..))
                    if token::is_keyword(keywords::If, &next.token_and_span.tok) => {
                true
            }

            (&token::COLON, _) => true,
            (&token::COMMA, _) => true,
            (&token::EQ, _) | (_, &token::EQ) => true,
            (&token::LT, _) | (_, &token::LT) => true,
            (&token::LE, _) | (_, &token::LE) => true,
            (&token::EQEQ, _) | (_, &token::EQEQ) => true,
            (&token::NE, _) | (_, &token::NE) => true,
            (&token::GE, _) | (_, &token::GE) => true,
            (&token::GT, _) | (_, &token::GT) => true,
            (&token::ANDAND, _) | (_, &token::ANDAND) => true,
            (&token::OROR, _) | (_, &token::OROR) => true,
            (&token::TILDE, _) | (_, &token::TILDE) => true,

            (&token::LPAREN, _) => false,
            (_, &token::RPAREN) => false,
            (&token::BINOP(token::AND), _) => false,

            (&token::BINOP(_), _) | (_, &token::BINOP(_)) => true,
            (&token::BINOPEQ(_), _) | (_, &token::BINOPEQ(_)) => true,

            (&token::MOD_SEP, _) | (_, &token::MOD_SEP) => false,

            (&token::RARROW, _) | (_, &token::RARROW) => true,
            (&token::FAT_ARROW, _) | (_, &token::FAT_ARROW) => true,
            (&token::LBRACE, _) | (_, &token::LBRACE) => true,
            (&token::RBRACE, _) | (_, &token::RBRACE) => true,
            _ => false,
        }
    }

    fn length(&self) -> i32 {
        token::to_string(&self.token_and_span.tok).len() as i32
    }

    fn preindentation(&self) -> i32 {
        match self.token_and_span.tok {
            token::RBRACE => -TAB_WIDTH,
            _ => 0,
        }
    }
}

struct LogicalLine {
    tokens: Vec<LineToken>,
}

impl LogicalLine {
    fn new() -> LogicalLine {
        LogicalLine {
            tokens: Vec::new(),
        }
    }

    fn layout(&mut self, mut x_pos: i32) {
        if self.tokens.len() == 0 {
            return
        }

        for i in range(0, self.tokens.len()) {
            self.tokens.get_mut(i).x_pos = x_pos;
            x_pos += self.tokens.get(i).length();

            if i < self.tokens.len() - 1 &&
                    self.tokens.get(i).whitespace_needed_after(self.tokens.get(i + 1)) {
                x_pos += 1;
            }
        }
    }

    fn whitespace_after(&self, index: uint) -> i32 {
        if self.tokens.len() <= 1 || index >= self.tokens.len() - 1 {
            return 0
        }

        self.tokens.get(index + 1).x_pos - (self.tokens.get(index).x_pos +
                                            self.tokens.get(index).length())
    }

    fn postindentation(&self) -> i32 {
        match self.tokens.as_slice().last() {
            None => 0,
            Some(line_token) => {
                match line_token.token_and_span.tok {
                    token::LBRACE => TAB_WIDTH,
                    _ => 0,
                }
            }
        }
    }
}

pub struct Formatter<'a> {
    lexer: StringReader<'a>,
    indent: i32,
    logical_line: LogicalLine,
    last_token: Token,
    second_previous_token: Token,
    newline_after_comma: bool,
    newline_after_brace: bool,
    output: &'a mut Writer
}

impl<'a> Formatter<'a> {
    pub fn new<'a>(lexer: StringReader<'a>, output: &'a mut Writer) -> Formatter<'a> {
        Formatter {
            lexer: lexer,
            indent: 0,
            logical_line: LogicalLine::new(),
            last_token: token::SEMI,
            second_previous_token: token::SEMI,
            newline_after_comma: false,
            newline_after_brace: true,
            output: output
        }
    }

    fn token_ends_logical_line(&self, line_token: &LineToken) -> bool {
        use syntax::parse::lexer::Reader;

        match line_token.token_and_span.tok {
            token::SEMI => true,
            token::RBRACE => {
                match self.lexer.peek() {
                    TokenAndSpan { tok: token::COMMA, sp: _ } => {
                        false
                    }
                    _ => true
                }
            },
            token::COMMA => self.newline_after_comma,
            token::LBRACE => {
                match self.lexer.peek() {
                    TokenAndSpan { tok: token::RBRACE, sp: _ } => {
                        false
                    }
                    _ => self.newline_after_brace
                }
            },
            _ => false,
        }
    }

    fn token_starts_logical_line(&self, line_token: &LineToken) -> bool {
        match line_token.token_and_span.tok {
            token::RBRACE => {
                match (&self.second_previous_token, &self.last_token) {
                    // suppress newline separating braces in empty match arms
                    (&token::FAT_ARROW, &token::LBRACE) => false,
                    _ => self.newline_after_brace
                }
            },
            _ => false,
        }
    }

    fn parse_tokens_up_to(&mut self, pred: |&token::Token| -> bool) -> FormatterResult<bool> {
        while try!(self.next_token()) {
            if pred(&self.last_token) {
                return Ok(true);
            }
        }
        return Ok(false);
    }

    fn parse_productions_up_to(&mut self, pred: |&token::Token| -> bool) -> FormatterResult<bool> {
        while try!(self.next_token()) {
            if pred(&self.last_token) {
                return Ok(true);
            }
            try!(self.parse_production());
        }
        return Ok(false);
    }

    fn parse_match(&mut self) -> FormatterResult<bool> {
        // We've already parsed the keyword. Parse until we find a `{`.
        if !try!(self.parse_tokens_up_to(|token| *token == token::LBRACE)) {
            return Ok(false);
        }

        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;

        if !try!(self.parse_productions_up_to(|token| *token == token::RBRACE)) {
            return Ok(false);
        }

        self.newline_after_comma = old_newline_after_comma_setting;
        return Ok(true);
    }

    fn parse_use(&mut self) -> FormatterResult<bool> {
        let old_newline_after_brace_setting = self.newline_after_brace;
        self.newline_after_brace = false;

        // We've already parsed the keyword. Parse until we find a `{`.
        if !try!(self.parse_tokens_up_to(|token| *token == token::LBRACE || *token == token::SEMI)) {
            return Ok(false);
        }

        if self.last_token == token::LBRACE {
            let old_newline_after_comma_setting = self.newline_after_comma;
            self.newline_after_comma = false;

            if !try!(self.parse_productions_up_to(|token| *token == token::RBRACE)) {
                return Ok(false);
            }

            self.newline_after_comma = old_newline_after_comma_setting;
        }

        self.newline_after_brace = old_newline_after_brace_setting;
        return Ok(true);
    }

    fn parse_braces(&mut self) -> FormatterResult<bool> {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;
        // We've already parsed the '{'. Parse until we find a '}'.
        let result = try!(self.parse_productions_up_to(|token| *token == token::RBRACE));

        self.newline_after_comma = old_newline_after_comma_setting;
        return Ok(result);
    }

    fn parse_parentheses(&mut self) -> FormatterResult<bool> {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = false;

        // We've already parsed the '('. Parse until we find a ')'.
        let result = try!(self.parse_productions_up_to(|token| *token == token::RPAREN));

        self.newline_after_comma = old_newline_after_comma_setting;
        return Ok(result);
    }

    fn parse_attribute(&mut self) -> FormatterResult<bool> {
        // Parse until we find a ']'.
        let result = try!(self.parse_productions_up_to(|token| *token == token::RBRACKET));
        try!(self.flush_line());
        return Ok(result);
    }

    pub fn parse_production(&mut self) -> FormatterResult<bool> {
        let production_to_parse;
        match self.last_token {
            token::IDENT(..) if token::is_keyword(keywords::Match, &self.last_token) => {
                production_to_parse = MatchProduction;
            }
            token::IDENT(..) if token::is_keyword(keywords::Use, &self.last_token) => {
                production_to_parse = UseProduction;
            }
            token::LBRACE => production_to_parse = BracesProduction,
            token::LPAREN => production_to_parse = ParenthesesProduction,
            token::POUND => production_to_parse = AttributeProduction,
            token::DOC_COMMENT(_) => {
                try!(self.flush_line());
                return Ok(true);
            },
            _ => return Ok(true),
        }

        match production_to_parse {
            MatchProduction => return self.parse_match(),
            UseProduction => return self.parse_use(),
            BracesProduction => return self.parse_braces(),
            ParenthesesProduction => return self.parse_parentheses(),
            AttributeProduction => return self.parse_attribute()
        }
    }

    pub fn next_token(&mut self) -> FormatterResult<bool> {
        use syntax::parse::lexer::Reader;

        loop {
            if self.lexer.is_eof() {
                return Ok(false);
            }

            let next_token = self.lexer.peek();
            let next_tok_copy = next_token.tok.clone();
            let line_token = LineToken::new(next_token);
            if self.token_starts_logical_line(&line_token) && self.logical_line.tokens.len() > 0 {
                try!(self.flush_line());
                continue;
            }
            self.second_previous_token = self.last_token.clone();
            self.last_token = next_tok_copy;

            if self.logical_line.tokens.len() == 0 {
                self.indent += line_token.preindentation();
            }

            drop(self.lexer.next_token());
            let token_ends_logical_line = self.token_ends_logical_line(&line_token);
            self.logical_line.tokens.push(line_token);
            if token_ends_logical_line {
                try!(self.flush_line());
            }

            return Ok(true);
        }
    }

    fn flush_line(&mut self) -> FormatterResult<()> {

        self.logical_line.layout(self.indent);

        for _ in range(0, self.indent) {
            try_io!(self.output.write_str(" "));
        }
        for i in range(0, self.logical_line.tokens.len()) {
            let curr_tok = &self.logical_line.tokens.get(i).token_and_span.tok;
            try_io!(self.output.write_str(format!("{}", token::to_string(curr_tok)).as_slice()));

            // collapse empty blocks in match arms
            if (curr_tok == &token::LBRACE && i != self.logical_line.tokens.len() -1) &&
                &self.logical_line.tokens.get(i+1).token_and_span.tok == &token::RBRACE {
                continue;
            }
            // no whitespace after right-brackets, before comma in match arm
            if (curr_tok == &token::RBRACE && i != self.logical_line.tokens.len() -1) &&
                &self.logical_line.tokens.get(i+1).token_and_span.tok == &token::COMMA {
                continue;
            }
            for _ in range(0, self.logical_line.whitespace_after(i)) {
                try_io!(self.output.write_str(" "));
            }
        }
        try_io!(self.output.write_line(""));

        self.indent += self.logical_line.postindentation();
        self.logical_line = LogicalLine::new();
        Ok(())
    }
}

<|endoftext|>


<commit_before>use bifrost::raft::client::RaftClient;
use bifrost::raft::state_machine::master::ExecError;
use bifrost_hasher::hash_str;

use dovahkiin::types::Type;
use std::collections::HashMap;
use std::sync::atomic::AtomicU32;
use lightning::map::{HashMap as LFHashMap, Map, ObjectMap};
use std::mem;

use super::types;
use core::borrow::Borrow;
use std::string::String;
use std::sync::Arc;

use futures::prelude::*;
use futures::FutureExt;
use std::ops::Deref;

pub mod sm;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Schema {
    pub id: u32,
    pub name: String,
    pub key_field: Option<Vec<u64>>,
    pub str_key_field: Option<Vec<String>>,
    pub field_index: HashMap<u64, Vec<usize>>,
    pub id_index: HashMap<u64, Vec<u64>>,
    pub fields: Field,
    pub static_bound: usize,
    pub is_dynamic: bool,
    pub is_scannable: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub enum IndexType {
    Ranged,
    Hashed,
    Vectorized,
    Statistics,
}

impl Schema {
    pub fn new(
        name: &str,
        key_field: Option<Vec<String>>,
        mut fields: Field,
        is_dynamic: bool,
        is_scannable: bool,
    ) -> Schema {
        let mut bound = 0;
        let mut field_index = HashMap::new();
        let mut id_index = HashMap::new();
        fields.assign_offsets(&mut bound, &mut field_index, &mut id_index, String::new(), vec![], vec![]);
        trace!("Schema {:?} has bound {}", fields, bound);
        Schema {
            id: 0,
            name: name.to_string(),
            key_field: match key_field {
                None => None,
                Some(ref keys) => Some(keys.iter().map(|f| hash_str(f)).collect()), // field list into field ids
            },
            str_key_field: key_field,
            static_bound: bound,
            fields,
            is_dynamic,
            is_scannable,
            field_index,
            id_index
        }
    }
    pub fn new_with_id(
        id: u32,
        name: &str,
        key_field: Option<Vec<String>>,
        fields: Field,
        dynamic: bool,
        scannable: bool,
    ) -> Schema {
        let mut schema = Schema::new(name, key_field, fields, dynamic, scannable);
        schema.id = id;
        schema
    }
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Field {
    pub data_type: Type,
    pub nullable: bool,
    pub is_array: bool,
    pub sub_fields: Option<Vec<Field>>,
    pub name: String,
    pub name_id: u64,
    pub indices: Vec<IndexType>,
    pub offset: Option<usize>,
}

impl Field {
    pub fn new(
        name: &str,
        data_type: Type,
        nullable: bool,
        is_array: bool,
        sub_fields: Option<Vec<Field>>,
        indices: Vec<IndexType>,
    ) -> Field {
        Field {
            name: name.to_string(),
            name_id: types::key_hash(name),
            data_type,
            nullable,
            is_array,
            sub_fields,
            indices,
            offset: None,
        }
    }
    fn assign_offsets(
        &mut self,
        offset: &mut usize,
        field_index: &mut HashMap<u64, Vec<usize>>,
        id_index: &mut HashMap<u64, Vec<u64>>,
        name_path: String,
        field_path: Vec<usize>,
        id_path: Vec<u64>
    ) {
        const POINTER_SIZE: usize = mem::size_of::<u32>();
        self.offset = Some(*offset);
        let is_field_var = self.is_var();
        let name_path_hash = hash_str(&name_path);
        if self.nullable && !is_field_var {
            *offset += 1;
        }
        if self.is_array {
            // u32 as indication of the offset to the actual data
            *offset += POINTER_SIZE;
        } else if let Some(ref mut subs) = self.sub_fields {
            let format_name = if name_path.is_empty() {
                name_path
            } else {
                format!("{}|", name_path)
            };
            subs.iter_mut().enumerate().for_each(|(i, f)| {
                let mut new_path = field_path.clone();
                let mut new_id = id_path.clone();
                new_path.push(i);
                new_id.push(f.name_id);
                let new_name_path = format!("{}{}", format_name, f.name);
                f.assign_offsets(offset, field_index, id_index, new_name_path, new_path, new_id);
            });
        } else {
            if !is_field_var {
                *offset += types::size_of_type(self.data_type);
            } else {
                *offset += POINTER_SIZE;
            }
        }
        if !field_path.is_empty() {
            field_index.insert(name_path_hash, field_path);
        }
        if !id_path.is_empty() {
            id_index.insert(name_path_hash, id_path);
        }
        trace!(
            "Assigned field {} to {:?}, now at {}, var {}, offset moved {}",
            self.name,
            self.offset,
            offset,
            is_field_var,
            *offset - self.offset.unwrap()
        );
    }
    pub fn is_var(&self) -> bool {
        self.is_array || !types::fixed_size(self.data_type)
    }
}

pub struct SchemasMap {
    schema_map: ObjectMap<SchemaRef>,
    name_map: LFHashMap<String, usize>,
    id_counter: AtomicU32,
}

pub struct LocalSchemasCache {
    map: Arc<SchemasMap>,
}

impl LocalSchemasCache {
    pub async fn new(
        group: &str,
        raft_client: &Arc<RaftClient>,
    ) -> Result<LocalSchemasCache, ExecError> {
        info!("Initializing local schema cache");
        let map = Arc::new(SchemasMap::new());
        let m1 = map.clone();
        let m2 = map.clone();
        let sm = sm::client::SMClient::new(sm::generate_sm_id(group), raft_client);
        let sm_data = sm.get_all().await?;
        {
            debug!("Importing {} schemas from cluster", sm_data.len());
            for schema in sm_data {
                trace!("Importing schema {}", schema.name);
                map.new_schema(schema);
            }
        }
        debug!("Subscribing schema events...");
        let _ = sm
            .on_schema_added(move |schema| {
                debug!("Add schema {} from subscription", schema.id);
                m1.new_schema(schema);
                future::ready(()).boxed()
            })
            .await?;
        let _ = sm
            .on_schema_deleted(move |schema| {
                m2.del_schema(&schema).unwrap();
                future::ready(()).boxed()
            })
            .await?;
        let schemas = LocalSchemasCache { map };
        info!("Local schema initialization completed");
        return Ok(schemas);
    }
    pub fn new_local(_group: &str) -> Self {
        let map = Arc::new(SchemasMap::new());
        LocalSchemasCache { map }
    }
    pub fn get(&self, id: &u32) -> Option<SchemaRef> {
        self.map.get(id)
    }
    pub fn new_schema(&self, schema: Schema) {
        // for debug only
        let mut m = &self.map;
        m.new_schema(schema)
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        let m = &self.map;
        m.name_to_id(name)
    }
}

impl SchemasMap {
    pub fn new() -> SchemasMap {
        SchemasMap {
            schema_map: ObjectMap::with_capacity(32),
            name_map: LFHashMap::with_capacity(32),
            id_counter: AtomicU32::new(0),
        }
    }
    pub fn new_schema(&self, schema: Schema) {
        let name = &schema.name;
        let id = schema.id;
        self.name_map.insert(name, id as usize);
        self.schema_map.insert(&(id as usize), Arc::new(schema));
    }
    pub fn del_schema(&self, name: &str) -> Result<(), ()> {
        if let Some(id) = self.name_map.remove(&(name.to_owned())) {
            self.schema_map.remove(&id);
        }
        Ok(())
    }
    pub fn get_by_name(&self, name: &str) -> Option<SchemaRef> {
        if let Some(id) = self.name_to_id(name) {
            return self.get(&id);
        }
        return None;
    }
    pub fn get(&self, id: &u32) -> Option<SchemaRef> {
        self.schema_map.get(&(*id as usize))
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        self.name_map.get(&name.to_string()).map(|id| id as u32)
    }
    fn next_id(&mut self) -> u32 {
        let mut id = self.id_counter.fetch_and(1, std::sync::atomic::Ordering::AcqRel);
        while self.schema_map.contains_key(&(id as usize)) {
            id = self.id_counter.fetch_and(1, std::sync::atomic::Ordering::AcqRel)
        }
        id
    }
    fn get_all(&self) -> Vec<Schema> {
        self.schema_map
            .entries()
            .iter()
            .map(|(_, s_ref)| {
                (**s_ref).clone()
            })
            .collect()
    }
    fn load_from_list(&mut self, data: Vec<Schema>) {
        for schema in data {
            let id = schema.id as usize;
            self.name_map.insert(&schema.name, id);
            self.schema_map.insert(&id, Arc::new(schema));
        }
    }
}

pub struct ReadingRef<O, T: ?Sized> {
    _owner: O,
    reference: *const T,
}

pub type SchemaRef = Arc<Schema>;

impl<O, T: ?Sized> Deref for ReadingRef<O, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.reference }
    }
}
<commit_msg>tracking indices in scherma<commit_after>use bifrost::raft::client::RaftClient;
use bifrost::raft::state_machine::master::ExecError;
use bifrost_hasher::hash_str;

use dovahkiin::types::Type;
use lightning::map::{HashMap as LFHashMap, Map, ObjectMap};
use std::collections::HashMap;
use std::mem;
use std::sync::atomic::AtomicU32;

use super::types;
use core::borrow::Borrow;
use std::string::String;
use std::sync::Arc;

use futures::prelude::*;
use futures::FutureExt;
use std::ops::Deref;

pub mod sm;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Schema {
    pub id: u32,
    pub name: String,
    pub key_field: Option<Vec<u64>>,
    pub str_key_field: Option<Vec<String>>,
    pub field_index: HashMap<u64, Vec<usize>>,
    pub id_index: HashMap<u64, Vec<u64>>,
    pub index_fields: HashMap<u64, Vec<IndexType>>,
    pub fields: Field,
    pub static_bound: usize,
    pub is_dynamic: bool,
    pub is_scannable: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum IndexType {
    Ranged,
    Hashed,
    Vectorized,
    Statistics,
}

impl Schema {
    pub fn new(
        name: &str,
        key_field: Option<Vec<String>>,
        mut fields: Field,
        is_dynamic: bool,
        is_scannable: bool,
    ) -> Schema {
        let mut bound = 0;
        let mut field_index = HashMap::new();
        let mut id_index = HashMap::new();
        let mut index_fields = HashMap::new();
        fields.assign_offsets(
            &mut bound,
            &mut field_index,
            &mut id_index,
            &mut index_fields,
            String::new(),
            vec![],
            vec![],
        );
        trace!("Schema {:?} has bound {}", fields, bound);
        Schema {
            id: 0,
            name: name.to_string(),
            key_field: match key_field {
                None => None,
                Some(ref keys) => Some(keys.iter().map(|f| hash_str(f)).collect()), // field list into field ids
            },
            str_key_field: key_field,
            static_bound: bound,
            fields,
            is_dynamic,
            is_scannable,
            field_index,
            id_index,
            index_fields,
        }
    }
    pub fn new_with_id(
        id: u32,
        name: &str,
        key_field: Option<Vec<String>>,
        fields: Field,
        dynamic: bool,
        scannable: bool,
    ) -> Schema {
        let mut schema = Schema::new(name, key_field, fields, dynamic, scannable);
        schema.id = id;
        schema
    }
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Field {
    pub data_type: Type,
    pub nullable: bool,
    pub is_array: bool,
    pub sub_fields: Option<Vec<Field>>,
    pub name: String,
    pub name_id: u64,
    pub indices: Vec<IndexType>,
    pub offset: Option<usize>,
}

impl Field {
    pub fn new(
        name: &str,
        data_type: Type,
        nullable: bool,
        is_array: bool,
        sub_fields: Option<Vec<Field>>,
        indices: Vec<IndexType>,
    ) -> Field {
        Field {
            name: name.to_string(),
            name_id: types::key_hash(name),
            data_type,
            nullable,
            is_array,
            sub_fields,
            indices,
            offset: None,
        }
    }
    fn assign_offsets(
        &mut self,
        offset: &mut usize,
        field_index: &mut HashMap<u64, Vec<usize>>,
        id_index: &mut HashMap<u64, Vec<u64>>,
        index_fields: &mut HashMap<u64, Vec<IndexType>>,
        name_path: String,
        field_path: Vec<usize>,
        id_path: Vec<u64>,
    ) {
        const POINTER_SIZE: usize = mem::size_of::<u32>();
        self.offset = Some(*offset);
        let is_field_var = self.is_var();
        let name_path_hash = hash_str(&name_path);
        if self.nullable && !is_field_var {
            *offset += 1;
        }
        if self.is_array {
            // u32 as indication of the offset to the actual data
            *offset += POINTER_SIZE;
        } else if let Some(ref mut subs) = self.sub_fields {
            let format_name = if name_path.is_empty() {
                name_path
            } else {
                format!("{}|", name_path)
            };
            subs.iter_mut().enumerate().for_each(|(i, f)| {
                let mut new_path = field_path.clone();
                let mut new_id = id_path.clone();
                new_path.push(i);
                new_id.push(f.name_id);
                let new_name_path = format!("{}{}", format_name, f.name);
                f.assign_offsets(
                    offset,
                    field_index,
                    id_index,
                    index_fields,
                    new_name_path,
                    new_path,
                    new_id,
                );
            });
        } else {
            if !is_field_var {
                *offset += types::size_of_type(self.data_type);
            } else {
                *offset += POINTER_SIZE;
            }
        }
        if !field_path.is_empty() {
            field_index.insert(name_path_hash, field_path);
        }
        if !id_path.is_empty() {
            id_index.insert(name_path_hash, id_path);
            if !self.indices.is_empty() {
                index_fields.insert(name_path_hash, self.indices.clone());
            }
        }
        trace!(
            "Assigned field {} to {:?}, now at {}, var {}, offset moved {}",
            self.name,
            self.offset,
            offset,
            is_field_var,
            *offset - self.offset.unwrap()
        );
    }
    pub fn is_var(&self) -> bool {
        self.is_array || !types::fixed_size(self.data_type)
    }
}

pub struct SchemasMap {
    schema_map: ObjectMap<SchemaRef>,
    name_map: LFHashMap<String, usize>,
    id_counter: AtomicU32,
}

pub struct LocalSchemasCache {
    map: Arc<SchemasMap>,
}

impl LocalSchemasCache {
    pub async fn new(
        group: &str,
        raft_client: &Arc<RaftClient>,
    ) -> Result<LocalSchemasCache, ExecError> {
        info!("Initializing local schema cache");
        let map = Arc::new(SchemasMap::new());
        let m1 = map.clone();
        let m2 = map.clone();
        let sm = sm::client::SMClient::new(sm::generate_sm_id(group), raft_client);
        let sm_data = sm.get_all().await?;
        {
            debug!("Importing {} schemas from cluster", sm_data.len());
            for schema in sm_data {
                trace!("Importing schema {}", schema.name);
                map.new_schema(schema);
            }
        }
        debug!("Subscribing schema events...");
        let _ = sm
            .on_schema_added(move |schema| {
                debug!("Add schema {} from subscription", schema.id);
                m1.new_schema(schema);
                future::ready(()).boxed()
            })
            .await?;
        let _ = sm
            .on_schema_deleted(move |schema| {
                m2.del_schema(&schema).unwrap();
                future::ready(()).boxed()
            })
            .await?;
        let schemas = LocalSchemasCache { map };
        info!("Local schema initialization completed");
        return Ok(schemas);
    }
    pub fn new_local(_group: &str) -> Self {
        let map = Arc::new(SchemasMap::new());
        LocalSchemasCache { map }
    }
    pub fn get(&self, id: &u32) -> Option<SchemaRef> {
        self.map.get(id)
    }
    pub fn new_schema(&self, schema: Schema) {
        // for debug only
        let mut m = &self.map;
        m.new_schema(schema)
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        let m = &self.map;
        m.name_to_id(name)
    }
}

impl SchemasMap {
    pub fn new() -> SchemasMap {
        SchemasMap {
            schema_map: ObjectMap::with_capacity(32),
            name_map: LFHashMap::with_capacity(32),
            id_counter: AtomicU32::new(0),
        }
    }
    pub fn new_schema(&self, schema: Schema) {
        let name = &schema.name;
        let id = schema.id;
        self.name_map.insert(name, id as usize);
        self.schema_map.insert(&(id as usize), Arc::new(schema));
    }
    pub fn del_schema(&self, name: &str) -> Result<(), ()> {
        if let Some(id) = self.name_map.remove(&(name.to_owned())) {
            self.schema_map.remove(&id);
        }
        Ok(())
    }
    pub fn get_by_name(&self, name: &str) -> Option<SchemaRef> {
        if let Some(id) = self.name_to_id(name) {
            return self.get(&id);
        }
        return None;
    }
    pub fn get(&self, id: &u32) -> Option<SchemaRef> {
        self.schema_map.get(&(*id as usize))
    }
    pub fn name_to_id(&self, name: &str) -> Option<u32> {
        self.name_map.get(&name.to_string()).map(|id| id as u32)
    }
    fn next_id(&mut self) -> u32 {
        let mut id = self
            .id_counter
            .fetch_and(1, std::sync::atomic::Ordering::AcqRel);
        while self.schema_map.contains_key(&(id as usize)) {
            id = self
                .id_counter
                .fetch_and(1, std::sync::atomic::Ordering::AcqRel)
        }
        id
    }
    fn get_all(&self) -> Vec<Schema> {
        self.schema_map
            .entries()
            .iter()
            .map(|(_, s_ref)| (**s_ref).clone())
            .collect()
    }
    fn load_from_list(&mut self, data: Vec<Schema>) {
        for schema in data {
            let id = schema.id as usize;
            self.name_map.insert(&schema.name, id);
            self.schema_map.insert(&id, Arc::new(schema));
        }
    }
}

pub struct ReadingRef<O, T: ?Sized> {
    _owner: O,
    reference: *const T,
}

pub type SchemaRef = Arc<Schema>;

impl<O, T: ?Sized> Deref for ReadingRef<O, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.reference }
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use glium::{self, DrawParameters, LinearBlendingFactor, Program, VertexBuffer};
use glium::draw_parameters::{BlendingFunction, DepthTest};
use super::camera::Camera;
use util::ToArr;
use base::math::*;
use base::world::PillarIndex;
use GameContext;
use std::rc::Rc;

const BOX_SIZE: f32 = 20.0;

#[derive(Copy, Clone)]
pub struct Vertex {
    point: [f32; 3],
}
implement_vertex!(Vertex, point);

#[derive(Debug, Copy, Clone)]
pub enum Form {
    None = 0,
    Rain = 1,
    Snow = 2,
    Pollen = 3,
}

#[derive(Debug, Copy, Clone)]
pub enum Strength {
    Weak = 1,
    Medium = 2,
    Heavy = 3,
}

#[derive(Copy, Clone)]
pub struct Particle {
    vertices: [Vertex; 4],
    position: Point3<f32>,
    velocity: f32,
    trans_x: f32,
    trans_y: f32,
    trans_z: f32,
}

#[derive(Copy, Clone)]
pub struct Instance {
    position: [f32; 3],
}
implement_vertex!(Instance, position);

impl Particle {
    pub fn new(cam_pos: Point3<f32>) -> Particle {
        let mut radius: f32 = 0.0;
        let mut spawn = false;

        // loop provides better distribution of particles, by rolling a dice
        // which equalizes the chance for every radius inside the circle
        while !spawn {
            radius = rand::random::<f32>();

            let dice = rand::random::<f32>();

            spawn = dice < radius;
        }

        radius = radius * BOX_SIZE;

        let angle = Rad::new(rand::random::<f32>() * std::f32::consts::PI * 2);

        let mut velocity = rand::random::<f32>();
        if velocity < 0.25 {
            velocity = velocity + 0.25;
        }
        if velocity > 0.75 {
            velocity = velocity - 0.25;
        }

        Particle {
            vertices: [Vertex { point: [1.0, 1.0, 0.0] },
                       Vertex { point: [-1.0, 1.0, 0.0] },
                       Vertex { point: [1.0, -1.0, 0.0] },
                       Vertex { point: [-1.0, -1.0, 0.0] }],
            position: Point3::new(cam_pos.x + radius * Rad::sin(angle),
                                  cam_pos.y + radius * Rad::cos(angle),
                                  cam_pos.z + BOX_SIZE),
            velocity: velocity,
            trans_x: rand::random::<f32>() * std::f32::consts::PI * 2,
            trans_y: rand::random::<f32>() * std::f32::consts::PI * 2,
            trans_z: rand::random::<f32>() * std::f32::consts::PI * 2,
        }
    }
}

pub struct Weather {
    particles: Vec<Particle>,
    program: Program,
    indices: glium::index::NoIndices,
    context: Rc<GameContext>,
    camera: Camera,
    particle_buf: VertexBuffer<Instance>,
    actual_buf: VertexBuffer<Instance>,
    form: Form,
    strength: Strength,
    time: f32,
}

impl Weather {
    pub fn new(context: Rc<GameContext>) -> Weather {
        let vec: Vec<Particle> = Vec::new();
        let index_buffer = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip);
        let weather_program = context.load_program("weather").unwrap();
        let camera = Camera::default();
        let sections = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        let sections2 = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        Weather {
            particles: vec,
            program: weather_program,
            indices: index_buffer,
            context: context,
            camera: camera,
            particle_buf: sections,
            actual_buf: sections2,
            form: Form::None,
            strength: Strength::Weak,
            time: 0.0,
        }
    }

    pub fn draw<S: glium::Surface>(&mut self, surface: &mut S, camera: &Camera) {
        if self.form as u8 == 0 {
            return;
        }

        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            blend: glium::Blend {
                color: BlendingFunction::Addition {
                    source: LinearBlendingFactor::SourceAlpha,
                    destination: LinearBlendingFactor::OneMinusSourceAlpha,
                },
                ..Default::default()
            },
            ..Default::default()
        };

        let buffer = vec![Vertex { point: [1.0, 1.0, 0.0] },
                          Vertex { point: [-1.0, 1.0, 0.0] },
                          Vertex { point: [1.0, -1.0, 0.0] },
                          Vertex { point: [-1.0, -1.0, 0.0] }];
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &buffer).unwrap();
        let mut scaling = Matrix4::from_cols(Vector4f::new(1.0, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 1.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 1.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
        let view = camera.view_matrix();
        let mut color = Vector4f::new(0.0, 0.0, 0.0, 0.0);
        match self.form {
            Form::Snow => {
                color = Vector4f::new(0.7, 0.7, 0.7, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Rain => {
                color = Vector4f::new(0.35, 0.43, 0.47, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.01, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.5, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Pollen => {
                color = Vector4f::new(0.5, 0.5, 0.5, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            _ => (),
        };

        let uniforms = uniform!{
                form: self.form as i32,
                view_matrix: view.to_arr(),
                proj_matrix: camera.proj_matrix().to_arr(),
                scaling_matrix: scaling.to_arr(),
                color: color.to_arr(),
            };

        surface.draw((&vertex_buffer, self.actual_buf.per_instance().unwrap()),
                  &self.indices,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();

    }

    pub fn update(&mut self, camera: &Camera, time: f32, world_manager: &super::WorldManager) {
        if self.time == time {
            return;
        } else {
            self.time += 1.0;
        }
        if self.form as u8 == 0 {
            return;
        }
        self.camera = *camera;
        let max_count: usize;
        match self.form {
            Form::Pollen => max_count = 25 * self.strength as usize,
            _ => max_count = 750 * self.strength as usize,
        }
        if self.particles.len() < max_count {
            let count = max_count / 10;
            for _ in 0..count {
                self.particles.push(Particle::new(camera.position));
            }
            let mut tmp = Vec::new();
            for particle in self.particles.iter() {
                tmp.push(Instance {
                    position: [particle.position.x, particle.position.y, particle.position.z],
                })
            }
            let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp).unwrap();
            self.particle_buf = vertex_buffer;
        }

        let mut mapping = self.particle_buf.map();
        let mut tmp2 = Vec::new();
        for (particle, instance) in &mut self.particles.iter_mut().zip(mapping.iter_mut()) {
            match self.form {
                Form::Snow => {
                    instance.position[2] = instance.position[2] - (particle.velocity * 0.1);
                    instance.position[0] += particle.trans_x.sin() * 0.05;
                    instance.position[1] += particle.trans_y.cos() * 0.05;
                    particle.trans_y += std::f32::consts::PI * 0.005 *
                                        (rand::random::<f32>() - 0.5);
                    particle.trans_x += std::f32::consts::PI * 0.005 *
                                        (rand::random::<f32>() - 0.5);
                }

                Form::Rain => {
                    instance.position[2] = instance.position[2] - ((particle.velocity + 0.5) * 1.0)
                }
                Form::Pollen => {
                    instance.position[0] += particle.trans_x.sin() * 0.025;
                    instance.position[1] += particle.trans_y.cos() * 0.025;
                    instance.position[2] += (particle.trans_z.sin() - 0.7) * 0.01;
                    particle.trans_y += std::f32::consts::PI * 0.005 *
                                        (rand::random::<f32>() - 0.5);
                    particle.trans_x += std::f32::consts::PI * 0.005 *
                                        (rand::random::<f32>() - 0.5);
                    particle.trans_z += std::f32::consts::PI * 0.005 *
                                        (rand::random::<f32>() - 0.1);
                }
                _ => (),

            }

            let pix_vec = Point2::new(instance.position[0], instance.position[1]);
            let cam_vec = Point2::new(camera.position.x, camera.position.y);
            let tmp = pix_vec - cam_vec;
            let len = ((tmp.x * tmp.x) + (tmp.y * tmp.y)).sqrt();

            let size = match self.form {
                Form::Pollen => BOX_SIZE / 4.0,
                _ => 1.0,
            };

            if len > BOX_SIZE - size || len < -BOX_SIZE - size {
                instance.position[0] = instance.position[0] - (1.95 * tmp.x);
                instance.position[1] = instance.position[1] - (1.95 * tmp.y);
            }
            if instance.position[2] < self.camera.position.z - BOX_SIZE / size {
                instance.position[2] += 1.9 * (BOX_SIZE / size);
            }
            if instance.position[2] > self.camera.position.z + BOX_SIZE / size {
                instance.position[2] -= 1.9 * (BOX_SIZE / size);
            }
            let tmp_point = Point3::new(instance.position[0],
                                        instance.position[1],
                                        instance.position[2]);
            let mut height = 0.0;

            let world = world_manager.get_world();
            let relevant_pos = Point2f::new(instance.position[0], instance.position[1]);
            let pillar_index = PillarIndex(AxialPoint::from_real(relevant_pos));
            let vec_len = world.pillar_at(pillar_index)
                .map(|pillar| pillar.sections().len())
                .unwrap_or(0);
            let pillar_vec = world.pillar_at(pillar_index).map(|pillar| pillar.sections());
            if pillar_vec.is_some() {
                let new_pillar_vec = pillar_vec.unwrap();

                if vec_len == 1 {
                    height = new_pillar_vec[0].top.to_real();
                } else {
                    for i in 0..vec_len {
                        if i != vec_len - 1 {
                            if new_pillar_vec[i].top.to_real() < instance.position[2] &&
                               instance.position[2] < new_pillar_vec[i + 1].bottom.to_real() {
                                height = new_pillar_vec[i].top.to_real();
                                break;
                            } else {
                                continue;
                            }
                        } else {
                            height = new_pillar_vec[i].top.to_real();
                            break;
                        }
                    }
                }
            }
            // let vec = world.pillar_at(pillar_index);
            if ((tmp_point - camera.position).dot(camera.get_look_at_vector())) > 0.0 &&
               instance.position[2] > height {
                tmp2.push(Instance {
                    position: [instance.position[0], instance.position[1], instance.position[2]],
                })
            }
        }
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp2).unwrap();

        self.actual_buf = vertex_buffer;
    }

    pub fn set_weather(&mut self, form: Form, strength: Strength) {
        self.form = form;
        self.strength = strength;
    }
}
<commit_msg>fixed travis problems<commit_after>extern crate rand;

use glium::{self, DrawParameters, LinearBlendingFactor, Program, VertexBuffer};
use glium::draw_parameters::{BlendingFunction, DepthTest};
use super::camera::Camera;
use util::ToArr;
use base::math::*;
use base::world::PillarIndex;
use GameContext;
use std::rc::Rc;
use std::f32::consts::PI;

const BOX_SIZE: f32 = 20.0;

#[derive(Copy, Clone)]
pub struct Vertex {
    point: [f32; 3],
}
implement_vertex!(Vertex, point);

#[derive(Debug, Copy, Clone)]
pub enum Form {
    None = 0,
    Rain = 1,
    Snow = 2,
    Pollen = 3,
}

#[derive(Debug, Copy, Clone)]
pub enum Strength {
    Weak = 1,
    Medium = 2,
    Heavy = 3,
}

#[derive(Copy, Clone)]
pub struct Particle {
    vertices: [Vertex; 4],
    position: Point3<f32>,
    velocity: f32,
    trans_x: f32,
    trans_y: f32,
    trans_z: f32,
}

#[derive(Copy, Clone)]
pub struct Instance {
    position: [f32; 3],
}
implement_vertex!(Instance, position);

impl Particle {
    pub fn new(cam_pos: Point3<f32>) -> Particle {
        let mut radius: f32 = 0.0;
        let mut spawn = false;

        // loop provides better distribution of particles, by rolling a dice
        // which equalizes the chance for every radius inside the circle
        while !spawn {
            radius = rand::random::<f32>();

            let dice = rand::random::<f32>();

            spawn = dice < radius;
        }

        radius = radius * BOX_SIZE;

        let angle = Rad::new(rand::random::<f32>() * PI * 2.0);

        let mut velocity = rand::random::<f32>();
        if velocity < 0.25 {
            velocity = velocity + 0.25;
        }
        if velocity > 0.75 {
            velocity = velocity - 0.25;
        }

        Particle {
            vertices: [Vertex { point: [1.0, 1.0, 0.0] },
                       Vertex { point: [-1.0, 1.0, 0.0] },
                       Vertex { point: [1.0, -1.0, 0.0] },
                       Vertex { point: [-1.0, -1.0, 0.0] }],
            position: Point3::new(cam_pos.x + radius * Rad::sin(angle),
                                  cam_pos.y + radius * Rad::cos(angle),
                                  cam_pos.z + BOX_SIZE),
            velocity: velocity,
            trans_x: rand::random::<f32>() * PI * 2.0,
            trans_y: rand::random::<f32>() * PI * 2.0,
            trans_z: rand::random::<f32>() * PI * 2.0,
        }
    }
}

pub struct Weather {
    particles: Vec<Particle>,
    program: Program,
    indices: glium::index::NoIndices,
    context: Rc<GameContext>,
    camera: Camera,
    particle_buf: VertexBuffer<Instance>,
    actual_buf: VertexBuffer<Instance>,
    form: Form,
    strength: Strength,
    time: f32,
}

impl Weather {
    pub fn new(context: Rc<GameContext>) -> Weather {
        let vec: Vec<Particle> = Vec::new();
        let index_buffer = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip);
        let weather_program = context.load_program("weather").unwrap();
        let camera = Camera::default();
        let sections = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        let sections2 = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        Weather {
            particles: vec,
            program: weather_program,
            indices: index_buffer,
            context: context,
            camera: camera,
            particle_buf: sections,
            actual_buf: sections2,
            form: Form::None,
            strength: Strength::Weak,
            time: 0.0,
        }
    }

    pub fn draw<S: glium::Surface>(&mut self, surface: &mut S, camera: &Camera) {
        if self.form as u8 == 0 {
            return;
        }

        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            blend: glium::Blend {
                color: BlendingFunction::Addition {
                    source: LinearBlendingFactor::SourceAlpha,
                    destination: LinearBlendingFactor::OneMinusSourceAlpha,
                },
                ..Default::default()
            },
            ..Default::default()
        };

        let buffer = vec![Vertex { point: [1.0, 1.0, 0.0] },
                          Vertex { point: [-1.0, 1.0, 0.0] },
                          Vertex { point: [1.0, -1.0, 0.0] },
                          Vertex { point: [-1.0, -1.0, 0.0] }];
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &buffer).unwrap();
        let mut scaling = Matrix4::from_cols(Vector4f::new(1.0, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 1.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 1.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
        let view = camera.view_matrix();
        let mut color = Vector4f::new(0.0, 0.0, 0.0, 0.0);
        match self.form {
            Form::Snow => {
                color = Vector4f::new(0.7, 0.7, 0.7, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Rain => {
                color = Vector4f::new(0.35, 0.43, 0.47, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.01, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.5, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Pollen => {
                color = Vector4f::new(0.5, 0.5, 0.5, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            _ => (),
        };

        let uniforms = uniform!{
                form: self.form as i32,
                view_matrix: view.to_arr(),
                proj_matrix: camera.proj_matrix().to_arr(),
                scaling_matrix: scaling.to_arr(),
                color: color.to_arr(),
            };

        surface.draw((&vertex_buffer, self.actual_buf.per_instance().unwrap()),
                  &self.indices,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();

    }

    pub fn update(&mut self, camera: &Camera, time: f32, world_manager: &super::WorldManager) {
        if self.time == time {
            return;
        } else {
            self.time += 1.0;
        }
        if self.form as u8 == 0 {
            return;
        }
        self.camera = *camera;
        let max_count: usize;
        match self.form {
            Form::Pollen => max_count = 25 * self.strength as usize,
            _ => max_count = 750 * self.strength as usize,
        }
        if self.particles.len() < max_count {
            let count = max_count / 10;
            for _ in 0..count {
                self.particles.push(Particle::new(camera.position));
            }
            let mut tmp = Vec::new();
            for particle in self.particles.iter() {
                tmp.push(Instance {
                    position: [particle.position.x, particle.position.y, particle.position.z],
                })
            }
            let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp).unwrap();
            self.particle_buf = vertex_buffer;
        }

        let mut mapping = self.particle_buf.map();
        let mut tmp2 = Vec::new();
        for (particle, instance) in &mut self.particles.iter_mut().zip(mapping.iter_mut()) {
            match self.form {
                Form::Snow => {
                    instance.position[2] = instance.position[2] - (particle.velocity * 0.1);
                    instance.position[0] += particle.trans_x.sin() * 0.05;
                    instance.position[1] += particle.trans_y.cos() * 0.05;
                    particle.trans_y += PI * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += PI * 0.005 * (rand::random::<f32>() - 0.5);
                }

                Form::Rain => {
                    instance.position[2] = instance.position[2] - ((particle.velocity + 0.5) * 1.0)
                }
                Form::Pollen => {
                    instance.position[0] += particle.trans_x.sin() * 0.025;
                    instance.position[1] += particle.trans_y.cos() * 0.025;
                    instance.position[2] += (particle.trans_z.sin() - 0.7) * 0.01;
                    particle.trans_y += PI * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += PI * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_z += PI * 0.005 * (rand::random::<f32>() - 0.1);
                }
                _ => (),

            }

            let pix_vec = Point2::new(instance.position[0], instance.position[1]);
            let cam_vec = Point2::new(camera.position.x, camera.position.y);
            let tmp = pix_vec - cam_vec;
            let len = ((tmp.x * tmp.x) + (tmp.y * tmp.y)).sqrt();

            let size = match self.form {
                Form::Pollen => BOX_SIZE / 4.0,
                _ => 1.0,
            };

            if len > BOX_SIZE - size || len < -BOX_SIZE - size {
                instance.position[0] = instance.position[0] - (1.95 * tmp.x);
                instance.position[1] = instance.position[1] - (1.95 * tmp.y);
            }
            if instance.position[2] < self.camera.position.z - BOX_SIZE / size {
                instance.position[2] += 1.9 * (BOX_SIZE / size);
            }
            if instance.position[2] > self.camera.position.z + BOX_SIZE / size {
                instance.position[2] -= 1.9 * (BOX_SIZE / size);
            }
            let tmp_point = Point3::new(instance.position[0],
                                        instance.position[1],
                                        instance.position[2]);
            let mut height = 0.0;

            let world = world_manager.get_world();
            let relevant_pos = Point2f::new(instance.position[0], instance.position[1]);
            let pillar_index = PillarIndex(AxialPoint::from_real(relevant_pos));
            let vec_len = world.pillar_at(pillar_index)
                .map(|pillar| pillar.sections().len())
                .unwrap_or(0);
            let pillar_vec = world.pillar_at(pillar_index).map(|pillar| pillar.sections());
            if pillar_vec.is_some() {
                let new_pillar_vec = pillar_vec.unwrap();

                if vec_len == 1 {
                    height = new_pillar_vec[0].top.to_real();
                } else {
                    for i in 0..vec_len {
                        if i != vec_len - 1 {
                            if new_pillar_vec[i].top.to_real() < instance.position[2] &&
                               instance.position[2] < new_pillar_vec[i + 1].bottom.to_real() {
                                height = new_pillar_vec[i].top.to_real();
                                break;
                            } else {
                                continue;
                            }
                        } else {
                            height = new_pillar_vec[i].top.to_real();
                            break;
                        }
                    }
                }
            }
            // let vec = world.pillar_at(pillar_index);
            if ((tmp_point - camera.position).dot(camera.get_look_at_vector())) > 0.0 &&
               instance.position[2] > height {
                tmp2.push(Instance {
                    position: [instance.position[0], instance.position[1], instance.position[2]],
                })
            }
        }
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp2).unwrap();

        self.actual_buf = vertex_buffer;
    }

    pub fn set_weather(&mut self, form: Form, strength: Strength) {
        self.form = form;
        self.strength = strength;
    }
}
<|endoftext|>


<commit_before>extern mod rust_fuse;

use std::libc::{
    S_IFDIR,
    S_IFREG,
    ENOENT,
    EACCES,
    O_RDONLY,
    stat,
    off_t,
    size_t,
    c_int
};

use std::cmp::min;
use rust_fuse::*;
use std::os;
use std::path::stat::arch::default_stat;
use std::vec::MutableCloneableVector;

static HELLO_STR:&'static str = "Hello rusty world!\n";
static HELLO_FILE_FULLPATH:&'static str = "/hello_from_rust";

struct HelloFs;

impl FuseOperations for HelloFs {
    fn getattr(&self, path:&str) -> Result<stat, errno> {
        match path {
            "/" => Ok({
                    let mut st = default_stat();
                    // 493: octal 755.  Rust lacks octal literals
                    st.st_mode = (S_IFDIR | 493) as u32;
                    st.st_nlink = 2;
                    st
                }),
            x if x == HELLO_FILE_FULLPATH => Ok({
                    let mut st = default_stat();
                    // 292: octal 0444
                    st.st_mode = (S_IFREG | 292) as u32;
                    st.st_nlink = 1;
                    st.st_size = HELLO_STR.len() as i64;
                    st
                }),
            _ => Err(ENOENT)
        }
    }

    fn readdir(&self, path:&str, filler: fuse_fill_dir_func,
               _offset: off_t, _info: &fuse_file_info) -> Result<(), errno> {
        match path {
            "/" => Ok({
                    filler(".", None, 0);
                    filler("..", None, 0);
                    filler(HELLO_FILE_FULLPATH.slice_from(1), None, 0);
                }),
            _ => Err(ENOENT)
        }
    }

    fn open(&self, path:&str, info: &fuse_file_info) -> Result<filehandle, errno> {
        match path {
            x if x == HELLO_FILE_FULLPATH =>
                if info.flags & 3 != O_RDONLY { Err(EACCES) } else { Ok(0) },
            _ => Err(ENOENT)
        }
    }

    fn read(&self, path:&str, buf:&mut [u8], size: size_t, offset: off_t,
            _info: &fuse_file_info) -> Result<c_int, errno> {
        if path != HELLO_FILE_FULLPATH {
            return Err(ENOENT)
        };

        let slice_to_read = HELLO_STR.slice(offset as uint,
                                            min(HELLO_STR.len(),size as uint));
        Ok(buf.copy_from(slice_to_read.as_bytes()) as c_int)
    }
}

fn main() {
    std::os::set_exit_status(fuse_main(os::args(), ~HelloFs))
}
<commit_msg>Found the syntax for initializing a struct based on another one<commit_after>extern mod rust_fuse;

use std::libc::{
    S_IFDIR,
    S_IFREG,
    ENOENT,
    EACCES,
    O_RDONLY,
    stat,
    off_t,
    size_t,
    c_int
};

use std::cmp::min;
use rust_fuse::*;
use std::os;
use std::path::stat::arch::default_stat;
use std::vec::MutableCloneableVector;

static HELLO_STR:&'static str = "Hello rusty world!\n";
static HELLO_FILE_FULLPATH:&'static str = "/hello_from_rust";

struct HelloFs;

impl FuseOperations for HelloFs {
    fn getattr(&self, path:&str) -> Result<stat, errno> {
        match path {
            "/" => Ok(stat{
                    // 493: octal 755.  Rust lacks octal literals
                    st_mode: (S_IFDIR | 493) as u32,
                    st_nlink: 2,
                    .. default_stat()
                }),
            x if x == HELLO_FILE_FULLPATH => Ok(stat{
                    // 292: octal 0444
                    st_mode: (S_IFREG | 292) as u32,
                    st_nlink: 1,
                    st_size: HELLO_STR.len() as i64,
                    .. default_stat()
                }),
            _ => Err(ENOENT)
        }
    }

    fn readdir(&self, path:&str, filler: fuse_fill_dir_func,
               _offset: off_t, _info: &fuse_file_info) -> Result<(), errno> {
        match path {
            "/" => Ok({
                    filler(".", None, 0);
                    filler("..", None, 0);
                    filler(HELLO_FILE_FULLPATH.slice_from(1), None, 0);
                }),
            _ => Err(ENOENT)
        }
    }

    fn open(&self, path:&str, info: &fuse_file_info) -> Result<filehandle, errno> {
        match path {
            x if x == HELLO_FILE_FULLPATH =>
                if info.flags & 3 != O_RDONLY { Err(EACCES) } else { Ok(0) },
            _ => Err(ENOENT)
        }
    }

    fn read(&self, path:&str, buf:&mut [u8], size: size_t, offset: off_t,
            _info: &fuse_file_info) -> Result<c_int, errno> {
        if path != HELLO_FILE_FULLPATH {
            return Err(ENOENT)
        };

        let slice_to_read = HELLO_STR.slice(offset as uint,
                                            min(HELLO_STR.len(),size as uint));
        Ok(buf.copy_from(slice_to_read.as_bytes()) as c_int)
    }
}

fn main() {
    std::os::set_exit_status(fuse_main(os::args(), ~HelloFs))
}
<|endoftext|>