<commit_before>extern crate tantivy;
extern crate tempdir;

use std::path::Path;
use tempdir::TempDir;
use tantivy::Index;
use tantivy::schema::*;
use tantivy::collector::TopCollector;
use tantivy::query::QueryParser;

fn main() {
    // Let's create a temporary directory for the
    // sake of this example
    if let Ok(dir) = TempDir::new("tantivy_example_dir") {
        run_example(dir.path()).unwrap();
        dir.close().unwrap();
    }
}

fn run_example(index_path: &Path) -> tantivy::Result<()> {

    // # Defining the schema
    //
    // The Tantivy index requires a very strict schema.
    // The schema declares which fields are in the index,
    // and for each field, its type and "the way it should
    // be indexed".

    // first we need to define a schema ...
    let mut schema_builder = SchemaBuilder::default();

    // Our first field is title.
    // We want full-text search for it, and we want to be able
    // to retrieve the document after the search.
    //
    // TEXT | STORED is some syntactic sugar to describe
    // that.
    //
    // `TEXT` means the field should be tokenized and indexed,
    // along with its term frequency and term positions.
    //
    // `STORED` means that the field will also be saved
    // in a compressed, row-oriented key-value store.
    // This store is useful to reconstruct the
    // documents that were selected during the search phase.
    schema_builder.add_text_field("title", TEXT | STORED);

    // Our first field is body.
    // We want full-text search for it, and we want to be able
    // to retrieve the body after the search.
    schema_builder.add_text_field("body", TEXT);

    let schema = schema_builder.build();

    // # Indexing documents
    //
    // Let's create a brand new index.
    //
    // This will actually just save a meta.json
    // with our schema in the directory.
    let index = try!(Index::create(index_path, schema.clone()));

    // To insert document we need an index writer.
    // There must be only one writer at a time.
    // This single `IndexWriter` is already
    // multithreaded.
    //
    // Here we use a buffer of 50MB per thread. Using a bigger
    // heap for the indexer can increase its throughput.
    let mut index_writer = try!(index.writer(50_000_000));

    // Let's index our documents!
    // We first need a handle on the title and the body field.

    // ### Create a document "manually".
    //
    // We can create a document manually, by setting the fields
    // one by one in a Document object.
    let title = schema.get_field("title").unwrap();
    let body = schema.get_field("body").unwrap();

    let mut old_man_doc = Document::default();
    old_man_doc.add_text(title, "The Old Man and the Sea");
    old_man_doc.add_text(body,
                         "He was an old man who fished alone in a skiff in the Gulf Stream and \
                          he had gone eighty-four days now without taking a fish.");

    // ... and add it to the `IndexWriter`.
    index_writer.add_document(old_man_doc);

    // ### Create a document directly from json.
    //
    // Alternatively, we can use our schema to parse
    // a document object directly from json.

    let mice_and_men_doc = try!(schema.parse_document(r#"{
       "title": "Of Mice and Men",
       "body": "few miles south of Soledad, the Salinas River drops in close to the hillside bank and runs deep and green. The water is warm too, for it has slipped twinkling over the yellow sands in the sunlight before reaching the narrow pool. On one side of the river the golden foothill slopes curve up to the strong and rocky Gabilan Mountains, but on the valley side the water is lined with trees—willows fresh and green with every spring, carrying in their lower leaf junctures the debris of the winter’s flooding; and sycamores with mottled, white,recumbent limbs and branches that arch over the pool"
    }"#));

    index_writer.add_document(mice_and_men_doc);

    // Multi-valued field are allowed, they are
    // expressed in JSON by an array.
    // The following document has two titles.
    let frankenstein_doc = try!(schema.parse_document(r#"{
       "title": ["Frankenstein", "The Modern Promotheus"],
       "body": "You will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings.  I arrived here yesterday, and my first task is to assure my dear sister of my welfare and increasing confidence in the success of my undertaking."
    }"#));
    index_writer.add_document(frankenstein_doc);

    // This is an example, so we will only index 3 documents
    // here. You can check out tantivy's tutorial to index
    // the English wikipedia. Tantivy's indexing is rather fast.
    // Indexing 5 million articles of the English wikipedia takes
    // around 4 minutes on my computer!

    // ### Committing
    //
    // At this point our documents are not searchable.
    //
    //
    // We need to call .commit() explicitly to force the
    // index_writer to finish processing the documents in the queue,
    // flush the current index to the disk, and advertise
    // the existence of new documents.
    //
    // This call is blocking.
    try!(index_writer.commit());

    // If `.commit()` returns correctly, then all of the
    // documents that have been added are guaranteed to be
    // persistently indexed.
    //
    // In the scenario of a crash or a power failure,
    // tantivy behaves as if has rolled back to its last
    // commit.

    // # Searching
    //
    // Let's search our index. Start by reloading
    // searchers in the index. This should be done
    // after every commit().
    try!(index.load_searchers());

    // Afterwards create one (or more) searchers.
    //
    // You should create a searcher
    // every time you start a "search query".
    let searcher = index.searcher();

    // The query parser can interpret human queries.
    // Here, if the user does not specify which
    // field they want to search, tantivy will search
    // in both title and body.
    let query_parser = QueryParser::new(index.schema(), vec![title, body]);

    // QueryParser may fail if the query is not in the right
    // format. For user facing applications, this can be a problem.
    // A ticket has been opened regarding this problem.
    let query = try!(query_parser.parse_query("sea whale"));

    // A query defines a set of documents, as
    // well as the way they should be scored.
    //
    // A query created by the query parser is scored according
    // to a metric called Tf-Idf, and will consider
    // any document matching at least one of our terms.

    // ### Collectors
    //
    // We are not interested in all of the documents but
    // only in the top 10. Keeping track of our top 10 best documents
    // is the role of the TopCollector.
    let mut top_collector = TopCollector::with_limit(10);

    // We can now perform our query.
    try!(searcher.search(&*query, &mut top_collector));

    // Our top collector now contains the 10
    // most relevant doc ids...
    let doc_addresses = top_collector.docs();

    // The actual documents still need to be
    // retrieved from Tantivy's store.
    //
    // Since the body field was not configured as stored,
    // the document returned will only contain
    // a title.

    for doc_address in doc_addresses {
        let retrieved_doc = try!(searcher.doc(&doc_address));
        println!("{}", schema.to_json(&retrieved_doc));
    }

    // Wait for indexing and merging threads to shut down.
    // Usually this isn't needed, but in `main` we try to
    // delete the temporary directory and that fails on
    // Windows if the files are still open.
    index_writer.wait_merging_threads();

    Ok(())
}
<commit_msg>Check the result of wait_merging_threads<commit_after>extern crate tantivy;
extern crate tempdir;

use std::path::Path;
use tempdir::TempDir;
use tantivy::Index;
use tantivy::schema::*;
use tantivy::collector::TopCollector;
use tantivy::query::QueryParser;

fn main() {
    // Let's create a temporary directory for the
    // sake of this example
    if let Ok(dir) = TempDir::new("tantivy_example_dir") {
        run_example(dir.path()).unwrap();
        dir.close().unwrap();
    }
}

fn run_example(index_path: &Path) -> tantivy::Result<()> {

    // # Defining the schema
    //
    // The Tantivy index requires a very strict schema.
    // The schema declares which fields are in the index,
    // and for each field, its type and "the way it should
    // be indexed".

    // first we need to define a schema ...
    let mut schema_builder = SchemaBuilder::default();

    // Our first field is title.
    // We want full-text search for it, and we want to be able
    // to retrieve the document after the search.
    //
    // TEXT | STORED is some syntactic sugar to describe
    // that.
    //
    // `TEXT` means the field should be tokenized and indexed,
    // along with its term frequency and term positions.
    //
    // `STORED` means that the field will also be saved
    // in a compressed, row-oriented key-value store.
    // This store is useful to reconstruct the
    // documents that were selected during the search phase.
    schema_builder.add_text_field("title", TEXT | STORED);

    // Our first field is body.
    // We want full-text search for it, and we want to be able
    // to retrieve the body after the search.
    schema_builder.add_text_field("body", TEXT);

    let schema = schema_builder.build();

    // # Indexing documents
    //
    // Let's create a brand new index.
    //
    // This will actually just save a meta.json
    // with our schema in the directory.
    let index = try!(Index::create(index_path, schema.clone()));

    // To insert document we need an index writer.
    // There must be only one writer at a time.
    // This single `IndexWriter` is already
    // multithreaded.
    //
    // Here we use a buffer of 50MB per thread. Using a bigger
    // heap for the indexer can increase its throughput.
    let mut index_writer = try!(index.writer(50_000_000));

    // Let's index our documents!
    // We first need a handle on the title and the body field.

    // ### Create a document "manually".
    //
    // We can create a document manually, by setting the fields
    // one by one in a Document object.
    let title = schema.get_field("title").unwrap();
    let body = schema.get_field("body").unwrap();

    let mut old_man_doc = Document::default();
    old_man_doc.add_text(title, "The Old Man and the Sea");
    old_man_doc.add_text(body,
                         "He was an old man who fished alone in a skiff in the Gulf Stream and \
                          he had gone eighty-four days now without taking a fish.");

    // ... and add it to the `IndexWriter`.
    index_writer.add_document(old_man_doc);

    // ### Create a document directly from json.
    //
    // Alternatively, we can use our schema to parse
    // a document object directly from json.

    let mice_and_men_doc = try!(schema.parse_document(r#"{
       "title": "Of Mice and Men",
       "body": "few miles south of Soledad, the Salinas River drops in close to the hillside bank and runs deep and green. The water is warm too, for it has slipped twinkling over the yellow sands in the sunlight before reaching the narrow pool. On one side of the river the golden foothill slopes curve up to the strong and rocky Gabilan Mountains, but on the valley side the water is lined with trees—willows fresh and green with every spring, carrying in their lower leaf junctures the debris of the winter’s flooding; and sycamores with mottled, white,recumbent limbs and branches that arch over the pool"
    }"#));

    index_writer.add_document(mice_and_men_doc);

    // Multi-valued field are allowed, they are
    // expressed in JSON by an array.
    // The following document has two titles.
    let frankenstein_doc = try!(schema.parse_document(r#"{
       "title": ["Frankenstein", "The Modern Promotheus"],
       "body": "You will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings.  I arrived here yesterday, and my first task is to assure my dear sister of my welfare and increasing confidence in the success of my undertaking."
    }"#));
    index_writer.add_document(frankenstein_doc);

    // This is an example, so we will only index 3 documents
    // here. You can check out tantivy's tutorial to index
    // the English wikipedia. Tantivy's indexing is rather fast.
    // Indexing 5 million articles of the English wikipedia takes
    // around 4 minutes on my computer!

    // ### Committing
    //
    // At this point our documents are not searchable.
    //
    //
    // We need to call .commit() explicitly to force the
    // index_writer to finish processing the documents in the queue,
    // flush the current index to the disk, and advertise
    // the existence of new documents.
    //
    // This call is blocking.
    try!(index_writer.commit());

    // If `.commit()` returns correctly, then all of the
    // documents that have been added are guaranteed to be
    // persistently indexed.
    //
    // In the scenario of a crash or a power failure,
    // tantivy behaves as if has rolled back to its last
    // commit.

    // # Searching
    //
    // Let's search our index. Start by reloading
    // searchers in the index. This should be done
    // after every commit().
    try!(index.load_searchers());

    // Afterwards create one (or more) searchers.
    //
    // You should create a searcher
    // every time you start a "search query".
    let searcher = index.searcher();

    // The query parser can interpret human queries.
    // Here, if the user does not specify which
    // field they want to search, tantivy will search
    // in both title and body.
    let query_parser = QueryParser::new(index.schema(), vec![title, body]);

    // QueryParser may fail if the query is not in the right
    // format. For user facing applications, this can be a problem.
    // A ticket has been opened regarding this problem.
    let query = try!(query_parser.parse_query("sea whale"));

    // A query defines a set of documents, as
    // well as the way they should be scored.
    //
    // A query created by the query parser is scored according
    // to a metric called Tf-Idf, and will consider
    // any document matching at least one of our terms.

    // ### Collectors
    //
    // We are not interested in all of the documents but
    // only in the top 10. Keeping track of our top 10 best documents
    // is the role of the TopCollector.
    let mut top_collector = TopCollector::with_limit(10);

    // We can now perform our query.
    try!(searcher.search(&*query, &mut top_collector));

    // Our top collector now contains the 10
    // most relevant doc ids...
    let doc_addresses = top_collector.docs();

    // The actual documents still need to be
    // retrieved from Tantivy's store.
    //
    // Since the body field was not configured as stored,
    // the document returned will only contain
    // a title.

    for doc_address in doc_addresses {
        let retrieved_doc = try!(searcher.doc(&doc_address));
        println!("{}", schema.to_json(&retrieved_doc));
    }

    // Wait for indexing and merging threads to shut down.
    // Usually this isn't needed, but in `main` we try to
    // delete the temporary directory and that fails on
    // Windows if the files are still open.
    index_writer.wait_merging_threads()?;

    Ok(())
}
<|endoftext|>


<commit_before>use nalgebra::{Isometry3, Matrix4, Perspective3, Point3, Real, Scalar, Vector3};

pub struct Camera<T>
where
    T: Real + Scalar,
{
    projection: Perspective3<T>,
    view: Isometry3<T>,
}

impl<T> Camera<T>
where
    T: Real + Scalar,
{
    pub fn new(aspect: T, fov: T, near: T, far: T) -> Self {
        Camera {
            projection: Perspective3::new(aspect, fov, near, far),
            view: Isometry3::look_at_rh(
                &Point3::origin(),
                &Point3::new(T::zero(), T::zero(), -T::one()),
                &Vector3::y(),
            ),
        }
    }

    pub fn look_at(&mut self, from: &Point3<T>, to: &Point3<T>) {
        self.view = Isometry3::look_at_rh(from, to, &Vector3::y());
    }

    pub fn transform(&self) -> Matrix4<T> {
        self.projection.unwrap() * self.view.to_homogeneous()
    }
}
<commit_msg>Use `into_inner` instead of `unwrap`.<commit_after>use nalgebra::{Isometry3, Matrix4, Perspective3, Point3, Real, Scalar, Vector3};

pub struct Camera<T>
where
    T: Real + Scalar,
{
    projection: Perspective3<T>,
    view: Isometry3<T>,
}

impl<T> Camera<T>
where
    T: Real + Scalar,
{
    pub fn new(aspect: T, fov: T, near: T, far: T) -> Self {
        Camera {
            projection: Perspective3::new(aspect, fov, near, far),
            view: Isometry3::look_at_rh(
                &Point3::origin(),
                &Point3::new(T::zero(), T::zero(), -T::one()),
                &Vector3::y(),
            ),
        }
    }

    pub fn look_at(&mut self, from: &Point3<T>, to: &Point3<T>) {
        self.view = Isometry3::look_at_rh(from, to, &Vector3::y());
    }

    pub fn transform(&self) -> Matrix4<T> {
        self.projection.into_inner() * self.view.to_homogeneous()
    }
}
<|endoftext|>


<commit_before><commit_msg>Can now strip an assignment and all its descendants from an implication graph<commit_after><|endoftext|>


<commit_before>extern crate exonum;
extern crate exonum_time;
#[macro_use]
extern crate exonum_testkit;
#[macro_use]
extern crate pretty_assertions;

use std::time::{SystemTime, Duration, UNIX_EPOCH};

use exonum::helpers::{Height, ValidatorId};
use exonum::crypto::gen_keypair;
use exonum::storage::Snapshot;

use exonum_time::{TimeService, TimeSchema, TxTime, Time, TimeProvider};
use exonum_testkit::{TestKitBuilder, TestNode};

fn verify_validators_times<T: AsRef<Snapshot>>(
    snapshot: T,
    validators: &[TestNode],
    expected_times: &[Option<SystemTime>],
) {
    let schema = TimeSchema::new(snapshot);
    let validators_times = schema.validators_time();

    for (i, validator) in validators.iter().enumerate() {
        let public_key = &validator.public_keys().service_key;

        if let Some(time) = validators_times.get(public_key) {
            assert_eq!(Some(time.time()), expected_times[i]);
        } else {
            assert_eq!(None, expected_times[i]);
        }
    }
}

fn verify_consolidated_time<T: AsRef<Snapshot>>(snapshot: T, expected_time: &Option<SystemTime>) {
    let schema = TimeSchema::new(snapshot);

    if let Some(time) = schema.time().get() {
        assert_eq!(&Some(time.time()), expected_time);
    } else {
        assert_eq!(&None, expected_time);
    }
}

#[test]
fn test_exonum_time_service_with_3_validators() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(3)
        .with_service(TimeService::new())
        .create();

    let validators = testkit.network().validators().to_vec();

    // Validators time, that is saved in storage, look like this:
    // number | 0    | 1    | 2    |
    // time   | None | None | None |
    //
    // Consolidated time is None.

    verify_validators_times(&testkit.snapshot(), &validators, &[None, None, None]);
    verify_consolidated_time(&testkit.snapshot(), &None);

    // Add first transaction `tx0` from first validator with time `time0`.
    // After that validators time look like this:
    // number | 0       | 1    | 2    |
    // time   | `time0` | None | None |
    //
    // Consolidated time will have the value `time0`.

    let time0 = SystemTime::now();
    let tx0 = {
        let (pub_key, sec_key) = validators[0].service_keypair();
        TxTime::new(time0, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx0]);

    verify_validators_times(&testkit.snapshot(), &validators, &[Some(time0), None, None]);
    verify_consolidated_time(&testkit.snapshot(), &Some(time0));

    // Add second transaction `tx1` from second validator with time `time1` = `time0` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2    |
    // time   | `time0` | `time1` | None |
    //
    // In sorted order: `time1` >= `time0`.
    // Consolidated time will have the value `time1`.

    let time1 = time0 + Duration::new(10, 0);
    let tx1 = {
        let (pub_key, sec_key) = validators[1].service_keypair();
        TxTime::new(time1, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx1]);

    verify_validators_times(
        &testkit.snapshot(),
        &validators,
        &[Some(time0), Some(time1), None],
    );
    verify_consolidated_time(&testkit.snapshot(), &Some(time1));
}

#[test]
fn test_exonum_time_service_with_4_validators() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(4)
        .with_service(TimeService::new())
        .create();

    let validators = testkit.network().validators().to_vec();

    // Validators time, that is saved in storage, look like this:
    // number | 0    | 1    | 2    | 3    |
    // time   | None | None | None | None |
    //
    // max_byzantine_nodes = (4 - 1) / 3 = 1.
    //
    // Consolidated time is None.

    verify_validators_times(testkit.snapshot(), &validators, &[None, None, None, None]);
    verify_consolidated_time(&testkit.snapshot(), &None);

    // Add first transaction `tx0` from first validator with time `time0`.
    // After that validators time look like this:
    // number | 0       | 1    | 2    | 3    |
    // time   | `time0` | None | None | None |
    //
    // Consolidated time doesn't change.

    let time0 = SystemTime::now();
    let tx0 = {
        let (pub_key, sec_key) = validators[0].service_keypair();
        TxTime::new(time0, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx0]);

    verify_validators_times(
        &testkit.snapshot(),
        &validators,
        &[Some(time0), None, None, None],
    );
    verify_consolidated_time(&testkit.snapshot(), &None);

    // Add second transaction `tx1` from second validator with time `time1` = `time0` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2    | 3    |
    // time   | `time0` | `time1` | None | None |
    //
    // In sorted order: `time1` >= `time0`.
    // Consolidated time doesn't change.

    let time1 = time0 + Duration::new(10, 0);
    let tx1 = {
        let (pub_key, sec_key) = validators[1].service_keypair();
        TxTime::new(time1, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx1]);

    verify_validators_times(
        &testkit.snapshot(),
        &validators,
        &[Some(time0), Some(time1), None, None],
    );
    verify_consolidated_time(&testkit.snapshot(), &None);

    // Add third transaction `tx2` from third validator with time `time2` = `time1` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2       | 3    |
    // time   | `time0` | `time1` | `time2` | None |
    //
    // In sorted order: `time2` >= `time1` >= `time0`.
    // Consolidated time will have the value `time1`.

    let time2 = time1 + Duration::new(10, 0);
    let tx2 = {
        let (pub_key, sec_key) = validators[2].service_keypair();
        TxTime::new(time2, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx2]);

    verify_validators_times(
        &testkit.snapshot(),
        &validators,
        &[Some(time0), Some(time1), Some(time2), None],
    );
    verify_consolidated_time(&testkit.snapshot(), &Some(time1));

    // Add fourth transaction `tx3` from fourth validator with time `time3` = `time2` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2       | 3       |
    // time   | `time0` | `time1` | `time2` | `time3` |
    //
    // In sorted order: `time3` >= `time2` >= `time1` >= `time0`.
    // Consolidated time will have the value `time2`.

    let time3 = time2 + Duration::new(10, 0);
    let tx3 = {
        let (pub_key, sec_key) = validators[3].service_keypair();
        TxTime::new(time3, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx3]);

    verify_validators_times(
        &testkit.snapshot(),
        &validators,
        &[Some(time0), Some(time1), Some(time2), Some(time3)],
    );
    verify_consolidated_time(&testkit.snapshot(), &Some(time2));
}

// A struct that provides the node with the current time.
#[derive(Debug)]
struct MyTimeProvider;
impl TimeProvider for MyTimeProvider {
    fn current_time(&self) -> SystemTime {
        UNIX_EPOCH
    }
}

#[test]
fn test_mock_provider() {
    // Create a simple testkit network.
    let mut testkit = TestKitBuilder::validator()
        .with_service(TimeService::with_provider(
            Box::new(MyTimeProvider) as Box<TimeProvider>,
        ))
        .create();

    // Get the validator public key.
    let validator_public_key = &testkit.network().validators().to_vec()[0]
        .public_keys()
        .service_key;

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    // Check that the blockchain does not contain time.
    assert_eq!(schema.time().get(), None);
    // Check that the time for the validator is unknown.
    assert_eq!(schema.validators_time().get(validator_public_key), None);

    // Create two blocks.
    testkit.create_blocks_until(Height(2));

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    // Check that the time in the blockchain and for the validator has been updated.
    assert_eq!(schema.time().get(), Some(Time::new(UNIX_EPOCH)));
    assert_eq!(
        schema.validators_time().get(validator_public_key),
        Some(Time::new(UNIX_EPOCH))
    );
}

#[test]
fn test_selected_time_less_than_time_in_storage() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(1)
        .with_service(TimeService::new())
        .create();

    let validators = testkit.network().validators().to_vec();

    let (pub_key_0, _) = validators[0].service_keypair();

    let cfg_change_height = Height(5);
    let new_cfg = {
        let mut cfg = testkit.configuration_change_proposal();
        cfg.set_validators(vec![TestNode::new_validator(ValidatorId(0))]);
        cfg.set_actual_from(cfg_change_height);
        cfg
    };
    testkit.commit_configuration_change(new_cfg);
    testkit.create_blocks_until(cfg_change_height.previous());

    let validators = testkit.network().validators().to_vec();
    let (pub_key_1, sec_key_1) = validators[0].service_keypair();

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    assert!(schema.time().get().is_some());
    assert!(schema.validators_time().get(pub_key_0).is_some());
    assert!(schema.validators_time().get(pub_key_1).is_none());
    assert_eq!(schema.time().get(), schema.validators_time().get(pub_key_0));

    if let Some(time_in_storage) = schema.time().get() {
        let time_tx = time_in_storage.time() - Duration::new(10, 0);
        let tx = {
            TxTime::new(time_tx, pub_key_1, sec_key_1)
        };
        testkit.create_block_with_transactions(txvec![tx]);
    }

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);
    assert!(schema.time().get().is_some());
    assert!(schema.validators_time().get(pub_key_0).is_some());
    assert!(schema.validators_time().get(pub_key_1).is_some());
    assert_eq!(schema.time().get(), schema.validators_time().get(pub_key_0));
}

