use std::borrow::Cow;
use std::marker;
use std::ops::Bound;
use crate::*;
use super::{advance_key, retreat_key};
fn move_on_range_end<'txn>(
cursor: &mut RoCursor<'txn>,
end_bound: &Bound<Vec<u8>>,
) -> Result<Option<(&'txn [u8], &'txn [u8])>>
{
match end_bound {
Bound::Included(end) => {
match cursor.move_on_key_greater_than_or_equal_to(end) {
Ok(Some((key, data))) if key == &end[..] => Ok(Some((key, data))),
Ok(_) => cursor.move_on_prev(),
Err(e) => Err(e),
}
},
Bound::Excluded(end) => {
cursor
.move_on_key_greater_than_or_equal_to(end)
.and_then(|_| cursor.move_on_prev())
},
Bound::Unbounded => cursor.move_on_last(),
}
}
fn move_on_range_start<'txn>(
cursor: &mut RoCursor<'txn>,
start_bound: &mut Bound<Vec<u8>>,
) -> Result<Option<(&'txn [u8], &'txn [u8])>>
{
match start_bound {
Bound::Included(start) => {
cursor.move_on_key_greater_than_or_equal_to(start)
},
Bound::Excluded(start) => {
advance_key(start);
let result = cursor.move_on_key_greater_than_or_equal_to(start);
retreat_key(start);
result
},
Bound::Unbounded => cursor.move_on_first(),
}
}
pub struct RoRange<'txn, KC, DC> {
cursor: RoCursor<'txn>,
move_on_start: bool,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RoRange<'txn, KC, DC> {
pub(crate) fn new(
cursor: RoCursor<'txn>,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
) -> RoRange<'txn, KC, DC>
{
RoRange {
cursor,
move_on_start: true,
start_bound,
end_bound,
_phantom: marker::PhantomData,
}
}
pub fn remap_types<KC2, DC2>(self) -> RoRange<'txn, KC2, DC2> {
RoRange {
cursor: self.cursor,
move_on_start: self.move_on_start,
start_bound: self.start_bound,
end_bound: self.end_bound,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RoRange<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RoRange<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RoRange<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RoRange<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_start {
self.move_on_start = false;
move_on_range_start(&mut self.cursor, &mut self.start_bound)
} else {
self.cursor.move_on_next()
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match &self.end_bound {
Bound::Included(end) => key <= end,
Bound::Excluded(end) => key < end,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
}
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_start {
move_on_range_end(&mut self.cursor, &self.end_bound)
} else {
match (self.cursor.current(), move_on_range_end(&mut self.cursor, &self.end_bound)) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match &self.start_bound {
Bound::Included(start) => key >= start,
Bound::Excluded(start) => key > start,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}
pub struct RwRange<'txn, KC, DC> {
cursor: RwCursor<'txn>,
move_on_start: bool,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RwRange<'txn, KC, DC> {
pub(crate) fn new(
cursor: RwCursor<'txn>,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
) -> RwRange<'txn, KC, DC>
{
RwRange {
cursor,
move_on_start: true,
start_bound,
end_bound,
_phantom: marker::PhantomData,
}
}
pub fn del_current(&mut self) -> Result<bool> {
self.cursor.del_current()
}
pub fn put_current<'a>(&mut self, key: &'a KC::EItem, data: &'a DC::EItem) -> Result<bool>
where
KC: BytesEncode<'a>,
DC: BytesEncode<'a>,
{
let key_bytes: Cow<[u8]> = KC::bytes_encode(&key).ok_or(Error::Encoding)?;
let data_bytes: Cow<[u8]> = DC::bytes_encode(&data).ok_or(Error::Encoding)?;
self.cursor.put_current(&key_bytes, &data_bytes)
}
pub fn remap_types<KC2, DC2>(self) -> RwRange<'txn, KC2, DC2> {
RwRange {
cursor: self.cursor,
move_on_start: self.move_on_start,
start_bound: self.start_bound,
end_bound: self.end_bound,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RwRange<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RwRange<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RwRange<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RwRange<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_start {
self.move_on_start = false;
move_on_range_start(&mut self.cursor, &mut self.start_bound)
} else {
self.cursor.move_on_next()
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match self.end_bound {
Bound::Included(ref end) => key <= end,
Bound::Excluded(ref end) => key < end,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
}
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_start {
move_on_range_end(&mut self.cursor, &self.end_bound)
} else {
match (self.cursor.current(), move_on_range_end(&mut self.cursor, &self.end_bound)) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match &self.start_bound {
Bound::Included(start) => key >= start,
Bound::Excluded(start) => key > start,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}
pub struct RoRevRange<'txn, KC, DC> {
cursor: RoCursor<'txn>,
move_on_end: bool,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RoRevRange<'txn, KC, DC> {
pub(crate) fn new(
cursor: RoCursor<'txn>,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
) -> RoRevRange<'txn, KC, DC>
{
RoRevRange {
cursor,
move_on_end: true,
start_bound,
end_bound,
_phantom: marker::PhantomData,
}
}
pub fn remap_types<KC2, DC2>(self) -> RoRevRange<'txn, KC2, DC2> {
RoRevRange {
cursor: self.cursor,
move_on_end: self.move_on_end,
start_bound: self.start_bound,
end_bound: self.end_bound,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RoRevRange<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RoRevRange<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RoRevRange<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RoRevRange<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_end {
self.move_on_end = false;
move_on_range_end(&mut self.cursor, &self.end_bound)
} else {
self.cursor.move_on_prev()
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match &self.start_bound {
Bound::Included(start) => key >= start,
Bound::Excluded(start) => key > start,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
}
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_end {
move_on_range_start(&mut self.cursor, &mut self.start_bound)
} else {
let current = self.cursor.current();
let start = move_on_range_start(&mut self.cursor, &mut self.start_bound);
match (current, start) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match &self.end_bound {
Bound::Included(end) => key <= end,
Bound::Excluded(end) => key < end,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}
pub struct RwRevRange<'txn, KC, DC> {
cursor: RwCursor<'txn>,
move_on_end: bool,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RwRevRange<'txn, KC, DC> {
pub(crate) fn new(
cursor: RwCursor<'txn>,
start_bound: Bound<Vec<u8>>,
end_bound: Bound<Vec<u8>>,
) -> RwRevRange<'txn, KC, DC>
{
RwRevRange {
cursor,
move_on_end: true,
start_bound,
end_bound,
_phantom: marker::PhantomData,
}
}
pub fn del_current(&mut self) -> Result<bool> {
self.cursor.del_current()
}
pub fn put_current<'a>(&mut self, key: &'a KC::EItem, data: &'a DC::EItem) -> Result<bool>
where
KC: BytesEncode<'a>,
DC: BytesEncode<'a>,
{
let key_bytes: Cow<[u8]> = KC::bytes_encode(&key).ok_or(Error::Encoding)?;
let data_bytes: Cow<[u8]> = DC::bytes_encode(&data).ok_or(Error::Encoding)?;
self.cursor.put_current(&key_bytes, &data_bytes)
}
pub fn remap_types<KC2, DC2>(self) -> RwRevRange<'txn, KC2, DC2> {
RwRevRange {
cursor: self.cursor,
move_on_end: self.move_on_end,
start_bound: self.start_bound,
end_bound: self.end_bound,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RwRevRange<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RwRevRange<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RwRevRange<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RwRevRange<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_end {
self.move_on_end = false;
move_on_range_end(&mut self.cursor, &self.end_bound)
} else {
self.cursor.move_on_prev()
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match &self.start_bound {
Bound::Included(start) => key >= start,
Bound::Excluded(start) => key > start,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
}
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_end {
move_on_range_start(&mut self.cursor, &mut self.start_bound)
} else {
let current = self.cursor.current();
let start = move_on_range_start(&mut self.cursor, &mut self.start_bound);
match (current, start) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => {
let must_be_returned = match &self.end_bound {
Bound::Included(end) => key <= end,
Bound::Excluded(end) => key < end,
Bound::Unbounded => true,
};
if must_be_returned {
match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
}
} else {
None
}
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}