use core::ops::RangeFull;
use super::*;
pub struct SetRange<'a, T, C, Q: ?Sized = &'static str, R = RangeFull>(SetIterator<'a, T, C, Q, R>);
impl<'a, T, C, Q, R> Clone for SetRange<'a, T, C, Q, R>
where
R: Clone,
Q: Clone,
T: Clone,
{
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<'a, T, C, Q, R> Copy for SetRange<'a, T, C, Q, R>
where
R: Copy,
Q: Copy,
T: Copy,
{
}
impl<'a, T, C, Q, R> core::ops::Deref for SetRange<'a, T, C, Q, R> {
type Target = SetIterator<'a, T, C, Q, R>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T, C, Q, R> core::ops::DerefMut for SetRange<'a, T, C, Q, R> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub struct SetIterator<'a, T, C, Q: ?Sized = &'static [u8], R = core::ops::RangeFull> {
pub(super) map: &'a SkipSet<T, C>,
pub(super) nd: NodePtr<T>,
pub(super) version: u64,
pub(super) range: R,
pub(super) all_versions: bool,
pub(super) last: Option<EntryRef<'a, T>>,
pub(super) _phantom: core::marker::PhantomData<Q>,
}
impl<'a, R: Clone, Q: Clone, T: Clone, C> Clone for SetIterator<'a, T, C, Q, R> {
fn clone(&self) -> Self {
Self {
map: self.map,
nd: self.nd,
version: self.version,
range: self.range.clone(),
last: self.last.clone(),
all_versions: self.all_versions,
_phantom: core::marker::PhantomData,
}
}
}
impl<'a, R: Copy, Q: Copy, T: Copy, C> Copy for SetIterator<'a, T, C, Q, R> {}
impl<'a, T, C> SetIterator<'a, T, C>
where
C: Comparator,
{
#[inline]
pub(super) const fn new(version: u64, map: &'a SkipSet<T, C>, all_versions: bool) -> Self {
Self {
map,
nd: map.head,
version,
range: RangeFull,
last: None,
all_versions,
_phantom: core::marker::PhantomData,
}
}
}
impl<'a, Q, R, T, C> SetIterator<'a, T, C, Q, R> {
#[inline]
pub const fn bounds(&self) -> &R {
&self.range
}
}
impl<'a, Q, R, T, C> SetIterator<'a, T, C, Q, R>
where
C: Comparator,
T: Trailer,
&'a [u8]: PartialOrd<Q>,
Q: ?Sized + PartialOrd<&'a [u8]>,
R: RangeBounds<Q>,
{
#[inline]
pub(super) fn range(
version: u64,
map: &'a SkipSet<T, C>,
r: R,
all_versions: bool,
) -> SetRange<'a, T, C, Q, R> {
SetRange(Self {
map,
nd: map.head,
version,
range: r,
last: None,
all_versions,
_phantom: core::marker::PhantomData,
})
}
pub fn first(&mut self) -> Option<EntryRef<T>> {
self.nd = self.map.first_in(self.version)?;
loop {
if self.nd.is_null() || self.nd.ptr == self.map.tail.ptr {
return None;
}
unsafe {
let node = self.nd.as_ptr();
let nk = node.get_key(&self.map.arena);
if node.trailer.version() > self.version {
self.nd = self.map.get_next(self.nd, 0);
continue;
}
if self.map.cmp.contains(&self.range, nk) {
let ent = EntryRef {
key: nk,
trailer: node.trailer,
};
self.last = Some(ent);
return Some(ent);
}
self.nd = self.map.get_next(self.nd, 0);
}
}
}
pub fn last(&mut self) -> Option<EntryRef<T>> {
self.nd = self.map.last_in(self.version)?;
loop {
unsafe {
if self.nd.is_null() || self.nd.ptr == self.map.head.ptr {
return None;
}
let node = self.nd.as_ptr();
if node.trailer.version() > self.version {
self.nd = self.map.get_prev(self.nd, 0);
continue;
}
let nk = node.get_key(&self.map.arena);
if self.map.cmp.contains(&self.range, nk) {
let ent = EntryRef {
key: nk,
trailer: node.trailer,
};
return Some(ent);
}
self.nd = self.map.get_prev(self.nd, 0);
}
}
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<EntryRef<T>> {
loop {
unsafe {
self.nd = self.map.get_next(self.nd, 0);
if self.nd.is_null() || self.nd.ptr == self.map.tail.ptr {
return None;
}
let node = self.nd.as_ptr();
if node.trailer.version() > self.version {
continue;
}
let nk = node.get_key(&self.map.arena);
if !self.all_versions {
if let Some(last) = self.last {
if self.map.cmp.compare(last.key, nk) == cmp::Ordering::Equal {
continue;
}
}
}
if self.map.cmp.contains(&self.range, nk) {
let ent = EntryRef {
key: nk,
trailer: node.trailer,
};
self.last = Some(ent);
return Some(ent);
}
}
}
}
pub fn prev(&mut self) -> Option<EntryRef<T>> {
loop {
unsafe {
self.nd = self.map.get_prev(self.nd, 0);
if self.nd.is_null() || self.nd.ptr == self.map.head.ptr {
return None;
}
let node = self.nd.as_ptr();
if node.trailer.version() > self.version {
continue;
}
let nk = node.get_key(&self.map.arena);
if !self.all_versions {
if let Some(last) = self.last {
if self.map.cmp.compare(last.key, nk) == cmp::Ordering::Equal {
continue;
}
}
}
if self.map.cmp.contains(&self.range, nk) {
let ent = EntryRef {
key: nk,
trailer: node.trailer,
};
self.last = Some(ent);
return Some(ent);
}
}
}
}
pub fn seek_upper_bound(&mut self, upper: Bound<&[u8]>) -> Option<EntryRef<T>> {
match upper {
Bound::Included(key) => self.seek_le(key).map(|n| {
let ent = EntryRef::from_node(n, &self.map.arena);
self.last = Some(ent);
ent
}),
Bound::Excluded(key) => self.seek_lt(key).map(|n| {
let ent = EntryRef::from_node(n, &self.map.arena);
self.last = Some(ent);
ent
}),
Bound::Unbounded => self.last(),
}
}
pub fn seek_lower_bound(&mut self, lower: Bound<&[u8]>) -> Option<EntryRef<T>> {
match lower {
Bound::Included(key) => self.seek_ge(key).map(|n| {
let ent = EntryRef::from_node(n, &self.map.arena);
self.last = Some(ent);
ent
}),
Bound::Excluded(key) => self.seek_gt(key).map(|n| {
let ent = EntryRef::from_node(n, &self.map.arena);
self.last = Some(ent);
ent
}),
Bound::Unbounded => self.first(),
}
}
fn seek_ge(&mut self, key: &[u8]) -> Option<NodePtr<T>> {
self.nd = self.map.ge(self.version, key)?;
if self.nd.is_null() || self.nd.ptr == self.map.tail.ptr {
return None;
}
loop {
unsafe {
let node = self.nd.as_ptr();
let nk = node.get_key(&self.map.arena);
if self.map.cmp.contains(&self.range, nk) {
return Some(self.nd);
} else {
let upper = self.range.end_bound();
match upper {
Bound::Included(upper) => {
if upper.lt(&nk) {
return None;
}
}
Bound::Excluded(upper) => {
if upper.le(&nk) {
return None;
}
}
Bound::Unbounded => {}
}
self.nd = self.map.get_next(self.nd, 0);
}
}
}
}
fn seek_gt(&mut self, key: &[u8]) -> Option<NodePtr<T>> {
self.nd = self.map.gt(self.version, key)?;
if self.nd.is_null() || self.nd.ptr == self.map.tail.ptr {
return None;
}
loop {
unsafe {
let node = self.nd.as_ptr();
let nk = node.get_key(&self.map.arena);
if self.map.cmp.contains(&self.range, nk) {
return Some(self.nd);
} else {
let upper = self.range.end_bound();
match upper {
Bound::Included(upper) => {
if upper.lt(&nk) {
return None;
}
}
Bound::Excluded(upper) => {
if upper.le(&nk) {
return None;
}
}
Bound::Unbounded => {}
}
self.nd = self.map.get_next(self.nd, 0);
}
}
}
}
fn seek_le(&mut self, key: &[u8]) -> Option<NodePtr<T>> {
self.nd = self.map.le(self.version, key)?;
loop {
unsafe {
let node = self.nd.as_ptr();
let nk = node.get_key(&self.map.arena);
if self.map.cmp.contains(&self.range, nk) {
return Some(self.nd);
} else {
let lower = self.range.start_bound();
match lower {
Bound::Included(lower) => {
if lower.gt(&nk) {
return None;
}
}
Bound::Excluded(lower) => {
if lower.ge(&nk) {
return None;
}
}
Bound::Unbounded => {}
}
self.nd = self.map.get_prev(self.nd, 0);
}
}
}
}
fn seek_lt(&mut self, key: &[u8]) -> Option<NodePtr<T>> {
self.nd = self.map.lt(self.version, key)?;
loop {
unsafe {
let node = self.nd.as_ptr();
let nk = node.get_key(&self.map.arena);
if self.map.cmp.contains(&self.range, nk) {
return Some(self.nd);
} else {
let lower = self.range.start_bound();
match lower {
Bound::Included(lower) => {
if lower.gt(&nk) {
return None;
}
}
Bound::Excluded(lower) => {
if lower.ge(&nk) {
return None;
}
}
Bound::Unbounded => {}
}
self.nd = self.map.get_prev(self.nd, 0);
}
}
}
}
}