#[test]
fn test_creating_transaction_is_not_validator() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(1)
        .with_service(TimeService::new())
        .create();

    let (pub_key, sec_key) = gen_keypair();
    let tx = TxTime::new(SystemTime::now(), &pub_key, &sec_key);
    testkit.create_block_with_transactions(txvec![tx]);

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);
    assert!(schema.time().get().is_none());
    assert!(schema.validators_time().get(&pub_key).is_none());
}

#[test]
fn test_transaction_time_less_than_validator_time_in_storage() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(1)
        .with_service(TimeService::new())
        .create();

    let validator = &testkit.network().validators().to_vec()[0];
    let (pub_key, sec_key) = validator.service_keypair();

    let time0 = SystemTime::now();
    let tx0 = TxTime::new(time0, pub_key, sec_key);

    testkit.create_block_with_transactions(txvec![tx0]);

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    assert_eq!(schema.time().get(), Some(Time::new(time0)));
    assert_eq!(
        schema.validators_time().get(pub_key),
        Some(Time::new(time0))
    );

    let time1 = time0 - Duration::new(10, 0);
    let tx1 = TxTime::new(time1, pub_key, sec_key);

    testkit.create_block_with_transactions(txvec![tx1]);

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    assert_eq!(schema.time().get(), Some(Time::new(time0)));
    assert_eq!(
        schema.validators_time().get(pub_key),
        Some(Time::new(time0))
    );
}
<commit_msg>Refactoring 'verify*' functions<commit_after>extern crate exonum;
extern crate exonum_time;
#[macro_use]
extern crate exonum_testkit;
#[macro_use]
extern crate pretty_assertions;

