Skip to content

Commit

Permalink
Implement range iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
Bergmann89 committed Mar 8, 2024
1 parent 1e96e8e commit ed999c4
Show file tree
Hide file tree
Showing 10 changed files with 949 additions and 59 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ exclude = [ "/.*" ]
[features]
std = [ ]
default = [ "std" ]
range = [ ]

[build-dependencies]
autocfg = "1"
Expand All @@ -31,3 +32,4 @@ serde = { version = "1.0", optional = true, default-features = false, features =
rustversion = "1"
serde = { version = "1", features = [ "derive" ] }
serde_test = "1"
rand = "0.8"
39 changes: 30 additions & 9 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::mem::replace;

use crate::entries::{Entries, Entry};
use crate::generic::GenericSlab;
use crate::key::Key;
Expand Down Expand Up @@ -29,19 +31,32 @@ where
let slab = &mut self.slab;

if index < slab.entries.as_ref().len() {
let entry = &mut slab.entries.as_mut()[index];

// iterator is not sorted, might need to recreate vacant list
if let Entry::Vacant { .. } = &*entry {
self.vacant_list_broken = true;
slab.meta.len += 1;
match replace(&mut slab.entries.as_mut()[index], Entry::Unknown) {
Entry::Vacant { .. } => {
self.vacant_list_broken = true;
slab.meta.len += 1;
}
Entry::Occupied {
#[cfg(feature = "range")]
range,
..
} => {
#[cfg(feature = "range")]
slab.remove_occupied_index(index, range);
}
_ => unreachable!(),
}

#[cfg(feature = "range")]
let range = slab.insert_occupied_index(index);

// if an element with this key already exists, replace it.
// This is consistent with HashMap and BtreeMap
*entry = Entry::Occupied {
slab.entries.as_mut()[index] = Entry::Occupied {
value,
key_data: Default::default(),
key_data: key.into_occupied_data(),
#[cfg(feature = "range")]
range,
};
} else {
if self.first_vacant_index.is_none() && slab.entries.as_ref().len() < index {
Expand All @@ -58,9 +73,15 @@ where
key_data: Default::default(),
});
}

#[cfg(feature = "range")]
let range = slab.insert_occupied_index(index);

slab.entries.push(Entry::Occupied {
value,
key_data: Default::default(),
key_data: key.into_occupied_data(),
#[cfg(feature = "range")]
range,
});
slab.meta.len += 1;
}
Expand Down
46 changes: 37 additions & 9 deletions src/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ where

/// Key related data for this entry
key_data: TKey::OccupiedData,

/// Indices of the range feature
#[cfg(feature = "range")]
range: RangeIndices,
},

/// Unknown state for this entry
Expand All @@ -128,13 +132,20 @@ where
fn clone(&self) -> Self {
match self {
Entry::Unknown => unreachable!(),
Entry::Vacant { next, key_data } => Self::Vacant {
Entry::Vacant { next, key_data } => Entry::Vacant {
next: *next,
key_data: key_data.clone(),
},
Entry::Occupied { value, key_data } => Self::Occupied {
Entry::Occupied {
value,
key_data,
#[cfg(feature = "range")]
range,
} => Entry::Occupied {
value: value.clone(),
key_data: key_data.clone(),
#[cfg(feature = "range")]
range: *range,
},
}
}
Expand All @@ -149,17 +160,34 @@ where
{
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::Unknown => write!(f, "Unknown"),
Self::Vacant { next, key_data } => f
Entry::Unknown => write!(f, "Unknown"),
Entry::Vacant { next, key_data } => f
.debug_struct("Vacant")
.field("next", next)
.field("key_data", key_data)
.finish(),
Self::Occupied { value, key_data } => f
.debug_struct("Occupied")
.field("value", value)
.field("key_data", key_data)
.finish(),
Entry::Occupied {
value,
key_data,
#[cfg(feature = "range")]
range,
} => {
let mut s = f.debug_struct("Occupied");
s.field("value", value);
s.field("key_data", key_data);
#[cfg(feature = "range")]
s.field("range", range);
s.finish()
}
}
}
}

/* RangeIndices */

#[cfg(feature = "range")]
#[derive(Debug, Clone, Copy)]
pub struct RangeIndices {
pub(crate) prev: usize,
pub(crate) next: usize,
}
Loading

0 comments on commit ed999c4

Please sign in to comment.