use std::marker::PhantomData;
use std::borrow::Borrow;
use super::{BaseIndex, BaseIndexIter, Snapshot, Fork, StorageKey};
use super::indexes_metadata::IndexType;
#[derive(Debug)]
pub struct KeySetIndex<T, K> {
base: BaseIndex<T>,
_k: PhantomData<K>,
}
#[derive(Debug)]
pub struct KeySetIndexIter<'a, K> {
base_iter: BaseIndexIter<'a, K, ()>,
}
impl<T, K> KeySetIndex<T, K>
where
T: AsRef<Snapshot>,
K: StorageKey,
{
pub fn new<S: AsRef<str>>(name: S, view: T) -> Self {
KeySetIndex {
base: BaseIndex::new(name, IndexType::KeySet, view),
_k: PhantomData,
}
}
pub fn with_prefix<S: AsRef<str>>(name: S, prefix: Vec<u8>, view: T) -> Self {
KeySetIndex {
base: BaseIndex::with_prefix(name, prefix, IndexType::KeySet, view),
_k: PhantomData,
}
}
pub fn contains<Q>(&self, item: &Q) -> bool
where
K: Borrow<Q>,
Q: StorageKey + ?Sized,
{
self.base.contains(item)
}
pub fn iter(&self) -> KeySetIndexIter<K> {
KeySetIndexIter { base_iter: self.base.iter(&()) }
}
pub fn iter_from(&self, from: &K) -> KeySetIndexIter<K> {
KeySetIndexIter { base_iter: self.base.iter_from(&(), from) }
}
}
impl<'a, K> KeySetIndex<&'a mut Fork, K>
where
K: StorageKey,
{
#[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))]
pub fn insert(&mut self, item: K) {
self.base.put(&item, ())
}
pub fn remove<Q>(&mut self, item: &Q)
where
K: Borrow<Q>,
Q: StorageKey + ?Sized,
{
self.base.remove(item)
}
pub fn clear(&mut self) {
self.base.clear()
}
}
impl<'a, T, K> ::std::iter::IntoIterator for &'a KeySetIndex<T, K>
where
T: AsRef<Snapshot>,
K: StorageKey,
{
type Item = K::Owned;
type IntoIter = KeySetIndexIter<'a, K>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K> Iterator for KeySetIndexIter<'a, K>
where
K: StorageKey,
{
type Item = K::Owned;
fn next(&mut self) -> Option<Self::Item> {
self.base_iter.next().map(|(k, ..)| k)
}
}
#[cfg(test)]
mod tests {
use super::*;
use super::super::{MemoryDB, Database};
const INDEX_NAME: &str = "test_index_name";
#[test]
fn str_key() {
let db = MemoryDB::new();
let mut fork = db.fork();
const KEY: &str = "key_1";
let mut index: KeySetIndex<_, String> = KeySetIndex::new(INDEX_NAME, &mut fork);
assert_eq!(false, index.contains(KEY));
index.insert(KEY.to_owned());
assert_eq!(true, index.contains(KEY));
index.remove(KEY);
assert_eq!(false, index.contains(KEY));
}
#[test]
fn u8_slice_key() {
let db = MemoryDB::new();
let mut fork = db.fork();
const KEY: &[u8] = &[1, 2, 3];
let mut index: KeySetIndex<_, Vec<u8>> = KeySetIndex::new(INDEX_NAME, &mut fork);
assert_eq!(false, index.contains(KEY));
index.insert(KEY.to_owned());
assert_eq!(true, index.contains(KEY));
index.remove(KEY);
assert_eq!(false, index.contains(KEY));
}
}