Initial commit
This commit is contained in:
26
Cargo.toml
Normal file
26
Cargo.toml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "ironsea_index_hashmap"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["EPFL-DIAS", "Lionel Sambuc <lionel.sambuc@epfl.ch>"]
|
||||||
|
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
description = "Simple `HashMap`-based index implementation for the Iron Sea database toolkit."
|
||||||
|
homepage = "https://crates.io/crates/ironsea_index_hashmap"
|
||||||
|
repository = "https://github.com/epfl-dias/ironsea_index_hashmap"
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
keywords = []
|
||||||
|
categories = ["database-implementations", "data-structures"]
|
||||||
|
|
||||||
|
license = "MIT"
|
||||||
|
#license-file = "LICENSE"
|
||||||
|
|
||||||
|
include = ["Cargo.toml", "README.md", "LICENSE", "ACKNOWLEDGEMENTS", "src/**/*.rs"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ironsea_index = "^0.1"
|
||||||
|
ironsea_table = "^0.1"
|
||||||
|
|
||||||
|
serde = "^1.0"
|
||||||
|
serde_derive = "^1.0"
|
||||||
32
README.md
Normal file
32
README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Iron Sea - Index Hash Map
|
||||||
|
|
||||||
|
A simple hash map index for the Iron Sea toolkit.
|
||||||
|
|
||||||
|
## Iron Sea: Database Toolkit
|
||||||
|
|
||||||
|
**Iron Sea** provides a set of database engine bricks, which can be combined and applied on arbitrary data structures.
|
||||||
|
|
||||||
|
Unlike a traditional database, it does not assume a specific physical structure for the tables nor the records, but relies on the developper to provide a set of extractor functions which are used by the specific indices provided.
|
||||||
|
|
||||||
|
This enables the index implementations to be agnostic from the underlying data structure, and re-used.
|
||||||
|
|
||||||
|
### Software
|
||||||
|
|
||||||
|
* Rust: https://www.rust-lang.org
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
For more information, please refer to the [documentation](https://epfl-dias.github.io/ironsea_index_hashmap/).
|
||||||
|
|
||||||
|
If you want to build the documentation and access it locally, you can use:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo doc --open
|
||||||
|
```
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
This open source software code was developed in part or in whole in the
|
||||||
|
Human Brain Project, funded from the European Union’s Horizon 2020
|
||||||
|
Framework Programme for Research and Innovation under the Specific Grant
|
||||||
|
Agreement No. 785907 (Human Brain Project SGA2).
|
||||||
102
src/borrowed.rs
Normal file
102
src/borrowed.rs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
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<T, R, K>
|
||||||
|
where
|
||||||
|
T: Table<R>,
|
||||||
|
R: Record<K>,
|
||||||
|
K: Hash + Eq + PartialEq + Ord,
|
||||||
|
{
|
||||||
|
table: HashMap<K, R>,
|
||||||
|
keys: Vec<K>,
|
||||||
|
_marker: marker::PhantomData<(T)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, R, K> Index<T, R, K>
|
||||||
|
where
|
||||||
|
T: Table<R>,
|
||||||
|
R: Clone + Record<K>,
|
||||||
|
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<K> {
|
||||||
|
&self.keys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, R, K> Indexed<T, R, K> for Index<T, R, K>
|
||||||
|
where
|
||||||
|
T: Table<R>,
|
||||||
|
R: Record<K>,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/lib.rs
Normal file
10
src/lib.rs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
mod borrowed;
|
||||||
|
mod owned;
|
||||||
|
|
||||||
|
pub use ironsea_table::Table;
|
||||||
|
|
||||||
|
pub use borrowed::Index;
|
||||||
|
pub use owned::IndexOwned;
|
||||||
104
src/owned.rs
Normal file
104
src/owned.rs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
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<T, R, K, F>
|
||||||
|
where
|
||||||
|
T: Table<R>,
|
||||||
|
R: Record<K> + RecordFields<F> + RecordBuild<K, F, R>,
|
||||||
|
K: Hash + Eq + PartialEq + Ord,
|
||||||
|
{
|
||||||
|
table: HashMap<K, F>,
|
||||||
|
keys: Vec<K>,
|
||||||
|
_marker: marker::PhantomData<(T, R)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, R, K, F> IndexOwned<T, R, K, F>
|
||||||
|
where
|
||||||
|
T: Table<R>,
|
||||||
|
R: Record<K> + RecordFields<F> + RecordBuild<K, F, R>,
|
||||||
|
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<K> {
|
||||||
|
&self.keys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, R, K, F> IndexedOwned<T, R, K> for IndexOwned<T, R, K, F>
|
||||||
|
where
|
||||||
|
T: Table<R>,
|
||||||
|
R: Record<K> + RecordFields<F> + RecordBuild<K, F, R>,
|
||||||
|
K: Hash + Eq + PartialEq + Ord,
|
||||||
|
{
|
||||||
|
fn find(&self, key: &K) -> Vec<R> {
|
||||||
|
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<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(R::build(key, record));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
values
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user