use std::time::{SystemTime, Duration, UNIX_EPOCH};

use exonum::helpers::{Height, ValidatorId};
use exonum::crypto::gen_keypair;
use exonum::storage::Snapshot;

use exonum_time::{TimeService, TimeSchema, TxTime, Time, TimeProvider};
use exonum_testkit::{TestKitBuilder, TestNode};

fn verify_data<T: AsRef<Snapshot>>(
    snapshot: T,
    validators: &[TestNode],
    expected_current_time: Option<SystemTime>,
    expected_validators_times: &[Option<SystemTime>],
) {
    let schema = TimeSchema::new(snapshot);

    assert_eq!(
        schema.time().get().map(|time| time.time()),
        expected_current_time
    );

    let validators_times = schema.validators_time();
    for (i, validator) in validators.iter().enumerate() {
        let public_key = &validator.public_keys().service_key;

        assert_eq!(
            validators_times.get(public_key).map(|time| time.time()),
            expected_validators_times[i]
        );
    }
}

#[test]
fn test_exonum_time_service_with_3_validators() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(3)
        .with_service(TimeService::new())
        .create();

    let validators = testkit.network().validators().to_vec();

    // Validators time, that is saved in storage, look like this:
    // number | 0    | 1    | 2    |
    // time   | None | None | None |
    //
    // Consolidated time is None.

    verify_data(&testkit.snapshot(), &validators, None, &[None, None, None]);

    // Add first transaction `tx0` from first validator with time `time0`.
    // After that validators time look like this:
    // number | 0       | 1    | 2    |
    // time   | `time0` | None | None |
    //
    // Consolidated time will have the value `time0`.

    let time0 = SystemTime::now();
    let tx0 = {
        let (pub_key, sec_key) = validators[0].service_keypair();
        TxTime::new(time0, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx0]);

    verify_data(
        &testkit.snapshot(),
        &validators,
        Some(time0),
        &[Some(time0), None, None],
    );

    // Add second transaction `tx1` from second validator with time `time1` = `time0` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2    |
    // time   | `time0` | `time1` | None |
    //
    // In sorted order: `time1` >= `time0`.
    // Consolidated time will have the value `time1`.

    let time1 = time0 + Duration::new(10, 0);
    let tx1 = {
        let (pub_key, sec_key) = validators[1].service_keypair();
        TxTime::new(time1, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx1]);

    verify_data(
        &testkit.snapshot(),
        &validators,
        Some(time1),
        &[Some(time0), Some(time1), None],
    );
}

#[test]
fn test_exonum_time_service_with_4_validators() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(4)
        .with_service(TimeService::new())
        .create();

    let validators = testkit.network().validators().to_vec();

    // Validators time, that is saved in storage, look like this:
    // number | 0    | 1    | 2    | 3    |
    // time   | None | None | None | None |
    //
    // max_byzantine_nodes = (4 - 1) / 3 = 1.
    //
    // Consolidated time is None.

    verify_data(
        testkit.snapshot(),
        &validators,
        None,
        &[None, None, None, None],
    );

    // Add first transaction `tx0` from first validator with time `time0`.
    // After that validators time look like this:
    // number | 0       | 1    | 2    | 3    |
    // time   | `time0` | None | None | None |
    //
    // Consolidated time doesn't change.

    let time0 = SystemTime::now();
    let tx0 = {
        let (pub_key, sec_key) = validators[0].service_keypair();
        TxTime::new(time0, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx0]);

    verify_data(
        &testkit.snapshot(),
        &validators,
        None,
        &[Some(time0), None, None, None],
    );

    // Add second transaction `tx1` from second validator with time `time1` = `time0` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2    | 3    |
    // time   | `time0` | `time1` | None | None |
    //
    // In sorted order: `time1` >= `time0`.
    // Consolidated time doesn't change.

    let time1 = time0 + Duration::new(10, 0);
    let tx1 = {
        let (pub_key, sec_key) = validators[1].service_keypair();
        TxTime::new(time1, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx1]);

    verify_data(
        &testkit.snapshot(),
        &validators,
        None,
        &[Some(time0), Some(time1), None, None],
    );

    // Add third transaction `tx2` from third validator with time `time2` = `time1` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2       | 3    |
    // time   | `time0` | `time1` | `time2` | None |
    //
    // In sorted order: `time2` >= `time1` >= `time0`.
    // Consolidated time will have the value `time1`.

    let time2 = time1 + Duration::new(10, 0);
    let tx2 = {
        let (pub_key, sec_key) = validators[2].service_keypair();
        TxTime::new(time2, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx2]);

    verify_data(
        &testkit.snapshot(),
        &validators,
        Some(time1),
        &[Some(time0), Some(time1), Some(time2), None],
    );

    // Add fourth transaction `tx3` from fourth validator with time `time3` = `time2` + 10 sec.
    // After that validators time look like this:
    // number | 0       | 1       | 2       | 3       |
    // time   | `time0` | `time1` | `time2` | `time3` |
    //
    // In sorted order: `time3` >= `time2` >= `time1` >= `time0`.
    // Consolidated time will have the value `time2`.

    let time3 = time2 + Duration::new(10, 0);
    let tx3 = {
        let (pub_key, sec_key) = validators[3].service_keypair();
        TxTime::new(time3, pub_key, sec_key)
    };
    testkit.create_block_with_transactions(txvec![tx3]);

    verify_data(
        &testkit.snapshot(),
        &validators,
        Some(time2),
        &[Some(time0), Some(time1), Some(time2), Some(time3)],
    );
}

// A struct that provides the node with the current time.
#[derive(Debug)]
struct MyTimeProvider;
impl TimeProvider for MyTimeProvider {
    fn current_time(&self) -> SystemTime {
        UNIX_EPOCH
    }
}

#[test]
fn test_mock_provider() {
    // Create a simple testkit network.
    let mut testkit = TestKitBuilder::validator()
        .with_service(TimeService::with_provider(
            Box::new(MyTimeProvider) as Box<TimeProvider>,
        ))
        .create();

    // Get the validator public key.
    let validator_public_key = &testkit.network().validators().to_vec()[0]
        .public_keys()
        .service_key;

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    // Check that the blockchain does not contain time.
    assert_eq!(schema.time().get(), None);
    // Check that the time for the validator is unknown.
    assert_eq!(schema.validators_time().get(validator_public_key), None);

    // Create two blocks.
    testkit.create_blocks_until(Height(2));

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    // Check that the time in the blockchain and for the validator has been updated.
    assert_eq!(schema.time().get(), Some(Time::new(UNIX_EPOCH)));
    assert_eq!(
        schema.validators_time().get(validator_public_key),
        Some(Time::new(UNIX_EPOCH))
    );
}

