From 00a10c9169b8b00e17dacada65d1acc9178d7d21 Mon Sep 17 00:00:00 2001 From: David Mehren <dmehren1@gmail.com> Date: Fri, 1 Jun 2018 09:13:08 +0200 Subject: [PATCH] [BPTree] Add serialization/deserialization --- Cargo.toml | 5 +++- src/lib.rs | 3 ++ src/trees/bp_tree.rs | 47 +++++++++++++++++++++++++++++-- testdata/bptree_invalid.testdata | Bin 0 -> 115 bytes 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 testdata/bptree_invalid.testdata diff --git a/Cargo.toml b/Cargo.toml index 4d0a043..a327b5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,7 @@ authors = ["David Mehren <dmehren1@gmail.com>"] bv = "0.7" bio = "0.19.0" id_tree = "1.3.0" -failure = "0.1.1" \ No newline at end of file +failure = "0.1.1" +serde = "1.0.64" +serde_derive = "1.0.64" +bincode = "1.0.0" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 2b18f66..e21698b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,9 @@ extern crate bv; extern crate id_tree; #[macro_use] extern crate failure; +#[macro_use] +extern crate serde_derive; +extern crate bincode; pub mod common; pub mod trees; diff --git a/src/trees/bp_tree.rs b/src/trees/bp_tree.rs index eb4ffcc..693bce5 100644 --- a/src/trees/bp_tree.rs +++ b/src/trees/bp_tree.rs @@ -1,18 +1,29 @@ +use bincode::{deserialize, serialize}; use bio::data_structures::rank_select::RankSelect; use bv::{BitVec, BitsMut}; use common::succinct_tree::SuccinctTree; -use failure::Error; +use failure::{Error, ResultExt}; use id_tree::Tree; use std::fmt; use std::fmt::Debug; use std::fmt::Formatter; +use std::fs; +use std::fs::File; +use std::io::Write; +#[derive(Serialize, Deserialize)] pub struct BPTree { bits: BitVec<u8>, rankselect: RankSelect, rminmax: String, } +impl PartialEq for BPTree { + fn eq(&self, other: &BPTree) -> bool { + self.bits == other.bits + } +} + impl SuccinctTree<BPTree> for BPTree { fn is_leaf(&self, index: u64) -> bool { unimplemented!() @@ -64,6 +75,19 @@ impl BPTree { rminmax: "foo".to_string(), }) } + + pub fn from_file(path: String) -> Result<BPTree, Error> { + let file = fs::read(path).context("Could not read saved tree.")?; + let tree: BPTree = deserialize(&file).context("Error while deserializing tree.")?; + Ok(tree) + } + + pub fn save_to(&self, path: String) -> Result<(), Error> { + let encoded = serialize(&self).context("Error while serializing tree.")?; + let mut file = File::create(path).context("Could not save tree.")?; + file.write_all(&encoded)?; + Ok(()) + } } #[cfg(test)] @@ -84,7 +108,26 @@ mod tests { #[test] #[should_panic(expected = "ErrorMessage { msg: \"Bit vector not valid.\" }")] fn new_from_bitvec_invalid() { - let mut bitvec = BitVec::new_fill(false, 2); + let bitvec = BitVec::new_fill(false, 2); BPTree::from_bitvec(bitvec.clone()).unwrap(); } + + #[test] + fn save_load() { + let tree = BPTree::stub_create(); + tree.save_to("testdata/bptree.testdata".to_string()) + .unwrap(); + let result = BPTree::from_file("testdata/bptree.testdata".to_string()).unwrap(); + assert_eq!( + tree, result, + "The loaded tree is not equal to the original one." + ); + } + + #[test] + #[should_panic(expected = "Error while deserializing tree.")] + fn load_invaild() { + BPTree::from_file("testdata/bptree_invalid.testdata".to_string()).unwrap(); + } + } diff --git a/testdata/bptree_invalid.testdata b/testdata/bptree_invalid.testdata new file mode 100644 index 0000000000000000000000000000000000000000..4318da13396d0f974a32b7f727f5bf23ac866417 GIT binary patch literal 115 zcmZQ#fB`Nj!vRWjKxqXA1_nk31_qcoLI*?~#7`_vDNam*YG9COU|<000`WmQK{PXn LU|?WK%g+Y@uek)W literal 0 HcmV?d00001 -- GitLab