use std::borrow::Cow;
use std::marker;
use crate::*;
use super::{advance_key, retreat_key};
fn move_on_prefix_end<'txn>(
cursor: &mut RoCursor<'txn>,
prefix: &mut Vec<u8>,
) -> Result<Option<(&'txn [u8], &'txn [u8])>>
{
advance_key(prefix);
let result = cursor
.move_on_key_greater_than_or_equal_to(prefix)
.and_then(|_| cursor.move_on_prev());
retreat_key(prefix);
result
}
pub struct RoPrefix<'txn, KC, DC> {
cursor: RoCursor<'txn>,
prefix: Vec<u8>,
move_on_first: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RoPrefix<'txn, KC, DC> {
pub(crate) fn new(cursor: RoCursor<'txn>, prefix: Vec<u8>) -> RoPrefix<'txn, KC, DC> {
RoPrefix { cursor, prefix, move_on_first: true, _phantom: marker::PhantomData }
}
pub fn remap_types<KC2, DC2>(self) -> RoPrefix<'txn, KC2, DC2> {
RoPrefix {
cursor: self.cursor,
prefix: self.prefix,
move_on_first: self.move_on_first,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RoPrefix<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RoPrefix<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RoPrefix<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RoPrefix<'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_first {
self.move_on_first = false;
self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
} else {
self.cursor.move_on_next()
};
match result {
Ok(Some((key, data))) => {
if key.starts_with(&self.prefix) {
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_first {
move_on_prefix_end(&mut self.cursor, &mut self.prefix)
} else {
match (self.cursor.current(), move_on_prefix_end(&mut self.cursor, &mut self.prefix)) {
(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))) => {
if key.starts_with(&self.prefix) {
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 RwPrefix<'txn, KC, DC> {
cursor: RwCursor<'txn>,
prefix: Vec<u8>,
move_on_first: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RwPrefix<'txn, KC, DC> {
pub(crate) fn new(cursor: RwCursor<'txn>, prefix: Vec<u8>) -> RwPrefix<'txn, KC, DC> {
RwPrefix { cursor, prefix, move_on_first: true, _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) -> RwPrefix<'txn, KC2, DC2> {
RwPrefix {
cursor: self.cursor,
prefix: self.prefix,
move_on_first: self.move_on_first,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RwPrefix<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RwPrefix<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RwPrefix<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RwPrefix<'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_first {
self.move_on_first = false;
self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
} else {
self.cursor.move_on_next()
};
match result {
Ok(Some((key, data))) => {
if key.starts_with(&self.prefix) {
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_first {
move_on_prefix_end(&mut self.cursor, &mut self.prefix)
} else {
match (self.cursor.current(), move_on_prefix_end(&mut self.cursor, &mut self.prefix)) {
(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))) => {
if key.starts_with(&self.prefix) {
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 RoRevPrefix<'txn, KC, DC> {
cursor: RoCursor<'txn>,
prefix: Vec<u8>,
move_on_last: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RoRevPrefix<'txn, KC, DC> {
pub(crate) fn new(cursor: RoCursor<'txn>, prefix: Vec<u8>) -> RoRevPrefix<'txn, KC, DC> {
RoRevPrefix { cursor, prefix, move_on_last: true, _phantom: marker::PhantomData }
}
pub fn remap_types<KC2, DC2>(self) -> RoRevPrefix<'txn, KC2, DC2> {
RoRevPrefix {
cursor: self.cursor,
prefix: self.prefix,
move_on_last: self.move_on_last,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RoRevPrefix<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RoRevPrefix<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RoRevPrefix<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RoRevPrefix<'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_last {
self.move_on_last = false;
move_on_prefix_end(&mut self.cursor, &mut self.prefix)
} else {
self.cursor.move_on_prev()
};
match result {
Ok(Some((key, data))) => {
if key.starts_with(&self.prefix) {
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_last {
self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
} else {
let current = self.cursor.current();
let start = self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix);
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))) => {
if key.starts_with(&self.prefix) {
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 RwRevPrefix<'txn, KC, DC> {
cursor: RwCursor<'txn>,
prefix: Vec<u8>,
move_on_last: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RwRevPrefix<'txn, KC, DC> {
pub(crate) fn new(cursor: RwCursor<'txn>, prefix: Vec<u8>) -> RwRevPrefix<'txn, KC, DC> {
RwRevPrefix { cursor, prefix, move_on_last: true, _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) -> RwRevPrefix<'txn, KC2, DC2> {
RwRevPrefix {
cursor: self.cursor,
prefix: self.prefix,
move_on_last: self.move_on_last,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RwRevPrefix<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RwRevPrefix<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RwRevPrefix<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RwRevPrefix<'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_last {
self.move_on_last = false;
move_on_prefix_end(&mut self.cursor, &mut self.prefix)
} else {
self.cursor.move_on_prev()
};
match result {
Ok(Some((key, data))) => {
if key.starts_with(&self.prefix) {
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_last {
self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
} else {
let current = self.cursor.current();
let start = self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix);
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))) => {
if key.starts_with(&self.prefix) {
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)),
}
}
}