#[test]
fn test_selected_time_less_than_time_in_storage() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(1)
        .with_service(TimeService::new())
        .create();

    let validators = testkit.network().validators().to_vec();

    let (pub_key_0, _) = validators[0].service_keypair();

    let cfg_change_height = Height(5);
    let new_cfg = {
        let mut cfg = testkit.configuration_change_proposal();
        cfg.set_validators(vec![TestNode::new_validator(ValidatorId(0))]);
        cfg.set_actual_from(cfg_change_height);
        cfg
    };
    testkit.commit_configuration_change(new_cfg);
    testkit.create_blocks_until(cfg_change_height.previous());

    let validators = testkit.network().validators().to_vec();
    let (pub_key_1, sec_key_1) = validators[0].service_keypair();

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    assert!(schema.time().get().is_some());
    assert!(schema.validators_time().get(pub_key_0).is_some());
    assert!(schema.validators_time().get(pub_key_1).is_none());
    assert_eq!(schema.time().get(), schema.validators_time().get(pub_key_0));

    if let Some(time_in_storage) = schema.time().get() {
        let time_tx = time_in_storage.time() - Duration::new(10, 0);
        let tx = {
            TxTime::new(time_tx, pub_key_1, sec_key_1)
        };
        testkit.create_block_with_transactions(txvec![tx]);
    }

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);
    assert!(schema.time().get().is_some());
    assert!(schema.validators_time().get(pub_key_0).is_some());
    assert!(schema.validators_time().get(pub_key_1).is_some());
    assert_eq!(schema.time().get(), schema.validators_time().get(pub_key_0));
}

#[test]
fn test_creating_transaction_is_not_validator() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(1)
        .with_service(TimeService::new())
        .create();

    let (pub_key, sec_key) = gen_keypair();
    let tx = TxTime::new(SystemTime::now(), &pub_key, &sec_key);
    testkit.create_block_with_transactions(txvec![tx]);

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);
    assert!(schema.time().get().is_none());
    assert!(schema.validators_time().get(&pub_key).is_none());
}

#[test]
fn test_transaction_time_less_than_validator_time_in_storage() {
    let mut testkit = TestKitBuilder::validator()
        .with_validators(1)
        .with_service(TimeService::new())
        .create();

    let validator = &testkit.network().validators().to_vec()[0];
    let (pub_key, sec_key) = validator.service_keypair();

    let time0 = SystemTime::now();
    let tx0 = TxTime::new(time0, pub_key, sec_key);

    testkit.create_block_with_transactions(txvec![tx0]);

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    assert_eq!(schema.time().get(), Some(Time::new(time0)));
    assert_eq!(
        schema.validators_time().get(pub_key),
        Some(Time::new(time0))
    );

    let time1 = time0 - Duration::new(10, 0);
    let tx1 = TxTime::new(time1, pub_key, sec_key);

    testkit.create_block_with_transactions(txvec![tx1]);

    let snapshot = testkit.snapshot();
    let schema = TimeSchema::new(snapshot);

    assert_eq!(schema.time().get(), Some(Time::new(time0)));
    assert_eq!(
        schema.validators_time().get(pub_key),
        Some(Time::new(time0))
    );
}
<|endoftext|>


<commit_before>//
//
//
//! Synchonisation primitives
use core::ops;
use core::sync::atomic::{AtomicUsize,Ordering};
use core::cell::UnsafeCell;

/// Primitive Mutex
pub struct Mutex<T>(AtomicUsize, UnsafeCell<T>);
unsafe impl<T: Send> Sync for Mutex<T> {}
unsafe impl<T: Send> Send for Mutex<T> {}
impl<T> Mutex<T>
{
	pub const fn new(v: T) -> Mutex<T> {
		Mutex( AtomicUsize::new(1), UnsafeCell::new(v) )
	}

	pub fn lock(&self) -> HeldMutex<T> {
		if self.0.fetch_sub(1, Ordering::Acquire) == 0 {
			HeldMutex { _ptr: self, }
		}
		else {
			panic!("TODO: Acquire Mutex when contended");
		}
	}

	pub fn unwrap(self) -> T {
		assert_eq!( self.0.load(Ordering::Relaxed), 0 );
		// SAFE: By-value self, so no aliasing
		unsafe { self.1.into_inner() }
	}
}

pub struct HeldMutex<'a, T: 'a> {
	_ptr: &'a Mutex<T>,
}
impl<'a, T: 'a> ops::Deref for HeldMutex<'a, T>
{
	type Target = T;

	fn deref(&self) -> &T {
		// SAFE: HeldMutex controls this memory
		unsafe { &*self._ptr.1.get() }
	}
}
impl<'a, T: 'a> ops::DerefMut for HeldMutex<'a, T>
{
	fn deref_mut(&mut self) -> &mut T {
		// SAFE: HeldMutex controls this memory
		unsafe { &mut *self._ptr.1.get() }
	}
}
impl<'a, T: 'a> ops::Drop for HeldMutex<'a, T>
{
	fn drop(&mut self) {
		if self._ptr.0.fetch_add(1, Ordering::Release) != 0 {
			panic!("TODO: Release Mutex when contended");
		}
	}
}

<commit_msg>Userland/syscalsl -  Fix Mutex<commit_after>//
//
//
//! Synchonisation primitives
use core::ops;
use core::sync::atomic::{AtomicUsize,Ordering};
use core::cell::UnsafeCell;

/// Primitive Mutex
pub struct Mutex<T>(AtomicUsize, UnsafeCell<T>);
unsafe impl<T: Send> Sync for Mutex<T> {}
unsafe impl<T: Send> Send for Mutex<T> {}
impl<T> Mutex<T>
{
	pub const fn new(v: T) -> Mutex<T> {
		Mutex( AtomicUsize::new(1), UnsafeCell::new(v) )
	}

	pub fn lock(&self) -> HeldMutex<T> {
		if self.0.fetch_sub(1, Ordering::Acquire) == 1 {
			HeldMutex { _ptr: self, }
		}
		else {
			panic!("TODO: Acquire Mutex when contended");
		}
	}

	pub fn unwrap(self) -> T {
		assert_eq!( self.0.load(Ordering::Relaxed), 0 );
		// SAFE: By-value self, so no aliasing
		unsafe { self.1.into_inner() }
	}
}

pub struct HeldMutex<'a, T: 'a> {
	_ptr: &'a Mutex<T>,
}
impl<'a, T: 'a> ops::Deref for HeldMutex<'a, T>
{
	type Target = T;

	fn deref(&self) -> &T {
		// SAFE: HeldMutex controls this memory
		unsafe { &*self._ptr.1.get() }
	}
}
impl<'a, T: 'a> ops::DerefMut for HeldMutex<'a, T>
{
	fn deref_mut(&mut self) -> &mut T {
		// SAFE: HeldMutex controls this memory
		unsafe { &mut *self._ptr.1.get() }
	}
}
impl<'a, T: 'a> ops::Drop for HeldMutex<'a, T>
{
	fn drop(&mut self) {
		if self._ptr.0.fetch_add(1, Ordering::Release) != 0 {
			panic!("TODO: Release Mutex when contended");
		}
	}
}

<|endoftext|>


<commit_before><commit_msg>Improve doc for thread_rng and EntropyRng.<commit_after><|endoftext|>


<commit_before><commit_msg>Add Promise::from_result and fix Promise::race<commit_after><|endoftext|>


<commit_before><commit_msg>Update for `Number` split in `serialize::json`<commit_after><|endoftext|>


<commit_before><commit_msg>Use functional style code :smile:<commit_after><|endoftext|>


<commit_before><commit_msg>First successful compilation of gross listener mapping processor<commit_after><|endoftext|>


<commit_before><commit_msg>Don't warn on an unknown allowed clippy lint<commit_after><|endoftext|>


<commit_before><commit_msg>Implement remove_link_at() to remove a link given it's index. Base remove_link() on this implementation<commit_after><|endoftext|>


<commit_before><commit_msg>Add parse function as a new entry point<commit_after><|endoftext|>


<commit_before><commit_msg>Added TOKEN.<commit_after><|endoftext|>


<commit_before><commit_msg>rust-rub works with buildable refactor<commit_after><|endoftext|>


