use crate::common::{Key, Value};
use crate::errors::NitriteResult;
use crate::store::NitriteMap;
use super::NitriteMapProvider;
use std::sync::Arc;
pub trait EntryIteratorProvider: Send + Sync {
fn next_entry(&mut self) -> Option<NitriteResult<(Key, Value)>>;
fn prev_entry(&mut self) -> Option<NitriteResult<(Key, Value)>>;
}
pub trait KeyIteratorProvider: Send + Sync {
fn next_key(&mut self) -> Option<NitriteResult<Key>>;
fn prev_key(&mut self) -> Option<NitriteResult<Key>>;
}
pub trait ValueIteratorProvider: Send + Sync {
fn next_value(&mut self) -> Option<NitriteResult<Value>>;
fn prev_value(&mut self) -> Option<NitriteResult<Value>>;
}
pub struct EntryIterator {
provider: Arc<parking_lot::Mutex<Box<dyn EntryIteratorProvider>>>,
}
impl EntryIterator {
pub fn new<T: EntryIteratorProvider + 'static>(provider: T) -> Self {
EntryIterator {
provider: Arc::new(parking_lot::Mutex::new(Box::new(provider))),
}
}
}
impl Clone for EntryIterator {
fn clone(&self) -> Self {
EntryIterator {
provider: Arc::clone(&self.provider),
}
}
}
impl Iterator for EntryIterator {
type Item = NitriteResult<(Key, Value)>;
fn next(&mut self) -> Option<Self::Item> {
let mut provider = self.provider.lock();
provider.next_entry()
}
}
impl DoubleEndedIterator for EntryIterator {
fn next_back(&mut self) -> Option<Self::Item> {
let mut provider = self.provider.lock();
provider.prev_entry()
}
}
pub struct KeyIterator {
provider: Arc<parking_lot::Mutex<Box<dyn KeyIteratorProvider>>>,
}
impl KeyIterator {
pub fn new<T: KeyIteratorProvider + 'static>(provider: T) -> Self {
KeyIterator {
provider: Arc::new(parking_lot::Mutex::new(Box::new(provider))),
}
}
}
impl Clone for KeyIterator {
fn clone(&self) -> Self {
KeyIterator {
provider: Arc::clone(&self.provider),
}
}
}
impl Iterator for KeyIterator {
type Item = NitriteResult<Key>;
fn next(&mut self) -> Option<Self::Item> {
let mut provider = self.provider.lock();
provider.next_key()
}
}
impl DoubleEndedIterator for KeyIterator {
fn next_back(&mut self) -> Option<Self::Item> {
let mut provider = self.provider.lock();
provider.prev_key()
}
}
pub struct ValueIterator {
provider: Arc<parking_lot::Mutex<Box<dyn ValueIteratorProvider>>>,
}
impl ValueIterator {
pub fn new<T: ValueIteratorProvider + 'static>(provider: T) -> Self {
ValueIterator {
provider: Arc::new(parking_lot::Mutex::new(Box::new(provider))),
}
}
}
impl Clone for ValueIterator {
fn clone(&self) -> Self {
ValueIterator {
provider: Arc::clone(&self.provider),
}
}
}
impl Iterator for ValueIterator {
type Item = NitriteResult<Value>;
fn next(&mut self) -> Option<Self::Item> {
let mut provider = self.provider.lock();
provider.next_value()
}
}
impl DoubleEndedIterator for ValueIterator {
fn next_back(&mut self) -> Option<Self::Item> {
let mut provider = self.provider.lock();
provider.prev_value()
}
}
pub type NitriteMapEntryIterator = EntryIterator;
pub type NitriteMapKeyIterator = KeyIterator;
pub type NitriteMapValueIterator = ValueIterator;
pub struct SingleMapEntryProvider {
inner_map: NitriteMap,
current: Option<Key>,
}
impl SingleMapEntryProvider {
pub fn new(map: NitriteMap) -> Self {
SingleMapEntryProvider {
inner_map: map,
current: None,
}
}
fn set_current(
&mut self,
map: NitriteMap,
next_key: NitriteResult<Option<Key>>,
) -> Option<NitriteResult<(Key, Value)>> {
match next_key {
Ok(Some(key)) => {
self.current = Some(key.clone());
match map.get(&key) {
Ok(Some(value)) => Some(Ok((key, value))),
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn higher_key(&self, map: NitriteMap) -> NitriteResult<Option<Key>> {
match &self.current {
Some(current_key) => map.higher_key(current_key),
None => map.first_key(),
}
}
fn lower_key(&self, map: NitriteMap) -> NitriteResult<Option<Key>> {
match &self.current {
Some(current_key) => map.lower_key(current_key),
None => map.last_key(),
}
}
}
impl EntryIteratorProvider for SingleMapEntryProvider {
fn next_entry(&mut self) -> Option<NitriteResult<(Key, Value)>> {
let map = self.inner_map.clone();
let next_key = self.higher_key(map.clone());
self.set_current(map, next_key)
}
fn prev_entry(&mut self) -> Option<NitriteResult<(Key, Value)>> {
let map = self.inner_map.clone();
let next_key = self.lower_key(map.clone());
self.set_current(map, next_key)
}
}
pub struct SingleMapKeyProvider {
inner_map: NitriteMap,
current: Option<Key>,
}
impl SingleMapKeyProvider {
pub fn new(map: NitriteMap) -> Self {
SingleMapKeyProvider {
inner_map: map,
current: None,
}
}
fn set_current(&mut self, next_key: NitriteResult<Option<Key>>) -> Option<NitriteResult<Key>> {
match next_key {
Ok(Some(key)) => {
self.current = Some(key.clone());
Some(Ok(key))
}
Ok(None) => {
self.current = None;
None
}
Err(e) => Some(Err(e)),
}
}
fn higher_key(&self, map: NitriteMap) -> NitriteResult<Option<Key>> {
match &self.current {
Some(current_key) => map.higher_key(current_key),
None => map.first_key(),
}
}
fn lower_key(&self, map: NitriteMap) -> NitriteResult<Option<Key>> {
match &self.current {
Some(current_key) => map.lower_key(current_key),
None => map.last_key(),
}
}
}
impl KeyIteratorProvider for SingleMapKeyProvider {
fn next_key(&mut self) -> Option<NitriteResult<Key>> {
let map = self.inner_map.clone();
let next_key = self.higher_key(map.clone());
self.set_current(next_key)
}
fn prev_key(&mut self) -> Option<NitriteResult<Key>> {
let map = self.inner_map.clone();
let next_key = self.lower_key(map.clone());
self.set_current(next_key)
}
}
pub struct SingleMapValueProvider {
inner_map: NitriteMap,
current: Option<Key>,
}
impl SingleMapValueProvider {
pub fn new(map: NitriteMap) -> Self {
SingleMapValueProvider {
inner_map: map,
current: None,
}
}
fn set_current(
&mut self,
map: NitriteMap,
next_key: NitriteResult<Option<Key>>,
) -> Option<NitriteResult<Value>> {
match next_key {
Ok(Some(key)) => {
self.current = Some(key.clone());
match map.get(&key) {
Ok(Some(value)) => Some(Ok(value)),
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn higher_key(&self, map: NitriteMap) -> NitriteResult<Option<Key>> {
match &self.current {
Some(current_key) => map.higher_key(current_key),
None => map.first_key(),
}
}
fn lower_key(&self, map: NitriteMap) -> NitriteResult<Option<Key>> {
match &self.current {
Some(current_key) => map.lower_key(current_key),
None => map.last_key(),
}
}
}
impl ValueIteratorProvider for SingleMapValueProvider {
fn next_value(&mut self) -> Option<NitriteResult<Value>> {
let map = self.inner_map.clone();
let next_key = self.higher_key(map.clone());
self.set_current(map, next_key)
}
fn prev_value(&mut self) -> Option<NitriteResult<Value>> {
let map = self.inner_map.clone();
let next_key = self.lower_key(map.clone());
self.set_current(map, next_key)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::common::{Key, Value};
use crate::nitrite_config::NitriteConfig;
fn create_test_map() -> NitriteMap {
let config = NitriteConfig::default();
config.auto_configure().unwrap();
config.initialize().unwrap();
let store = config.nitrite_store().unwrap();
let map = store.open_map("test_map").unwrap();
map.put(Key::from("key1"), Value::from("value1")).unwrap();
map.put(Key::from("key2"), Value::from("value2")).unwrap();
map.put(Key::from("key3"), Value::from("value3")).unwrap();
map
}
#[test]
fn test_entry_iterator_forward() {
let map = create_test_map();
let provider = SingleMapEntryProvider::new(map);
let mut iter = EntryIterator::new(provider);
let (key, value) = iter.next().unwrap().unwrap();
assert_eq!(key, Key::from("key1"));
assert_eq!(value, Value::from("value1"));
let (key, value) = iter.next().unwrap().unwrap();
assert_eq!(key, Key::from("key2"));
assert_eq!(value, Value::from("value2"));
let (key, value) = iter.next().unwrap().unwrap();
assert_eq!(key, Key::from("key3"));
assert_eq!(value, Value::from("value3"));
assert!(iter.next().is_none());
}
#[test]
fn test_entry_iterator_backward() {
let map = create_test_map();
let provider = SingleMapEntryProvider::new(map);
let mut iter = EntryIterator::new(provider);
let (key, value) = iter.next_back().unwrap().unwrap();
assert_eq!(key, Key::from("key3"));
assert_eq!(value, Value::from("value3"));
let (key, value) = iter.next_back().unwrap().unwrap();
assert_eq!(key, Key::from("key2"));
assert_eq!(value, Value::from("value2"));
let (key, value) = iter.next_back().unwrap().unwrap();
assert_eq!(key, Key::from("key1"));
assert_eq!(value, Value::from("value1"));
assert!(iter.next_back().is_none());
}
#[test]
fn test_key_iterator_forward() {
let map = create_test_map();
let provider = SingleMapKeyProvider::new(map);
let mut iter = KeyIterator::new(provider);
assert_eq!(iter.next().unwrap().unwrap(), Key::from("key1"));
assert_eq!(iter.next().unwrap().unwrap(), Key::from("key2"));
assert_eq!(iter.next().unwrap().unwrap(), Key::from("key3"));
assert!(iter.next().is_none());
}
#[test]
fn test_key_iterator_backward() {
let map = create_test_map();
let provider = SingleMapKeyProvider::new(map);
let mut iter = KeyIterator::new(provider);
assert_eq!(iter.next_back().unwrap().unwrap(), Key::from("key3"));
assert_eq!(iter.next_back().unwrap().unwrap(), Key::from("key2"));
assert_eq!(iter.next_back().unwrap().unwrap(), Key::from("key1"));
assert!(iter.next_back().is_none());
}
#[test]
fn test_value_iterator_forward() {
let map = create_test_map();
let provider = SingleMapValueProvider::new(map);
let mut iter = ValueIterator::new(provider);
assert_eq!(iter.next().unwrap().unwrap(), Value::from("value1"));
assert_eq!(iter.next().unwrap().unwrap(), Value::from("value2"));
assert_eq!(iter.next().unwrap().unwrap(), Value::from("value3"));
assert!(iter.next().is_none());
}
#[test]
fn test_value_iterator_backward() {
let map = create_test_map();
let provider = SingleMapValueProvider::new(map);
let mut iter = ValueIterator::new(provider);
assert_eq!(iter.next_back().unwrap().unwrap(), Value::from("value3"));
assert_eq!(iter.next_back().unwrap().unwrap(), Value::from("value2"));
assert_eq!(iter.next_back().unwrap().unwrap(), Value::from("value1"));
assert!(iter.next_back().is_none());
}
#[test]
fn test_entry_iterator_bidirectional() {
let map = create_test_map();
let provider = SingleMapEntryProvider::new(map.clone());
let mut iter = EntryIterator::new(provider);
let (key1, _) = iter.next().unwrap().unwrap();
assert_eq!(key1, Key::from("key1"));
let (key2, _) = iter.next().unwrap().unwrap();
assert_eq!(key2, Key::from("key2"));
let provider_back = SingleMapEntryProvider::new(map);
let mut iter_back = EntryIterator::new(provider_back);
let (key3, _) = iter_back.next_back().unwrap().unwrap();
assert_eq!(key3, Key::from("key3"));
let (key2_back, _) = iter_back.next_back().unwrap().unwrap();
assert_eq!(key2_back, Key::from("key2"));
let (key1_back, _) = iter_back.next_back().unwrap().unwrap();
assert_eq!(key1_back, Key::from("key1"));
}
#[test]
fn test_entry_iterator_cloning() {
let map = create_test_map();
let provider = SingleMapEntryProvider::new(map);
let mut iter = EntryIterator::new(provider);
let mut iter_cloned = iter.clone();
let (key1, value1) = iter.next().unwrap().unwrap();
assert_eq!(key1, Key::from("key1"));
assert_eq!(value1, Value::from("value1"));
let (key2, value2) = iter_cloned.next().unwrap().unwrap();
assert_eq!(key2, Key::from("key2"));
assert_eq!(value2, Value::from("value2"));
}
#[test]
fn test_custom_provider_implementation() {
struct SimpleEntryProvider {
entries: Vec<(Key, Value)>,
index: usize,
}
impl EntryIteratorProvider for SimpleEntryProvider {
fn next_entry(&mut self) -> Option<NitriteResult<(Key, Value)>> {
if self.index < self.entries.len() {
let entry = self.entries[self.index].clone();
self.index += 1;
Some(Ok(entry))
} else {
None
}
}
fn prev_entry(&mut self) -> Option<NitriteResult<(Key, Value)>> {
if self.index > 0 {
self.index -= 1;
Some(Ok(self.entries[self.index].clone()))
} else {
None
}
}
}
let provider = SimpleEntryProvider {
entries: vec![
(Key::from("a"), Value::from("1")),
(Key::from("b"), Value::from("2")),
],
index: 0,
};
let mut iter = EntryIterator::new(provider);
let (key, value) = iter.next().unwrap().unwrap();
assert_eq!(key, Key::from("a"));
assert_eq!(value, Value::from("1"));
let (key, value) = iter.next().unwrap().unwrap();
assert_eq!(key, Key::from("b"));
assert_eq!(value, Value::from("2"));
assert!(iter.next().is_none());
}
}