arthas 0.3.0

Arthas is an in-memory structure database.
Documentation

use std::collections::HashSet;
use super::super::comparision::Comparision;
use item::FieldInt;
use query::{Query, Order, QueryType};
use super::super::rc::RcChild;

pub type Subs = Vec<Sub>;
pub type Orders = Vec<(String, Order)>;

#[derive(Debug)]
pub struct Sub {
    pub field_int: FieldInt,
    pub comparisions: Vec<Comparision>,
    pub order: Option<Order>,
    pub stopped: bool,
}

impl Sub {
    pub fn _match(&self, rc_child: &RcChild) -> bool {
        let child = rc_child.read().unwrap();
        let item = child.item.read().unwrap();
        let rc_data = item.datas.get(&self.field_int).unwrap();
        let data = rc_data.read().unwrap();
        let value = data.get_value();

        for comparision in &self.comparisions {
            if !comparision._match(value) {
                return false;
            }
        }
        true
    }
}


#[derive(Default, Debug)]
pub struct Task {
    pub subs: Subs,
    pub orders: Orders,
    pub order_field: Option<String>,
    pub order: Option<Order>,
    pub offset: usize,
    pub limit: Option<usize>,
    pub query_type: QueryType,
    pub subs_length: usize,
    pub current: usize,
}

impl Task {
    pub fn new<T>(query: &Query<T>, query_type: &QueryType) -> Task {
        let (subs_length, subs) = Self::create_subs(query);
        let orders = Self::create_orders(query);
        let order_field = if let Some(order) = orders.first() {
            Some(order.0.to_owned())
        } else {
            None
        };
        let order = if let Some(order) = orders.first() {
            Some(order.1.clone())
        } else {
            None
        };

        Task {
            subs: subs,
            orders: orders,
            order: order,
            offset: query.offset.unwrap_or(0),
            limit: query.limit.clone(),
            query_type: query_type.clone(),
            subs_length: subs_length,
            order_field: order_field,
            current: 0,
        }
    }

    fn create_orders<T>(query: &Query<T>) -> Orders {
        let mut fields = HashSet::new();
        let mut orders = Vec::new();

        for tup in &query.orders {
            if fields.contains(&tup.0) {
                continue;
            } else {
                orders.push(tup.clone());
                fields.insert(tup.0.clone());
            }
        }

        orders
    }

    fn create_subs<T>(query: &Query<T>) -> (usize, Subs) {
        let mut subs_length = 0;
        let mut subs = Vec::new();

        for (field_int, comparisions) in &query.conditions {
            subs_length += 1;
            let mut sub_order = None;

            if !query.orders.is_empty() {
                let order = query.orders.first().unwrap();
                if field_int == &order.0 {
                    sub_order = Some(order.1.clone());
                }
            }

            subs.push(Sub {
                field_int: field_int.to_owned(),
                comparisions: comparisions.clone(),
                order: sub_order,
                stopped: false,
            });
        }

        (subs_length, subs)
    }

    pub fn get_order_field(&self) -> &str {
        self.order_field.as_ref().unwrap()
    }

    pub fn has_order(&self) -> bool {
        self.order_field.is_some()
    }
}