<commit_before><commit_msg>Fix typo in lib.rs (#279)<commit_after><|endoftext|>


<commit_before><commit_msg>Fix postgres 9.0 typeinfo<commit_after><|endoftext|>


<commit_before><commit_msg>Canonicalize some free functions (1) equal<commit_after><|endoftext|>


<commit_before><commit_msg>fixed doc<commit_after><|endoftext|>


<commit_before><commit_msg>rewrite read! macro to not require public functions<commit_after><|endoftext|>


<commit_before><commit_msg>Remove lib.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Comment the remaining lit cases<commit_after><|endoftext|>


<commit_before>extern crate num;
use std::collections::BTreeSet;
use std::cmp;
use rand::Rng;
use std::ops::Range;
use std::iter::Rev;
use super::{Genetic, SISO};
use std::marker::PhantomData;

/// Defines an opcode for the Mep. Every opcode contains an instruction and two parameter indices. These specify which
/// previous opcodes produced the result required as inputs to this opcode. These parameters can also come from the inputs
/// to the program, which sequentially preceed the internal instructions.
#[derive(Debug, Clone, Copy)]
struct Opcode<Ins> {
    instruction: Ins,
    first: usize,
    second: usize,
}

/// A multi-expression program represented using a series of operations that can reuse results of previous operations.
#[derive(Debug)]
pub struct Mep<Ins, R, Param, F1, F2> {
    program: Vec<Opcode<Ins>>,
    pub unit_mutate_size: usize,
    pub crossover_points: usize,
    inputs: usize,
    outputs: usize,
    mutator: F1,
    processor: F2,
    _phantom: (PhantomData<R>, PhantomData<Param>),
}

impl<Ins, R, Param, F1, F2> Clone for Mep<Ins, R, Param, F1, F2>
    where Ins: Clone,
          F1: Copy,
          F2: Copy
{
    fn clone(&self) -> Self {
        Mep {
            program: self.program.clone(),
            unit_mutate_size: self.unit_mutate_size,
            crossover_points: self.crossover_points,
            inputs: self.inputs,
            outputs: self.outputs,
            mutator: self.mutator,
            processor: self.processor,
            _phantom: (PhantomData, PhantomData),
        }
    }
}

impl<Ins, R, Param, F1, F2> Mep<Ins, R, Param, F1, F2> {
    /// Generates a new Mep with a particular size and takes a closure to generate random instructions.
    /// Takes an RNG as well to generate random internal data for each instruction. This Rng is different from the Mep's
    /// Rng, thus it is parameterized separately here.
    pub fn new<I, Rg>(inputs: usize,
                      outputs: usize,
                      unit_mutate_size: usize,
                      crossover_points: usize,
                      rng: &mut Rg,
                      instruction_iter: I,
                      mutator: F1,
                      processor: F2)
                      -> Self
        where I: ExactSizeIterator<Item = Ins>,
              Rg: Rng,
              F1: Fn(&mut Ins, &mut R),
              F2: Fn(&Ins, Param, Param) -> Param
    {
        let outputs_beginning = instruction_iter.len() - outputs;
        Mep {
            program: instruction_iter.enumerate()
                .map(|(index, ins)|
                    // For normal instructions previous outputs may be used.
                    if index < outputs_beginning {
                        Opcode{
                            instruction: ins,
                            first: rng.gen_range(0, index + inputs),
                            second: rng.gen_range(0, index + inputs),
                        }
                    // An output should not be used as an input to another output.
                    } else {
                        Opcode{
                            instruction: ins,
                            first: rng.gen_range(0, outputs_beginning + inputs),
                            second: rng.gen_range(0, outputs_beginning + inputs),
                        }
                    })
                .collect(),
            unit_mutate_size: unit_mutate_size,
            crossover_points: crossover_points,
            inputs: inputs,
            outputs: outputs,
            mutator: mutator,
            processor: processor,
            _phantom: (PhantomData, PhantomData),
        }
    }
}

impl<Ins, R, Param, F1, F2> Genetic<R> for Mep<Ins, R, Param, F1, F2>
    where R: Rng,
          Ins: Clone,
          Param: Clone,
          F1: Copy + Fn(&mut Ins, &mut R),
          F2: Copy
{
    fn mate(parents: (&Self, &Self), rng: &mut R) -> Self {
        // Each Mep must have the same amount of inputs
        // TODO: Once Rust implements generic values, this can be made explicit and is not needed
        assert!(parents.0.inputs == parents.1.inputs);
        assert!(parents.0.outputs == parents.1.outputs);
        // Get the smallest of the two lengths
        let total_instructions = cmp::min(parents.0.program.len(), parents.1.program.len());
        let crossover_choice = rng.gen_range(0, 2);
        Mep{program:
            //Generate a randomly sized sequence between 1 and crossover_points
            (0..rng.gen_range(1, cmp::min(total_instructions / 2, {
                if crossover_choice == 0 {parents.0}
                else {parents.1}}.crossover_points + 1)))
            //Map these to random crossover points
            .map(|_| rng.gen_range(0, total_instructions))
            //Add total_instructions at the end so we can generate a range with it
            .chain(Some(total_instructions))
            //Sort them by value into BTree, which removes duplicates and orders them
            .fold(BTreeSet::new(), |mut set, i| {set.insert(i); set})
            //Iterate over the sorted values
            .iter()
            //Turn every copy of two, prepending a 0, into a range
            .scan(0, |prev, x| {let out = Some(*prev..*x); *prev = *x; out})
            //Enumerate by index to differentiate odd and even values
            .enumerate()
            //Map even pairs to ranges in parent 0 and odd ones to ranges in parent 1 and expand the ranges
            .flat_map(|(index, range)| {
                {if index % 2 == 0 {parents.0} else {parents.1}}.program[range].iter().cloned()
            })
            //Collect all the instruction ranges from each parent
            .collect(),

            unit_mutate_size: if parents.0.unit_mutate_size < parents.1.unit_mutate_size {
                rng.gen_range(parents.0.unit_mutate_size, parents.1.unit_mutate_size + 1)
            } else {
                rng.gen_range(parents.1.unit_mutate_size, parents.0.unit_mutate_size + 1)
            },

            crossover_points: if parents.0.crossover_points < parents.1.crossover_points {
                rng.gen_range(parents.0.crossover_points, parents.1.crossover_points + 1)
            } else {
                rng.gen_range(parents.1.crossover_points, parents.0.crossover_points + 1)
            },

            inputs: parents.0.inputs,
            outputs: parents.0.outputs,
            mutator: {if rng.gen_range(0, 2) == 0 {parents.0} else {parents.1}}.mutator,
            processor: {if rng.gen_range(0, 2) == 0 {parents.0} else {parents.1}}.processor,
            _phantom: (PhantomData, PhantomData),
        }
    }

    /// The Mep mutate function operates using the unit_mutate_size. This variable specifies the amount of instructions
    /// for which a single mutation is expect to occour every time mutate is called. This variable can be mutated inside
    /// of mutate, in which case it may never go below 1, but may tend towards infinity in increments of 1. This variable
    /// is implemented as a u64 to permit it to expand unbounded to mutation levels that are so low that mutations
    /// virtually never happen. Allowing this to mutate allows species to find the equilibrium between genomic
    /// adaptability and stability. If a species develops information gathering, then it can adapt intellegently, making
    /// it possibly more beneficial to operate at lower mutation rates. Setting the default mutation rate for species
    /// properly, or allowing it to adapt as the simulation continues, permits species to survive more frequently that
    /// are randomly generated.
    fn mutate(&mut self, rng: &mut R) {
        // Mutate unit_mutate_size
        if rng.gen_range(0, self.unit_mutate_size) == 0 {
            // Make it possibly go up or down by 1
            match rng.gen_range(0, 2) {
                0 => self.unit_mutate_size += 1,
                1 => {
                    if self.unit_mutate_size > 1 {
                        self.unit_mutate_size -= 1
                    }
                }
                _ => unreachable!(),
            }
        }
        // Mutate crossover_points
        if rng.gen_range(0, self.unit_mutate_size) == 0 {
            // Make it possibly go up or down by 1
            match rng.gen_range(0, 2) {
                0 => self.crossover_points += 1,
                1 => {
                    if self.crossover_points > 1 {
                        self.crossover_points -= 1
                    }
                }
                _ => unreachable!(),
            }
        }

        // Mutate the instructions using the mutator
        loop {
            // Choose a random location in the instructions and then add a random value up to the unit_mutate_size
            let choice = rng.gen_range(0, self.program.len() + self.unit_mutate_size);
            // Whenever we choose a location outside the vector reject the choice and end mutation
            if choice >= self.program.len() {
                break;
            }
            let op = &mut self.program[choice];
            // Randomly mutate only one of the things contained here
            match rng.gen_range(0, 3) {
                0 => (self.mutator)(&mut op.instruction, rng),
                1 => op.first = rng.gen_range(0, choice + self.inputs),
                2 => op.second = rng.gen_range(0, choice + self.inputs),
                _ => unreachable!(),
            }
        }
    }
}

impl<'a, Ins: 'a, R: 'a, Param: 'a, F1: 'a, F2: 'a> SISO<'a, Param, Param> for Mep<Ins,
                                                                                R,
                                                                                Param,
                                                                                F1,
                                                                                F2>
    where F2: Fn(&Ins, Param, Param) -> Param,
          Param: Clone
{
    type Iter = ResultIterator<'a, Ins, R, Param, F1, F2>;

    fn compute(&'a self, inputs: &'a [Param]) -> Self::Iter {
        // Ensure we have enough opcodes to produce the desired amount of outputs, otherwise the programmer has failed
        assert!(self.outputs <= self.program.len());
        ResultIterator {
            mep: self,
            buff: vec![None; self.program.len()],
            solve_iter: ((self.program.len() + self.inputs - self.outputs)..(self.program.len() +
                                                                             self.inputs))
                .rev(),
            inputs: inputs,
        }
    }
}

pub struct ResultIterator<'a, Ins: 'a, R: 'a, Param: 'a, F1: 'a, F2: 'a> {
    mep: &'a Mep<Ins, R, Param, F1, F2>,
    buff: Vec<Option<Param>>,
    solve_iter: Rev<Range<usize>>,
    inputs: &'a [Param],
}

impl<'a, Ins, R, Param, F1, F2> ResultIterator<'a, Ins, R, Param, F1, F2>
    where F2: Fn(&Ins, Param, Param) -> Param,
          Param: Clone
{
    fn op_solved(&mut self, i: usize) -> Param {
        // If this is an input, it is already solved, so return the result immediately
        if i < self.mep.inputs {
            return unsafe { self.inputs.get_unchecked(i) }.clone();
        }
        // Check if this has been evaluated or not
        let possible = unsafe { self.buff.get_unchecked(i - self.mep.inputs) }.clone();
        match possible {
            // If it has, return the value
            Some(x) => x,
            // If it hasnt been solved
            None => {
                // Get a reference to the opcode
                let op = unsafe { self.mep.program.get_unchecked(i - self.mep.inputs) };
                // Compute the result of the operation, ensuring the inputs are solved beforehand
                let result = (self.mep.processor)(&op.instruction,
                                                  self.op_solved(op.first),
                                                  self.op_solved(op.second));
                // Properly store the Some result to the buffer
                unsafe { *self.buff.get_unchecked_mut(i - self.mep.inputs) = Some(result.clone()) };
                // Return the result
                result
            }
        }
    }
}

impl<'a, Ins, R, Param, F1, F2> Iterator for ResultIterator<'a, Ins, R, Param, F1, F2>
    where F2: Fn(&Ins, Param, Param) -> Param,
          Param: Clone
{
    type Item = Param;
    fn next(&mut self) -> Option<Param> {
        match self.solve_iter.next() {
            None => None,
            Some(i) => Some(self.op_solved(i)),
        }
    }
}

#[cfg(test)]
mod tests {
    use rand::{Isaac64Rng, SeedableRng, Rng};
    use super::*;
    use super::super::{Genetic, SISO};

    fn mutator(_: &mut i32, _: &mut Isaac64Rng) {}
    fn processor(_: &i32, _: i32, _: i32) -> i32 {
        0
    }

    #[test]
    fn new() {
        let a = Mep::new(3,
                         1,
                         10,
                         10,
                         &mut Isaac64Rng::from_seed(&[1, 2, 3, 4]),
                         0..30,
                         mutator,
                         processor);

        assert_eq!(a.program.iter().map(|i| i.instruction).collect::<Vec<_>>(),
                   (0..30).collect::<Vec<_>>());
    }

    #[test]
    fn crossover() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let (a, b) = {
            let mut clos = || Mep::new(3, 1, 10, 10, &mut rng, 0..30, mutator, processor);
            (clos(), clos())
        };
        let old_rngs: Vec<_> = rng.clone().gen_iter::<i32>().take(5).collect();
        let _ = Mep::mate((&a, &b), &mut rng);
        // Ensure that rng was borrowed mutably
        assert!(rng.clone().gen_iter::<i32>().take(5).collect::<Vec<_>>() != old_rngs);
    }

    #[test]
    fn compute() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let a = Mep::new(3, 1, 10, 10, &mut rng, 0..30, mutator, processor);

        let inputs = [2, 3, 4];
        assert_eq!(a.compute(&inputs[..]).collect::<Vec<_>>(), [0]);
    }
}
<commit_msg>add legit Debug implementation<commit_after>extern crate num;
use std::collections::BTreeSet;
use std::cmp;
use rand::Rng;
use std::ops::Range;
use std::iter::Rev;
use super::{Genetic, SISO};
use std::marker::PhantomData;
use std::fmt::{self, Debug};

/// Defines an opcode for the Mep. Every opcode contains an instruction and two parameter indices. These specify which
/// previous opcodes produced the result required as inputs to this opcode. These parameters can also come from the inputs
/// to the program, which sequentially preceed the internal instructions.
#[derive(Debug, Clone, Copy)]
struct Opcode<Ins> {
    instruction: Ins,
    first: usize,
    second: usize,
}

