Skip to content

Commit

Permalink
use u5 and u27 in public API
Browse files Browse the repository at this point in the history
  • Loading branch information
al8n committed Jun 18, 2024
1 parent 3396f96 commit bdb3b85
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 68 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "skl"
version = "0.11.1"
version = "0.11.2"
edition = "2021"
rust-version = "1.56.0"
repository = "https://github.com/al8n/skl"
Expand Down Expand Up @@ -46,6 +46,7 @@ getrandom = { version = "0.2", features = ["js"] }
either = { version = "1", default-features = false }
rand = { version = "0.8", default-features = false, features = ["getrandom"] }
rarena-allocator = { version = "0.1", default-features = false }
ux2 = { version = "0.8", default-features = false, features = ["32"] }

tracing = { version = "0.1", optional = true }

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub use rarena_allocator::{Arena, Error as ArenaError};

pub use map::{AllVersionsIter, SkipMap};

pub use ux2::{u27, u5};

const MAX_HEIGHT: usize = 32;

#[cfg(feature = "std")]
Expand Down
28 changes: 13 additions & 15 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ impl<T, C> Drop for SkipMap<T, C> {

impl<T, C> SkipMap<T, C> {
fn new_in(arena: Arena, cmp: C, opts: Options) -> Result<Self, Error> {
let data_offset = Self::check_capacity(&arena, opts.max_height())?;
let data_offset = Self::check_capacity(&arena, opts.max_height().into())?;

if arena.read_only() {
let (meta, head, tail) = Self::get_pointers(&arena);
Expand Down Expand Up @@ -640,14 +640,15 @@ impl<T, C> SkipMap<T, C> {
}
};

let head = Self::allocate_full_node(&arena, opts.max_height())?;
let tail = Self::allocate_full_node(&arena, opts.max_height())?;
let max_height: u8 = opts.max_height().into();
let head = Self::allocate_full_node(&arena, max_height)?;
let tail = Self::allocate_full_node(&arena, max_height)?;

// Safety:
// We will always allocate enough space for the head node and the tail node.
unsafe {
// Link all head/tail levels together.
for i in 0..(opts.max_height() as usize) {
for i in 0..(max_height as usize) {
let head_link = head.tower(&arena, i);
let tail_link = tail.tower(&arena, i);
head_link.next_offset.store(tail.offset, Ordering::Relaxed);
Expand Down Expand Up @@ -1085,17 +1086,14 @@ impl<T, C> SkipMap<T, C> {
}

#[inline]
const fn check_node_size(
&self,
height: u32,
key_size: u32,
mut value_size: u32,
) -> Result<(), Error> {
if height < 1 || height > self.opts.max_height() as u32 {
fn check_node_size(&self, height: u32, key_size: u32, mut value_size: u32) -> Result<(), Error> {
let max_height: u32 = self.opts.max_height().into();
if height < 1 || height > max_height {
panic!("height cannot be less than one or greater than the max height");
}

if key_size > self.opts.max_key_size() {
let max_key_size: u32 = self.opts.max_key_size().into();
if key_size > max_key_size {
return Err(Error::KeyTooLarge(key_size as u64));
}

Expand Down Expand Up @@ -1156,7 +1154,7 @@ impl<T: Trailer, C> SkipMap<T, C> {
value_size: u32,
f: impl FnOnce(&mut VacantBuffer<'a>) -> Result<(), E>,
) -> Result<(NodePtr<T>, u32, Deallocator), Either<E, Error>> {
let height = super::random_height(self.opts.max_height());
let height = super::random_height(self.opts.max_height().into());
let (nd, deallocator) = match key {
Key::Occupied(key) => self.allocate_entry_node(
height,
Expand Down Expand Up @@ -1700,12 +1698,12 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {

fn fetch_vacant_key<'a, 'b: 'a, E>(
&'a self,
key_size: u16,
key_size: u32,
key: impl FnOnce(&mut VacantBuffer<'a>) -> Result<(), E>,
) -> Result<VacantBuffer<'a>, Either<E, Error>> {
let (key_offset, key_size) = self
.arena
.alloc_bytes(key_size as u32)
.alloc_bytes(key_size)
.map(|mut b| {
b.detach();
(b.offset(), b.capacity())
Expand Down
38 changes: 19 additions & 19 deletions src/map/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rarena_allocator::ArenaOptions;
use ux2::u27;

use super::*;

Expand Down Expand Up @@ -389,14 +390,15 @@ impl<T, C> SkipMap<T, C> {

self.meta = meta;

let head = Self::allocate_full_node(&self.arena, self.opts.max_height())?;
let tail = Self::allocate_full_node(&self.arena, self.opts.max_height())?;
let max_height: u8 = self.opts.max_height().into();
let head = Self::allocate_full_node(&self.arena, max_height)?;
let tail = Self::allocate_full_node(&self.arena, max_height)?;

// Safety:
// We will always allocate enough space for the head node and the tail node.
unsafe {
// Link all head/tail levels together.
for i in 0..(self.opts.max_height() as usize) {
for i in 0..(max_height as usize) {
let head_link = head.tower(&self.arena, i);
let tail_link = tail.tower(&self.arena, i);
head_link.next_offset.store(tail.offset, Ordering::Relaxed);
Expand Down Expand Up @@ -701,7 +703,7 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
/// # Example
///
/// ```rust
/// use skl::SkipMap;
/// use skl::{SkipMap, u27};
///
/// struct Person {
/// id: u32,
Expand All @@ -724,7 +726,7 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
///
/// let l = SkipMap::new().unwrap();
///
/// l.insert_with::<core::convert::Infallible>(1, 5, |key| {
/// l.insert_with::<core::convert::Infallible>(1, u27::new(5), |key| {
/// key.write(b"alice").unwrap();
/// Ok(())
/// }, encoded_size as u32, |mut val| {
Expand All @@ -737,12 +739,12 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
pub fn insert_with<'a, E>(
&'a self,
trailer: T,
key_size: u16,
key_size: u27,
key: impl FnOnce(&mut VacantBuffer<'a>) -> Result<(), E>,
val_size: u32,
val: impl FnOnce(&mut VacantBuffer<'a>) -> Result<(), E> + Copy,
) -> Result<Option<EntryRef<'a, T, C>>, Either<E, Error>> {
let vk = self.fetch_vacant_key(key_size, key)?;
let vk = self.fetch_vacant_key(u32::from(key_size), key)?;

self
.update(
Expand Down Expand Up @@ -779,7 +781,7 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
/// # Example
///
/// ```rust
/// use skl::SkipMap;
/// use skl::{SkipMap, u27};
///
/// struct Person {
/// id: u32,
Expand All @@ -802,7 +804,7 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
///
/// let l = SkipMap::new().unwrap();
///
/// l.get_or_insert_with::<core::convert::Infallible>(1, 5, |key| {
/// l.get_or_insert_with::<core::convert::Infallible>(1, u27::new(5), |key| {
/// key.write(b"alice").unwrap();
/// Ok(())
/// }, encoded_size as u32, |mut val| {
Expand All @@ -815,12 +817,12 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
pub fn get_or_insert_with<'a, E>(
&'a self,
trailer: T,
key_size: u16,
key_size: u27,
key: impl FnOnce(&mut VacantBuffer<'a>) -> Result<(), E>,
val_size: u32,
val: impl FnOnce(&mut VacantBuffer<'a>) -> Result<(), E> + Copy,
) -> Result<Option<EntryRef<'a, T, C>>, Either<E, Error>> {
let vk = self.fetch_vacant_key(key_size, key)?;
let vk = self.fetch_vacant_key(u32::from(key_size), key)?;

self
.update(
Expand Down Expand Up @@ -944,7 +946,7 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
/// # Example
///
/// ```rust
/// use skl::SkipMap;
/// use skl::{SkipMap, u27};
///
/// struct Person {
/// id: u32,
Expand All @@ -967,7 +969,7 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
///
/// let l = SkipMap::new().unwrap();
///
/// l.get_or_remove_with::<core::convert::Infallible>(1, 5, |key| {
/// l.get_or_remove_with::<core::convert::Infallible>(1, u27::new(5), |key| {
/// key.write(b"alice").unwrap();
/// Ok(())
/// })
Expand All @@ -976,15 +978,15 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
pub fn get_or_remove_with<'a, 'b: 'a, E>(
&'a self,
trailer: T,
key_size: u16,
key_size: u27,
key: impl FnOnce(&mut VacantBuffer<'a>) -> Result<(), E>,
) -> Result<Option<EntryRef<'a, T, C>>, Either<E, Error>> {
let vk = self.fetch_vacant_key(key_size, key)?;

let vk = self.fetch_vacant_key(u32::from(key_size), key)?;
let key = Key::RemoveVacant(vk);
self
.update(
trailer,
Key::RemoveVacant(vk),
key,
0,
noop::<Infallible>,
Ordering::Relaxed,
Expand All @@ -995,8 +997,6 @@ impl<T: Trailer, C: Comparator> SkipMap<T, C> {
.map(|res| match res {
Either::Left(old) => match old {
Some(old) => {
self.arena.increase_discarded(key_size as u32);

if old.is_removed() {
None
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/map/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2440,7 +2440,7 @@ fn get_or_insert_with(l: SkipMap) {

l.get_or_insert_with::<()>(
1,
5,
u27::new(5),
|key| {
key.write(b"alice").unwrap();
Ok(())
Expand Down Expand Up @@ -2695,7 +2695,7 @@ fn insert_with(l: SkipMap) {

l.insert_with::<()>(
1,
5,
u27::new(5),
|key| {
key.write(b"alice").unwrap();
Ok(())
Expand Down Expand Up @@ -2730,7 +2730,7 @@ fn insert_with(l: SkipMap) {
let old = l
.insert_with::<()>(
1,
5,
u27::new(5),
|key| {
key.write(b"alice").unwrap();
Ok(())
Expand Down
58 changes: 33 additions & 25 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ pub use rarena_allocator::{MmapOptions, OpenOptions};

pub use rarena_allocator::Freelist;

const U27_MAX: u32 = (1 << 27) - 1;
use ux2::{u27, u5};

/// Options for `SkipMap`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Options {
max_value_size: u32,
max_key_size: u32,
max_height: u8,
max_key_size: u27,
max_height: u5,
magic_version: u16,
capacity: u32,
unify: bool,
Expand All @@ -31,8 +31,8 @@ impl Options {
pub const fn new() -> Self {
Self {
max_value_size: u32::MAX,
max_key_size: U27_MAX,
max_height: 20,
max_key_size: u27::MAX,
max_height: u5::new(20),
capacity: 1024,
unify: false,
magic_version: 0,
Expand Down Expand Up @@ -127,13 +127,13 @@ impl Options {
/// # Example
///
/// ```
/// use skl::Options;
/// use skl::{Options, u27};
///
/// let options = Options::new().with_max_key_size(1024);
/// let options = Options::new().with_max_key_size(u27::new(1024));
/// ```
#[inline]
pub const fn with_max_key_size(mut self, size: u32) -> Self {
self.max_key_size = if size > U27_MAX { U27_MAX } else { size };
pub const fn with_max_key_size(mut self, size: u27) -> Self {
self.max_key_size = size;
self
}

Expand All @@ -144,19 +144,13 @@ impl Options {
/// # Example
///
/// ```
/// use skl::Options;
/// use skl::{Options, u5};
///
/// let options = Options::new().with_max_height(20);
/// let options = Options::new().with_max_height(u5::new(20));
/// ```
#[inline]
pub const fn with_max_height(mut self, height: u8) -> Self {
self.max_height = if height == 0 {
1
} else if height > 31 {
31
} else {
height
};
pub const fn with_max_height(mut self, height: u5) -> Self {
self.max_height = height;
self
}

Expand Down Expand Up @@ -194,26 +188,40 @@ impl Options {
}

/// Returns the maximum size of the key.
///
/// The maximum size of the key is `u27::MAX`.
///
/// Default is `u27::MAX`.
///
/// # Example
///
/// ```
/// use skl::{Options, u27};
///
/// let options = Options::new().with_max_key_size(u27::new(1024));
///
/// assert_eq!(options.max_key_size(), u27::new(1024));
/// ```
#[inline]
pub const fn max_key_size(&self) -> u32 {
pub const fn max_key_size(&self) -> u27 {
self.max_key_size
}

/// Returns the maximum height.
///
/// Default is `20`. The maximum height is `31`. The minimum height is `1`.
/// Default is `20`. The maximum height is `u5::MAX`. The minimum height is `1`.
///
/// # Example
///
/// ```
/// use skl::Options;
/// use skl::{Options, u5};
///
/// let options = Options::new().with_max_height(20);
/// let options = Options::new().with_max_height(u5::new(5));
///
/// assert_eq!(options.max_height(), 20);
/// assert_eq!(options.max_height(), u5::new(5));
/// ```
#[inline]
pub const fn max_height(&self) -> u8 {
pub const fn max_height(&self) -> u5 {
self.max_height
}

Expand Down
Loading

0 comments on commit bdb3b85

Please sign in to comment.