optra 0.2.1

An engine for remote file synchronization
Documentation
Optra
=====
[![Build Status](https://travis-ci.org/dyule/optra.svg?branch=master)](https://travis-ci.org/dyule/optra)

Optra is a Rust package allowing for remote file synchronization.  It provides the algorithms necessary to keep files in sync, but not the transmission or file change detection needed.  These are provided by [wamp-rs](https://github.com/dyule/wamp-rs) and  [rdiff](https://github.com/dyule/rdiff) respectively, or you can use your own mechanism.

Optra currently requires nightly rust to build, because it uses in place insertion into linked lists, which is feature gated (see [the docs](https://doc.rust-lang.org/std/collections/linked_list/struct.IterMut.html)) for more.

Optra is licensed using the MIT license (see [LICENSE](LICENSE))

[Documentation](https://dyule.github.io/optra/optra/)

# Usage

 The engine is based on the Admissabilty Based Sequence Transformation algorithm (doi: [10.1109/TPDS.2010.64](http://dx.doi.org.ezproxy.library.dal.ca/10.1109/TPDS.2010.64)), which is a type of Operational Transformation.
 The idea is that each site that wants to have a file synchronized will have an instance of [`Engine`](engine/struct.Engine.html) running.
 Any changes that are made to teh file should be run through the engine using either `process_diffs()` or `process_transaction()` prior to being broadcast.
 Any changes that are made at a remote site should be run through the engine using `integrate_remote()` prior to being applied to the file.

 This crate generally works well with [`rdiff`](https://crates.io/crates/rdiff), but can work with
 any system that generates difference operations that are limited to insert and delete.

 To use simply include

 ```toml
 [dependencies]
 optra = "^0.2"
 ```

 in your `Cargo.toml` file

 Examples

 Assuming you have a method `read_transaction` for reading transactions from remote sites,
 the process for integrating remote changes onto a local file go like this:

 ```rust
 let (mut remote_sequence, remote_lookup) = read_transaction();
 engine.integrate_remote(&mut remote_sequence, &remote_lookup, &mut time_stamper);
 let mut file = OpenOptions::new()
                .read(true)
                .write(true)
                .open("local_file")
                .unwrap();
 remote_sequence.apply(&mut file).unwrap();
 ```

 On the other hand, if you have a Diff generated by detecting differences to a local file,
 you can process the diff and then send it out (assuming you have a method called `send_transaction()`)

 ```rust
 let diffs = file_hashes.diff_and_update(File::open("local_file").unwrap()).unwrap();
 let (transaction, lookup) = engine.process_diffs(diffs, &mut time_stamper);
 send_transaction(transaction, lookup);
 ```