/// A multi-expression program represented using a series of operations that can reuse results of previous operations.
pub struct Mep<Ins, R, Param, F1, F2> {
    program: Vec<Opcode<Ins>>,
    pub unit_mutate_size: usize,
    pub crossover_points: usize,
    inputs: usize,
    outputs: usize,
    mutator: F1,
    processor: F2,
    _phantom: (PhantomData<R>, PhantomData<Param>),
}

impl<Ins, R, Param, F1, F2> Debug for Mep<Ins, R, Param, F1, F2>
    where Ins: Debug
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // write!(f, "Mep{{ program: {}, unit_mutate_size: {}, crossover_points: {}, inputs: {}, outputs: {} }}", )
        try!(write!(f, "Mep{{ program: ["));
        if self.program.len() != 0 {
            for op in &self.program[..self.program.len() - 1] {
                try!(write!(f, "{:?}, ", op));
            }
            try!(write!(f, "{:?}", self.program.last().unwrap()));
        }
        write!(f,
               "], unit_mutate_size: {}, crossover_points: {}, inputs: {}, outputs: {} }}",
               self.unit_mutate_size,
               self.crossover_points,
               self.inputs,
               self.outputs)
    }
}

impl<Ins, R, Param, F1, F2> Clone for Mep<Ins, R, Param, F1, F2>
    where Ins: Clone,
          F1: Copy,
          F2: Copy
{
    fn clone(&self) -> Self {
        Mep {
            program: self.program.clone(),
            unit_mutate_size: self.unit_mutate_size,
            crossover_points: self.crossover_points,
            inputs: self.inputs,
            outputs: self.outputs,
            mutator: self.mutator,
            processor: self.processor,
            _phantom: (PhantomData, PhantomData),
        }
    }
}

impl<Ins, R, Param, F1, F2> Mep<Ins, R, Param, F1, F2> {
    /// Generates a new Mep with a particular size and takes a closure to generate random instructions.
    /// Takes an RNG as well to generate random internal data for each instruction. This Rng is different from the Mep's
    /// Rng, thus it is parameterized separately here.
    pub fn new<I, Rg>(inputs: usize,
                      outputs: usize,
                      unit_mutate_size: usize,
                      crossover_points: usize,
                      rng: &mut Rg,
                      instruction_iter: I,
                      mutator: F1,
                      processor: F2)
                      -> Self
        where I: ExactSizeIterator<Item = Ins>,
              Rg: Rng,
              F1: Fn(&mut Ins, &mut R),
              F2: Fn(&Ins, Param, Param) -> Param
    {
        let outputs_beginning = instruction_iter.len() - outputs;
        Mep {
            program: instruction_iter.enumerate()
                .map(|(index, ins)|
                    // For normal instructions previous outputs may be used.
                    if index < outputs_beginning {
                        Opcode{
                            instruction: ins,
                            first: rng.gen_range(0, index + inputs),
                            second: rng.gen_range(0, index + inputs),
                        }
                    // An output should not be used as an input to another output.
                    } else {
                        Opcode{
                            instruction: ins,
                            first: rng.gen_range(0, outputs_beginning + inputs),
                            second: rng.gen_range(0, outputs_beginning + inputs),
                        }
                    })
                .collect(),
            unit_mutate_size: unit_mutate_size,
            crossover_points: crossover_points,
            inputs: inputs,
            outputs: outputs,
            mutator: mutator,
            processor: processor,
            _phantom: (PhantomData, PhantomData),
        }
    }
}

impl<Ins, R, Param, F1, F2> Genetic<R> for Mep<Ins, R, Param, F1, F2>
    where R: Rng,
          Ins: Clone,
          Param: Clone,
          F1: Copy + Fn(&mut Ins, &mut R),
          F2: Copy
{
    fn mate(parents: (&Self, &Self), rng: &mut R) -> Self {
        // Each Mep must have the same amount of inputs
        // TODO: Once Rust implements generic values, this can be made explicit and is not needed
        assert!(parents.0.inputs == parents.1.inputs);
        assert!(parents.0.outputs == parents.1.outputs);
        // Get the smallest of the two lengths
        let total_instructions = cmp::min(parents.0.program.len(), parents.1.program.len());
        let crossover_choice = rng.gen_range(0, 2);
        Mep{program:
            //Generate a randomly sized sequence between 1 and crossover_points
            (0..rng.gen_range(1, cmp::min(total_instructions / 2, {
                if crossover_choice == 0 {parents.0}
                else {parents.1}}.crossover_points + 1)))
            //Map these to random crossover points
            .map(|_| rng.gen_range(0, total_instructions))
            //Add total_instructions at the end so we can generate a range with it
            .chain(Some(total_instructions))
            //Sort them by value into BTree, which removes duplicates and orders them
            .fold(BTreeSet::new(), |mut set, i| {set.insert(i); set})
            //Iterate over the sorted values
            .iter()
            //Turn every copy of two, prepending a 0, into a range
            .scan(0, |prev, x| {let out = Some(*prev..*x); *prev = *x; out})
            //Enumerate by index to differentiate odd and even values
            .enumerate()
            //Map even pairs to ranges in parent 0 and odd ones to ranges in parent 1 and expand the ranges
            .flat_map(|(index, range)| {
                {if index % 2 == 0 {parents.0} else {parents.1}}.program[range].iter().cloned()
            })
            //Collect all the instruction ranges from each parent
            .collect(),

            unit_mutate_size: if parents.0.unit_mutate_size < parents.1.unit_mutate_size {
                rng.gen_range(parents.0.unit_mutate_size, parents.1.unit_mutate_size + 1)
            } else {
                rng.gen_range(parents.1.unit_mutate_size, parents.0.unit_mutate_size + 1)
            },

            crossover_points: if parents.0.crossover_points < parents.1.crossover_points {
                rng.gen_range(parents.0.crossover_points, parents.1.crossover_points + 1)
            } else {
                rng.gen_range(parents.1.crossover_points, parents.0.crossover_points + 1)
            },

            inputs: parents.0.inputs,
            outputs: parents.0.outputs,
            mutator: {if rng.gen_range(0, 2) == 0 {parents.0} else {parents.1}}.mutator,
            processor: {if rng.gen_range(0, 2) == 0 {parents.0} else {parents.1}}.processor,
            _phantom: (PhantomData, PhantomData),
        }
    }

    /// The Mep mutate function operates using the unit_mutate_size. This variable specifies the amount of instructions
    /// for which a single mutation is expect to occour every time mutate is called. This variable can be mutated inside
    /// of mutate, in which case it may never go below 1, but may tend towards infinity in increments of 1. This variable
    /// is implemented as a u64 to permit it to expand unbounded to mutation levels that are so low that mutations
    /// virtually never happen. Allowing this to mutate allows species to find the equilibrium between genomic
    /// adaptability and stability. If a species develops information gathering, then it can adapt intellegently, making
    /// it possibly more beneficial to operate at lower mutation rates. Setting the default mutation rate for species
    /// properly, or allowing it to adapt as the simulation continues, permits species to survive more frequently that
    /// are randomly generated.
    fn mutate(&mut self, rng: &mut R) {
        // Mutate unit_mutate_size
        if rng.gen_range(0, self.unit_mutate_size) == 0 {
            // Make it possibly go up or down by 1
            match rng.gen_range(0, 2) {
                0 => self.unit_mutate_size += 1,
                1 => {
                    if self.unit_mutate_size > 1 {
                        self.unit_mutate_size -= 1
                    }
                }
                _ => unreachable!(),
            }
        }
        // Mutate crossover_points
        if rng.gen_range(0, self.unit_mutate_size) == 0 {
            // Make it possibly go up or down by 1
            match rng.gen_range(0, 2) {
                0 => self.crossover_points += 1,
                1 => {
                    if self.crossover_points > 1 {
                        self.crossover_points -= 1
                    }
                }
                _ => unreachable!(),
            }
        }

        // Mutate the instructions using the mutator
        loop {
            // Choose a random location in the instructions and then add a random value up to the unit_mutate_size
            let choice = rng.gen_range(0, self.program.len() + self.unit_mutate_size);
            // Whenever we choose a location outside the vector reject the choice and end mutation
            if choice >= self.program.len() {
                break;
            }
            let op = &mut self.program[choice];
            // Randomly mutate only one of the things contained here
            match rng.gen_range(0, 3) {
                0 => (self.mutator)(&mut op.instruction, rng),
                1 => op.first = rng.gen_range(0, choice + self.inputs),
                2 => op.second = rng.gen_range(0, choice + self.inputs),
                _ => unreachable!(),
            }
        }
    }
}

impl<'a, Ins: 'a, R: 'a, Param: 'a, F1: 'a, F2: 'a> SISO<'a, Param, Param> for Mep<Ins,
                                                                                R,
                                                                                Param,
                                                                                F1,
                                                                                F2>
    where F2: Fn(&Ins, Param, Param) -> Param,
          Param: Clone
{
    type Iter = ResultIterator<'a, Ins, R, Param, F1, F2>;

    fn compute(&'a self, inputs: &'a [Param]) -> Self::Iter {
        // Ensure we have enough opcodes to produce the desired amount of outputs, otherwise the programmer has failed
        assert!(self.outputs <= self.program.len());
        ResultIterator {
            mep: self,
            buff: vec![None; self.program.len()],
            solve_iter: ((self.program.len() + self.inputs - self.outputs)..(self.program.len() +
                                                                             self.inputs))
                .rev(),
            inputs: inputs,
        }
    }
}

pub struct ResultIterator<'a, Ins: 'a, R: 'a, Param: 'a, F1: 'a, F2: 'a> {
    mep: &'a Mep<Ins, R, Param, F1, F2>,
    buff: Vec<Option<Param>>,
    solve_iter: Rev<Range<usize>>,
    inputs: &'a [Param],
}

impl<'a, Ins, R, Param, F1, F2> ResultIterator<'a, Ins, R, Param, F1, F2>
    where F2: Fn(&Ins, Param, Param) -> Param,
          Param: Clone
{
    fn op_solved(&mut self, i: usize) -> Param {
        // If this is an input, it is already solved, so return the result immediately
        if i < self.mep.inputs {
            return unsafe { self.inputs.get_unchecked(i) }.clone();
        }
        // Check if this has been evaluated or not
        let possible = unsafe { self.buff.get_unchecked(i - self.mep.inputs) }.clone();
        match possible {
            // If it has, return the value
            Some(x) => x,
            // If it hasnt been solved
            None => {
                // Get a reference to the opcode
                let op = unsafe { self.mep.program.get_unchecked(i - self.mep.inputs) };
                // Compute the result of the operation, ensuring the inputs are solved beforehand
                let result = (self.mep.processor)(&op.instruction,
                                                  self.op_solved(op.first),
                                                  self.op_solved(op.second));
                // Properly store the Some result to the buffer
                unsafe { *self.buff.get_unchecked_mut(i - self.mep.inputs) = Some(result.clone()) };
                // Return the result
                result
            }
        }
    }
}

