diff --git a/Cargo.toml b/Cargo.toml index 0309c21..8554c68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ include = ["Cargo.toml", "README.md", "LICENSE", "ACKNOWLEDGEMENTS", "src/**/*.r [dependencies] ironsea_index = "^0.1" -ironsea_table = "^0.1" serde = "^1.0" serde_derive = "^1.0" diff --git a/src/borrowed.rs b/src/borrowed.rs deleted file mode 100644 index a44d15e..0000000 --- a/src/borrowed.rs +++ /dev/null @@ -1,102 +0,0 @@ -use std::collections::HashMap; -use std::hash::Hash; -use std::marker; - -use ironsea_index::Indexed; -use ironsea_index::Record; -use ironsea_table::Table; - -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct Index -where - T: Table, - R: Record, - K: Hash + Eq + PartialEq + Ord, -{ - table: HashMap, - keys: Vec, - _marker: marker::PhantomData<(T)>, -} - -impl Index -where - T: Table, - R: Clone + Record, - K: Hash + Eq + PartialEq + Ord, -{ - pub fn new(table: T) -> Self { - let size = table.get_table().len(); - let mut ht = HashMap::with_capacity(size); - let mut keys = Vec::with_capacity(size); - - for r in table.get_table() { - keys.push(r.key()); - ht.insert(r.key(), r.clone()); - } - - keys.sort_unstable(); - keys.dedup(); - - Index { - table: ht, - keys, - _marker: marker::PhantomData, - } - } - - pub fn keys(&self) -> &Vec { - &self.keys - } -} - -impl Indexed for Index -where - T: Table, - R: Record, - K: Hash + Eq + PartialEq + Ord, -{ - fn find(&self, key: &K) -> Vec<&R> { - let mut values = vec![]; - - if let Some(record) = self.table.get(key) { - values.push(record); - } - - values - } - - fn find_range(&self, start: &K, end: &K) -> Vec<&R> { - let start = match self.keys.binary_search(start) { - Ok(i) => i, - Err(i) => { - if i >= self.keys.len() { - self.keys.len() - 1 - } else { - i - } - } - }; - - let end = match self.keys.binary_search(end) { - Ok(i) => i, - Err(i) => { - if i >= self.keys.len() { - self.keys.len() - 1 - } else { - i - } - } - }; - - let mut values = vec![]; - - for i in start..end { - let key = &self.keys[i]; - if let Some(record) = self.table.get(key) { - values.push(record); - } - } - - values - } -} diff --git a/src/destructured.rs b/src/destructured.rs new file mode 100644 index 0000000..3a74b4a --- /dev/null +++ b/src/destructured.rs @@ -0,0 +1,88 @@ +#![allow(clippy::type_repetition_in_bounds)] + +use std::collections::HashMap; +use std::hash::Hash; + +use ironsea_index::IndexedDestructured; +use ironsea_index::Record; +use ironsea_index::RecordFields; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Index +where + K: Clone + Eq + Hash + PartialEq + Ord, +{ + hashmap: HashMap, + keys: Vec, +} + +impl Index +where + K: Clone + Eq + Hash + PartialEq + Ord, +{ + pub fn new(iter: I) -> Self + where + I: Iterator, + R: Record + RecordFields, + { + let (size, _) = iter.size_hint(); + let mut hashmap = HashMap::with_capacity(size); + + for r in iter { + hashmap.insert(r.key(), r.fields()); + } + + let mut keys = hashmap.keys().cloned().collect::>(); + keys.sort_unstable(); + + Index { hashmap, keys } + } + + pub fn keys(&self) -> &Vec { + &self.keys + } + + pub fn index(&self, key: &K) -> usize { + match self.keys.binary_search(&key) { + Ok(i) => i, + Err(i) => { + if i >= self.keys.len() { + self.keys.len() - 1 + } else { + i + } + } + } + } +} + +impl IndexedDestructured for Index +where + K: Clone + Eq + Hash + PartialEq + Ord, +{ + fn find(&self, key: &K) -> Vec<&F> { + let mut values = vec![]; + + if let Some(fields) = self.hashmap.get(key) { + values.push(fields); + } + + values + } + + fn find_range(&self, start: &K, end: &K) -> Vec<(K, &F)> { + let start = self.index(start); + let end = self.index(end); + + (start..end) + .filter_map(|i| { + let key = &self.keys[i]; + if let Some(fields) = self.hashmap.get(key) { + Some((key.clone(), fields)) + } else { + None + } + }) + .collect() + } +} diff --git a/src/full_record.rs b/src/full_record.rs new file mode 100644 index 0000000..d92b3f9 --- /dev/null +++ b/src/full_record.rs @@ -0,0 +1,82 @@ +#![allow(clippy::type_repetition_in_bounds)] + +use std::collections::HashMap; +use std::hash::Hash; +use std::iter::Iterator; + +use ironsea_index::Indexed; +use ironsea_index::Record; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Index +where + K: Clone + Eq + Hash + PartialEq + Ord, +{ + hashmap: HashMap, + keys: Vec, +} + +impl Index +where + R: Record, + K: Clone + Eq + Hash + PartialEq + Ord, +{ + pub fn new(iter: I) -> Self + where + I: Iterator, + { + let (size, _) = iter.size_hint(); + let mut hashmap = HashMap::with_capacity(size); + + for r in iter { + hashmap.insert(r.key(), r); + } + + let mut keys = hashmap.keys().cloned().collect::>(); + keys.sort_unstable(); + + Index { hashmap, keys } + } + + pub fn keys(&self) -> &Vec { + &self.keys + } + + pub fn index(&self, key: &K) -> usize { + match self.keys.binary_search(key) { + Ok(i) => i, + Err(i) => { + if i >= self.keys.len() { + self.keys.len() - 1 + } else { + i + } + } + } + } +} + +impl Indexed for Index +where + R: Record, + K: Clone + Eq + Hash + PartialEq + Ord, +{ + fn find(&self, key: &K) -> Vec<&R> { + let mut values = vec![]; + + if let Some(record) = self.hashmap.get(key) { + values.push(record); + } + + values + } + + fn find_range(&self, start: &K, end: &K) -> Vec<&R> { + let start = self.index(start); + let end = self.index(end); + + (start..end) + .filter_map(|i| self.hashmap.get(&self.keys[i])) + .collect() + } +} diff --git a/src/lib.rs b/src/lib.rs index 1ecf7e8..b8e02f3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,8 @@ #[macro_use] extern crate serde_derive; -mod borrowed; -mod owned; +mod destructured; +mod full_record; -pub use ironsea_table::Table; - -pub use borrowed::Index; -pub use owned::IndexOwned; +pub use destructured::Index as IndexDestructured; +pub use full_record::Index; diff --git a/src/owned.rs b/src/owned.rs deleted file mode 100644 index befd09f..0000000 --- a/src/owned.rs +++ /dev/null @@ -1,104 +0,0 @@ -use std::collections::HashMap; -use std::hash::Hash; -use std::marker; - -use ironsea_index::IndexedOwned; -use ironsea_index::Record; -use ironsea_index::RecordBuild; -use ironsea_index::RecordFields; -use ironsea_table::Table; - -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct IndexOwned -where - T: Table, - R: Record + RecordFields + RecordBuild, - K: Hash + Eq + PartialEq + Ord, -{ - table: HashMap, - keys: Vec, - _marker: marker::PhantomData<(T, R)>, -} - -impl IndexOwned -where - T: Table, - R: Record + RecordFields + RecordBuild, - K: Hash + Eq + PartialEq + Ord, -{ - pub fn new(table: T) -> Self { - let size = table.get_table().len(); - let mut ht = HashMap::with_capacity(size); - let mut keys = Vec::with_capacity(size); - - for r in table.get_table() { - ht.insert(r.key(), r.fields()); - keys.push(r.key()); - } - - keys.sort_unstable(); - keys.dedup(); - - IndexOwned { - table: ht, - keys, - _marker: marker::PhantomData, - } - } - - pub fn keys(&self) -> &Vec { - &self.keys - } -} - -impl IndexedOwned for IndexOwned -where - T: Table, - R: Record + RecordFields + RecordBuild, - K: Hash + Eq + PartialEq + Ord, -{ - fn find(&self, key: &K) -> Vec { - let mut values = vec![]; - - if let Some(fields) = self.table.get(key) { - values.push(R::build(key, fields)); - } - - values - } - - fn find_range(&self, start: &K, end: &K) -> Vec { - let start = match self.keys.binary_search(start) { - Ok(i) => i, - Err(i) => { - if i >= self.keys.len() { - self.keys.len() - 1 - } else { - i - } - } - }; - - let end = match self.keys.binary_search(end) { - Ok(i) => i, - Err(i) => { - if i >= self.keys.len() { - self.keys.len() - 1 - } else { - i - } - } - }; - - let mut values = vec![]; - - for i in start..end { - let key = &self.keys[i]; - if let Some(record) = self.table.get(key) { - values.push(R::build(key, record)); - } - } - - values - } -}