impl<'a, Ins, R, Param, F1, F2> Iterator for ResultIterator<'a, Ins, R, Param, F1, F2>
    where F2: Fn(&Ins, Param, Param) -> Param,
          Param: Clone
{
    type Item = Param;
    fn next(&mut self) -> Option<Param> {
        match self.solve_iter.next() {
            None => None,
            Some(i) => Some(self.op_solved(i)),
        }
    }
}

#[cfg(test)]
mod tests {
    use rand::{Isaac64Rng, SeedableRng, Rng};
    use super::*;
    use super::super::{Genetic, SISO};

    fn mutator(_: &mut i32, _: &mut Isaac64Rng) {}
    fn processor(_: &i32, _: i32, _: i32) -> i32 {
        0
    }

    #[test]
    fn new() {
        let a = Mep::new(3,
                         1,
                         10,
                         10,
                         &mut Isaac64Rng::from_seed(&[1, 2, 3, 4]),
                         0..30,
                         mutator,
                         processor);

        assert_eq!(a.program.iter().map(|i| i.instruction).collect::<Vec<_>>(),
                   (0..30).collect::<Vec<_>>());
    }

    #[test]
    fn crossover() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let (a, b) = {
            let mut clos = || Mep::new(3, 1, 10, 10, &mut rng, 0..30, mutator, processor);
            (clos(), clos())
        };
        let old_rngs: Vec<_> = rng.clone().gen_iter::<i32>().take(5).collect();
        let _ = Mep::mate((&a, &b), &mut rng);
        // Ensure that rng was borrowed mutably
        assert!(rng.clone().gen_iter::<i32>().take(5).collect::<Vec<_>>() != old_rngs);
    }

    #[test]
    fn compute() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let a = Mep::new(3, 1, 10, 10, &mut rng, 0..30, mutator, processor);

        let inputs = [2, 3, 4];
        assert_eq!(a.compute(&inputs[..]).collect::<Vec<_>>(), [0]);
    }
}
<|endoftext|>


<commit_before>use rustc::lint::*;
use rustc::middle::ty::TypeVariants;
use rustc_front::hir::*;
use syntax::codemap::Span;
use syntax::ptr::P;
use utils::{BOX_NEW_PATH, VEC_FROM_ELEM_PATH};
use utils::{is_expn_of, match_path, snippet, span_lint_and_then};

/// **What it does:** This lint warns about using `&vec![..]` when using `&[..]` would be possible.
///
/// **Why is this bad?** This is less efficient.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust,ignore
/// foo(&vec![1, 2])
/// ```
declare_lint! {
    pub USELESS_VEC,
    Warn,
    "useless `vec!`"
}

#[derive(Copy, Clone, Debug)]
pub struct UselessVec;

impl LintPass for UselessVec {
    fn get_lints(&self) -> LintArray {
        lint_array!(USELESS_VEC)
    }
}

impl LateLintPass for UselessVec {
    fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
        unexpand_vec(cx, expr);

        // search for `&!vec[_]` expressions where the adjusted type is `&[_]`
        if_let_chain!{[
            let TypeVariants::TyRef(_, ref ty) = cx.tcx.expr_ty_adjusted(expr).sty,
            let TypeVariants::TySlice(..) = ty.ty.sty,
            let ExprAddrOf(_, ref addressee) = expr.node,
            let Some(vec_args) = unexpand_vec(cx, addressee)
        ], {
            let snippet = match vec_args {
                VecArgs::Repeat(elem, len) => {
                    format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into()
                }
                VecArgs::Vec(args) => {
                    if let Some(last) = args.iter().last() {
                        let span = Span {
                            lo: args[0].span.lo,
                            hi: last.span.hi,
                            expn_id: args[0].span.expn_id,
                        };

                        format!("&[{}]", snippet(cx, span, "..")).into()
                    }
                    else {
                        "&[]".into()
                    }
                }
            };

            span_lint_and_then(cx, USELESS_VEC, expr.span, "useless use of `vec!`", |db| {
                db.span_suggestion(expr.span, "you can use a slice directly", snippet);
            });
        }}
    }
}

/// Represent the pre-expansion arguments of a `vec!` invocation.
pub enum VecArgs<'a> {
    /// `vec![elem, len]`
    Repeat(&'a P<Expr>, &'a P<Expr>),
    /// `vec![a, b, c]`
    Vec(&'a [P<Expr>]),
}

/// Returns the arguments of the `vec!` macro if this expression was expanded from `vec!`.
pub fn unexpand_vec<'e>(cx: &LateContext, expr: &'e Expr) -> Option<VecArgs<'e>> {
    if_let_chain!{[
        let ExprCall(ref fun, ref args) = expr.node,
        let ExprPath(_, ref path) = fun.node,
        is_expn_of(cx, fun.span, "vec").is_some()
    ], {
        return if match_path(path, &VEC_FROM_ELEM_PATH) && args.len() == 2 {
            // `vec![elem; size]` case
            Some(VecArgs::Repeat(&args[0], &args[1]))
        }
        else if match_path(path, &["into_vec"]) && args.len() == 1 {
            // `vec![a, b, c]` case
            if_let_chain!{[
                let ExprCall(ref fun, ref args) = args[0].node,
                let ExprPath(_, ref path) = fun.node,
                match_path(path, &BOX_NEW_PATH) && args.len() == 1,
                let ExprVec(ref args) = args[0].node
            ], {
                return Some(VecArgs::Vec(&*args));
            }}

            None
        }
        else {
            None
        };
    }}

    None
}
<commit_msg>`vec!` now uses `box`<commit_after>use rustc::lint::*;
use rustc::middle::ty::TypeVariants;
use rustc_front::hir::*;
use syntax::codemap::Span;
use syntax::ptr::P;
use utils::VEC_FROM_ELEM_PATH;
use utils::{is_expn_of, match_path, snippet, span_lint_and_then};

/// **What it does:** This lint warns about using `&vec![..]` when using `&[..]` would be possible.
///
/// **Why is this bad?** This is less efficient.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust,ignore
/// foo(&vec![1, 2])
/// ```
declare_lint! {
    pub USELESS_VEC,
    Warn,
    "useless `vec!`"
}

#[derive(Copy, Clone, Debug)]
pub struct UselessVec;

impl LintPass for UselessVec {
    fn get_lints(&self) -> LintArray {
        lint_array!(USELESS_VEC)
    }
}

impl LateLintPass for UselessVec {
    fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
        // search for `&vec![_]` expressions where the adjusted type is `&[_]`
        if_let_chain!{[
            let TypeVariants::TyRef(_, ref ty) = cx.tcx.expr_ty_adjusted(expr).sty,
            let TypeVariants::TySlice(..) = ty.ty.sty,
            let ExprAddrOf(_, ref addressee) = expr.node,
            let Some(vec_args) = unexpand_vec(cx, addressee)
        ], {
            let snippet = match vec_args {
                VecArgs::Repeat(elem, len) => {
                    format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into()
                }
                VecArgs::Vec(args) => {
                    if let Some(last) = args.iter().last() {
                        let span = Span {
                            lo: args[0].span.lo,
                            hi: last.span.hi,
                            expn_id: args[0].span.expn_id,
                        };

                        format!("&[{}]", snippet(cx, span, "..")).into()
                    }
                    else {
                        "&[]".into()
                    }
                }
            };

            span_lint_and_then(cx, USELESS_VEC, expr.span, "useless use of `vec!`", |db| {
                db.span_suggestion(expr.span, "you can use a slice directly", snippet);
            });
        }}
    }
}

/// Represent the pre-expansion arguments of a `vec!` invocation.
pub enum VecArgs<'a> {
    /// `vec![elem; len]`
    Repeat(&'a P<Expr>, &'a P<Expr>),
    /// `vec![a, b, c]`
    Vec(&'a [P<Expr>]),
}

/// Returns the arguments of the `vec!` macro if this expression was expanded from `vec!`.
pub fn unexpand_vec<'e>(cx: &LateContext, expr: &'e Expr) -> Option<VecArgs<'e>> {
    if_let_chain!{[
        let ExprCall(ref fun, ref args) = expr.node,
        let ExprPath(_, ref path) = fun.node,
        is_expn_of(cx, fun.span, "vec").is_some()
    ], {
        return if match_path(path, &VEC_FROM_ELEM_PATH) && args.len() == 2 {
            // `vec![elem; size]` case
            Some(VecArgs::Repeat(&args[0], &args[1]))
        }
        else if match_path(path, &["into_vec"]) && args.len() == 1 {
            // `vec![a, b, c]` case
            if_let_chain!{[
                let ExprBox(ref boxed) = args[0].node,
                let ExprVec(ref args) = boxed.node
            ], {
                return Some(VecArgs::Vec(&*args));
            }}

            None
        }
        else {
            None
        };
    }}

    None
}
<|endoftext|>


<commit_before>struct Stack {
    content: Vec<i32>,
    digits: Vec<i32>,
}

impl Stack {
    fn push(&mut self, d: i32) -> Result<i32, &str> {
        self.content.push(d);
        Ok(d)
    }

    fn pop(&mut self) -> Option<i32> {
        self.content.pop()
    }

    fn consume_digit(&mut self, d: i32) {
        self.digits.retain(|&n| n != d);
    }

    fn valid_digit(&self, d: i32) -> bool {
        self.digits.contains(&d)
    }

    fn add_digit(&mut self, c: char) -> Result<i32, &str> {
        match c.to_digit(10) {
            Some(n) => match self.valid_digit(n as i32) {
                true => {
                    self.consume_digit(n as i32);
                    self.push(n as i32)
                },
                false => Err("Invalid or duplicate digit!"),
            },
            None => Err("Invalid character"),
        }
    }

    fn apply<F>(&mut self, f: F) -> Result<i32, &str>
        where F : Fn(i32, i32) -> i32 {

        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => match r {
                Some(i) => self.push(f(n, i)),
                None => Err("Stack empty"),
            },
            None => Err("Stack empty"),
        }
    }
}

fn evaluate<'a>(program: Vec<char>, digits: Vec<i32>) -> Result<i32, &'a str> {
    let mut stack = Stack {
        content: vec![],
        digits: digits,
    };

    for c in program {
        let answer: Result<i32, &str> = match c {
            '*' => stack.apply(|l, r| l * r),
            '+' => stack.apply(|l, r| l + r),
            '-' => stack.apply(|l, r| l - r),
            '/' => stack.apply(|l, r| l / r),
            _   => stack.add_digit(c),
        };

        if answer.is_err() {
            // TODO: Fix this. Work out how to return "answer" without compiler error.
            // return answer;
            println!("Actual: {}", answer.unwrap_err());
            return Err("Program error");
        }
    }

    match stack.content.len() {
        1 => Ok(stack.content[0]),
        _ => Err("Invalid formula"),
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();
    let digits: Vec<i32> = vec![1, 2, 3, 4];

    match evaluate(program, digits) {
        Ok(n) => match n {
            24 => println!("Well done!"),
            _  => println!("Nice try, but {} is not 24!", n),
        },
        Err(s) => {
            println!("Oops: {}", s);
        },
    }
}
<commit_msg>Allowed for duplicate digits<commit_after>struct Stack {
    content: Vec<i32>,
    digits: Vec<i32>,
}

impl Stack {
    fn push(&mut self, d: i32) -> Result<i32, &str> {
        self.content.push(d);
        Ok(d)
    }

    fn pop(&mut self) -> Option<i32> {
        self.content.pop()
    }

    fn consume_digit(&mut self, d: i32) {
        self.digits.iter().position(|&i| i == d).expect("Cannot consume!");
    }

    fn valid_digit(&self, d: i32) -> bool {
        self.digits.contains(&d)
    }

    fn add_digit(&mut self, c: char) -> Result<i32, &str> {
        match c.to_digit(10) {
            Some(n) => match self.valid_digit(n as i32) {
                true => {
                    self.consume_digit(n as i32);
                    self.push(n as i32)
                },
                false => Err("Invalid or duplicate digit!"),
            },
            None => Err("Invalid character"),
        }
    }

    fn apply<F>(&mut self, f: F) -> Result<i32, &str>
        where F : Fn(i32, i32) -> i32 {

        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => match r {
                Some(i) => self.push(f(n, i)),
                None => Err("Stack empty"),
            },
            None => Err("Stack empty"),
        }
    }
}

fn evaluate<'a>(program: Vec<char>, digits: Vec<i32>) -> Result<i32, &'a str> {
    let mut stack = Stack {
        content: vec![],
        digits: digits,
    };

    for c in program {
        let answer: Result<i32, &str> = match c {
            '*' => stack.apply(|l, r| l * r),
            '+' => stack.apply(|l, r| l + r),
            '-' => stack.apply(|l, r| l - r),
            '/' => stack.apply(|l, r| l / r),
            _   => stack.add_digit(c),
        };

        if answer.is_err() {
            // TODO: Fix this. Work out how to return "answer" without compiler error.
            // return answer;
            println!("Actual: {}", answer.unwrap_err());
            return Err("Program error");
        }
    }

    match stack.content.len() {
        1 => Ok(stack.content[0]),
        _ => Err("Invalid formula"),
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();
    let digits: Vec<i32> = vec![2, 3, 1, 4];

    match evaluate(program, digits) {
        Ok(n) => match n {
            24 => println!("Well done!"),
            _  => println!("Nice try, but {} is not 24!", n),
        },
        Err(s) => {
            println!("Oops: {}", s);
        },
    }
}
<|endoftext|>


<commit_before>//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Lean miner for Cuckatoo Cycle

use croaring::Bitmap;

use pow::common::CuckooParams;
use pow::cuckatoo::CuckatooContext;
use pow::error::Error;
use pow::Proof;

/// Lean miner implementation aiming to be as short and simple as possible.
/// As a consequence, it's a little less than 10 times slower than John
/// Tromp's implementation, as it's not optimized for performance and reuses
/// croaring which is likely sub-optimal for this task.
pub struct Lean {
	params: CuckooParams<u32>,
	edges: Bitmap,
}

impl Lean {
	/// Instantiates a new lean miner based on some Cuckatoo parameters
	pub fn new(edge_bits: u8, easiness_pct: u32) -> Lean {
		// note that proof size doesn't matter to a lean miner
		let params = CuckooParams::new(edge_bits, 42, easiness_pct, true).unwrap();

		// edge bitmap, before trimming all of them are on
		let mut edges = Bitmap::create_with_capacity(params.easiness);
		edges.flip_inplace(0..params.easiness.into());

		Lean { params, edges }
	}

	/// Sets the header and nonce to seed the graph
	pub fn set_header_nonce(&mut self, header: Vec<u8>, nonce: u32) {
		self.params.reset_header_nonce(header, Some(nonce)).unwrap();
	}

	/// Trim edges in the Cuckatoo graph. This applies multiple trimming rounds
	/// and works well for Cuckatoo size above 18.
	pub fn trim(&mut self) {
		// trimming successively
		while self.edges.cardinality() > (7 * (self.params.easiness >> 8) / 8) as u64 {
			self.count_and_kill();
		}
	}

	/// Finds the Cuckatoo Cycles on the remaining edges. Delegates the finding
	/// to a context, passing the trimmed edges iterator.
	pub fn find_cycles(&self, mut ctx: CuckatooContext<u32>) -> Result<Vec<Proof>, Error> {
		ctx.find_cycles_iter(self.edges.iter().map(|e| e as u64))
	}

	fn count_and_kill(&mut self) {
		// on each side u or v of the bipartite graph
		for uorv in 0..2 {
			let mut nodes = Bitmap::create();
			// increment count for each node
			for e in self.edges.iter() {
				let node = self.params.sipnode(e, uorv, false).unwrap();
				nodes.add(node);
			}

			// then kill edges with lone nodes (no neighbour at ^1)
			let mut to_kill = Bitmap::create();
			for e in self.edges.iter() {
				let node = self.params.sipnode(e, uorv, false).unwrap();
				if !nodes.contains(node ^ 1) {
					to_kill.add(e);
				}
			}
			self.edges.andnot_inplace(&to_kill);
		}
	}
}

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

	#[test]
	fn lean_miner() {
		let nonce = 15465723;
		let header = [0u8; 84].to_vec(); // with nonce
		let edge_bits = 19;

		let mut lean = Lean::new(edge_bits, 50);
		lean.set_header_nonce(header.clone(), nonce);
		lean.trim();

		let mut ctx_u32 = CuckatooContext::<u32>::new_impl(edge_bits, 42, 50, 10).unwrap();
		ctx_u32.set_header_nonce(header, Some(nonce), true).unwrap();
		lean.find_cycles(ctx_u32).unwrap();
	}
}
<commit_msg>fix: a missed crate in pow lean test (#1677)<commit_after>//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Lean miner for Cuckatoo Cycle

use croaring::Bitmap;

use pow::common::CuckooParams;
use pow::cuckatoo::CuckatooContext;
use pow::error::Error;
use pow::Proof;

/// Lean miner implementation aiming to be as short and simple as possible.
/// As a consequence, it's a little less than 10 times slower than John
/// Tromp's implementation, as it's not optimized for performance and reuses
/// croaring which is likely sub-optimal for this task.
pub struct Lean {
	params: CuckooParams<u32>,
	edges: Bitmap,
}

impl Lean {
	/// Instantiates a new lean miner based on some Cuckatoo parameters
	pub fn new(edge_bits: u8, easiness_pct: u32) -> Lean {
		// note that proof size doesn't matter to a lean miner
		let params = CuckooParams::new(edge_bits, 42, easiness_pct, true).unwrap();

		// edge bitmap, before trimming all of them are on
		let mut edges = Bitmap::create_with_capacity(params.easiness);
		edges.flip_inplace(0..params.easiness.into());

		Lean { params, edges }
	}

	/// Sets the header and nonce to seed the graph
	pub fn set_header_nonce(&mut self, header: Vec<u8>, nonce: u32) {
		self.params.reset_header_nonce(header, Some(nonce)).unwrap();
	}

	/// Trim edges in the Cuckatoo graph. This applies multiple trimming rounds
	/// and works well for Cuckatoo size above 18.
	pub fn trim(&mut self) {
		// trimming successively
		while self.edges.cardinality() > (7 * (self.params.easiness >> 8) / 8) as u64 {
			self.count_and_kill();
		}
	}

	/// Finds the Cuckatoo Cycles on the remaining edges. Delegates the finding
	/// to a context, passing the trimmed edges iterator.
	pub fn find_cycles(&self, mut ctx: CuckatooContext<u32>) -> Result<Vec<Proof>, Error> {
		ctx.find_cycles_iter(self.edges.iter().map(|e| e as u64))
	}

	fn count_and_kill(&mut self) {
		// on each side u or v of the bipartite graph
		for uorv in 0..2 {
			let mut nodes = Bitmap::create();
			// increment count for each node
			for e in self.edges.iter() {
				let node = self.params.sipnode(e, uorv, false).unwrap();
				nodes.add(node);
			}

			// then kill edges with lone nodes (no neighbour at ^1)
			let mut to_kill = Bitmap::create();
			for e in self.edges.iter() {
				let node = self.params.sipnode(e, uorv, false).unwrap();
				if !nodes.contains(node ^ 1) {
					to_kill.add(e);
				}
			}
			self.edges.andnot_inplace(&to_kill);
		}
	}
}

#[cfg(test)]
mod test {
	use super::*;
	use pow::common;
	use pow::cuckatoo::*;
	use pow::types::PoWContext;

	#[test]
	fn lean_miner() {
		let nonce = 15465723;
		let header = [0u8; 84].to_vec(); // with nonce
		let edge_bits = 19;

		let mut lean = Lean::new(edge_bits, 50);
		lean.set_header_nonce(header.clone(), nonce);
		lean.trim();

		let mut ctx_u32 = CuckatooContext::<u32>::new_impl(edge_bits, 42, 50, 10).unwrap();
		ctx_u32.set_header_nonce(header, Some(nonce), true).unwrap();
		lean.find_cycles(ctx_u32).unwrap();
	}
}
<|endoftext|>


<commit_before>// structs1.rs
// Address all the TODOs to make the tests pass!

struct ColorClassicStruct {
    // TODO: Something goes here
}

struct ColorTupleStruct(/* TODO: Something goes here */);

struct ColorUnitStruct;

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

    #[test]
    fn classic_c_structs() {
        // TODO: Instantiate a classic c struct!
        // let green =

        assert_eq!(green.name, "green");
        assert_eq!(green.hex, "#00FF00");
    }

    #[test]
    fn tuple_structs() {
        // TODO: Instantiate a tuple struct!
        // For more fun, use the field initialization shorthand.
        // let green =

        assert_eq!(green.0, "green");
        assert_eq!(green.1, "#00FF00");
    }

    #[test]
    fn unit_structs() {
        // TODO: Instantiate a unit struct!
        // let green =

        if let ColorUnitStruct = green {
            assert!(true);
        } else {
            assert!(false);
        }
    }
}
<commit_msg>Fixes the irrefutable let pattern warning<commit_after>// structs1.rs
// Address all the TODOs to make the tests pass!

struct ColorClassicStruct {
    // TODO: Something goes here
}

struct ColorTupleStruct(/* TODO: Something goes here */);

#[derive(Debug)]
struct UnitStruct;

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

    #[test]
    fn classic_c_structs() {
        // TODO: Instantiate a classic c struct!
        // let green =

        assert_eq!(green.name, "green");
        assert_eq!(green.hex, "#00FF00");
    }

    #[test]
    fn tuple_structs() {
        // TODO: Instantiate a tuple struct!
        // For more fun, use the field initialization shorthand.
        // let green =

        assert_eq!(green.0, "green");
        assert_eq!(green.1, "#00FF00");
    }

    #[test]
    fn unit_structs() {
        // TODO: Instantiate a unit struct!
        // let unit_struct =
        let message = format!("{:?}s are fun!", unit_struct);

        assert_eq!(message, "UnitStructs are fun!");
    }
}
<|endoftext|>