Skip to content

Commit

Permalink
test different freelist (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
al8n authored Sep 29, 2024
1 parent ad39c4d commit c6a3db4
Show file tree
Hide file tree
Showing 27 changed files with 476 additions and 757 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ jobs:
- sync_versioned_concurrent
- sync_trailed_concurrent
- sync_full_concurrent
- sync_map_concurrent_with_optimistic_freelist
- sync_versioned_concurrent_with_optimistic_freelist
- sync_trailed_concurrent_with_optimistic_freelist
- sync_full_concurrent_with_optimistic_freelist
- sync_map_concurrent_with_pessimistic_freelist
- sync_versioned_concurrent_with_pessimistic_freelist
- sync_trailed_concurrent_with_pessimistic_freelist
- sync_full_concurrent_with_pessimistic_freelist
# Exclude invalid combinations
exclude:
- os: ubuntu-latest
Expand Down Expand Up @@ -329,6 +337,14 @@ jobs:
- sync_versioned_concurrent
- sync_trailed_concurrent
- sync_full_concurrent
- sync_map_concurrent_with_optimistic_freelist
- sync_versioned_concurrent_with_optimistic_freelist
- sync_trailed_concurrent_with_optimistic_freelist
- sync_full_concurrent_with_optimistic_freelist
- sync_map_concurrent_with_pessimistic_freelist
- sync_versioned_concurrent_with_pessimistic_freelist
- sync_trailed_concurrent_with_pessimistic_freelist
- sync_full_concurrent_with_pessimistic_freelist
# Exclude invalid combinations
exclude:
- os: ubuntu-latest
Expand Down
12 changes: 10 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ getrandom = { version = "0.2", features = ["js"] }
among = { version = "0.1", default-features = false }
arbitrary-int = { version = "1.2", default-features = false }
derive_more = "0.99"
dbutils = { version = "0.3", default-features = false }
dbutils = { version = "0.4", default-features = false }
either = { version = "1", default-features = false }
memchr = { version = "2", default-features = false, optional = true }
rand = { version = "0.8", default-features = false, features = ["getrandom"] }
# rarena-allocator = { version = "0.3", default-features = false, path = "../arena/rarena-allocator" }
rarena-allocator = { version = "0.3", default-features = false }
rarena-allocator = { version = "0.4", default-features = false }
viewit = "0.1.5"
paste = "1"
zerocopy = { version = "0.7", features = ["derive"] }
Expand Down Expand Up @@ -99,4 +99,12 @@ unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(test_sync_versioned_concurrent)',
'cfg(test_sync_trailed_concurrent)',
'cfg(test_sync_map_concurrent)',
'cfg(test_sync_full_concurrent_with_optimistic_freelist)',
'cfg(test_sync_versioned_concurrent_with_optimistic_freelist)',
'cfg(test_sync_trailed_concurrent_with_optimistic_freelist)',
'cfg(test_sync_map_concurrent_with_optimistic_freelist)',
'cfg(test_sync_full_concurrent_with_pessimistic_freelist)',
'cfg(test_sync_versioned_concurrent_with_pessimistic_freelist)',
'cfg(test_sync_trailed_concurrent_with_pessimistic_freelist)',
'cfg(test_sync_map_concurrent_with_pessimistic_freelist)',
] }
24 changes: 0 additions & 24 deletions src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,32 +184,8 @@ mod sealed {

fn set_key_offset(&mut self, key_offset: u32);

fn version(&self) -> Version;

fn set_version(&mut self, version: Version);

fn key_size_and_height(&self) -> u32;

fn key_offset(&self) -> u32;

#[inline]
fn key_size(&self) -> u32 {
decode_key_size_and_height(self.key_size_and_height()).0
}

#[inline]
fn height(&self) -> u8 {
decode_key_size_and_height(self.key_size_and_height()).1
}

/// ## Safety
///
/// - The caller must ensure that the node is allocated by the arena.
#[inline]
unsafe fn get_key<'a, 'b: 'a, A: Allocator>(&'a self, arena: &'b A) -> &'b [u8] {
arena.get_bytes(self.key_offset() as usize, self.key_size() as usize)
}

/// ## Safety
///
/// - The caller must ensure that the node is allocated by the arena.
Expand Down
17 changes: 9 additions & 8 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ where
}
}

#[cfg(all(feature = "memmap", not(target_family = "wasm"), not(windows)))]
if self.arena.is_mmap() && self.arena.options().lock_meta() {
#[cfg(all(feature = "memmap", not(target_family = "wasm"), not(miri)))]
if self.arena.is_map() && self.arena.options().lock_meta() {
let _ = unsafe { self.arena.munlock(0, self.arena.page_size()) };
}
}
Expand Down Expand Up @@ -142,12 +142,13 @@ where
) -> Result<(<A::Node as Node>::Pointer, Deallocator), Either<E, Error>> {
let (nd, deallocator) = match key {
Key::Occupied(key) => {
let kb = KeyBuilder::new(KeySize::from_u32_unchecked(key.len() as u32), |buf| {
buf
.put_slice(key)
.expect("buffer must be large enough for key");
Ok(())
});
let kb = KeyBuilder::new(
KeySize::from_u32_unchecked(key.len() as u32),
|buf: &mut VacantBuffer<'_>| {
buf.put_slice_unchecked(key);
Ok(())
},
);
let vb = value_builder.unwrap();
self
.arena
Expand Down
4 changes: 0 additions & 4 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,6 @@ impl<C> Builder<C> {
///
/// let builder = Builder::new().with_freelist(Freelist::Optimistic);
/// ```
#[cfg(feature = "experimental")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
#[inline]
pub const fn with_freelist(mut self, freelist: Freelist) -> Self {
self.opts.freelist = freelist;
Expand Down Expand Up @@ -440,8 +438,6 @@ impl<C> Builder<C> {
///
/// assert_eq!(builder.freelist(), Freelist::Optimistic);
/// ```
#[cfg(feature = "experimental")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
#[inline]
pub const fn freelist(&self) -> Freelist {
self.opts.freelist
Expand Down
11 changes: 3 additions & 8 deletions src/builder/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ impl Options {
///
/// let opts = Options::new().with_freelist(Freelist::Optimistic);
/// ```
#[cfg(feature = "experimental")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
#[inline]
pub const fn with_freelist(mut self, freelist: Freelist) -> Self {
self.freelist = freelist;
Expand Down Expand Up @@ -466,8 +464,6 @@ impl Options {
///
/// assert_eq!(opts.freelist(), Freelist::Optimistic);
/// ```
#[cfg(feature = "experimental")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
#[inline]
pub const fn freelist(&self) -> Freelist {
self.freelist
Expand Down Expand Up @@ -500,14 +496,13 @@ impl Options {
.with_magic_version(CURRENT_VERSION)
.with_reserved(self.reserved())
.with_unify(self.unify())
.maybe_capacity(self.capacity);

#[cfg(feature = "experimental")]
let opts = opts.with_freelist(self.freelist());
.maybe_capacity(self.capacity)
.with_freelist(self.freelist());

#[cfg(all(feature = "memmap", not(target_family = "wasm")))]
{
opts
.with_lock_meta(false) // we need to avoid arena's lock_meta
.with_create(self.create())
.with_create_new(self.create_new())
.with_read(self.read())
Expand Down
14 changes: 9 additions & 5 deletions src/builder/options/open_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use core::mem;

use dbutils::Comparator;
use either::Either;

#[cfg(not(windows))]
use rarena_allocator::Allocator;

use super::{super::Builder, Options, CURRENT_VERSION};
Expand Down Expand Up @@ -61,7 +59,7 @@ impl<C: Comparator> Builder<C> {
.map_err(invalid_data)
.and_then(|map| {
// Lock the memory of first page to prevent it from being swapped out.
#[cfg(not(windows))]
#[cfg(not(miri))]
if opts.lock_meta {
unsafe {
let arena = map.allocator();
Expand Down Expand Up @@ -127,6 +125,12 @@ impl<C: Comparator> Builder<C> {
opts
.to_arena_options()
.with_unify(true)
.with_read(true)
.with_create(false)
.with_create_new(false)
.with_write(false)
.with_truncate(false)
.with_append(false)
.with_maximum_alignment(node_align.max(trailer_align))
.map_with_path_builder::<<T::Allocator as Sealed>::Allocator, _, _>(path_builder)
.and_then(|arena| {
Expand All @@ -139,7 +143,7 @@ impl<C: Comparator> Builder<C> {
Err(bad_version())
} else {
// Lock the memory of first page to prevent it from being swapped out.
#[cfg(not(windows))]
#[cfg(not(miri))]
if opts.lock_meta {
unsafe {
let allocator = map.allocator();
Expand Down Expand Up @@ -222,7 +226,7 @@ impl<C: Comparator> Builder<C> {
Err(bad_version())
} else {
// Lock the memory of first page to prevent it from being swapped out.
#[cfg(not(windows))]
#[cfg(not(miri))]
if opts.lock_meta {
unsafe {
let allocator = map.allocator();
Expand Down
31 changes: 9 additions & 22 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ pub mod iter {
test_sync_map_concurrent,
test_sync_versioned_concurrent,
test_sync_trailed_concurrent,
test_sync_full_concurrent_with_optimistic_freelist,
test_sync_map_concurrent_with_optimistic_freelist,
test_sync_versioned_concurrent_with_optimistic_freelist,
test_sync_trailed_concurrent_with_optimistic_freelist,
test_sync_full_concurrent_with_pessimistic_freelist,
test_sync_map_concurrent_with_pessimistic_freelist,
test_sync_versioned_concurrent_with_pessimistic_freelist,
test_sync_trailed_concurrent_with_pessimistic_freelist,
))]
mod tests;

Expand Down Expand Up @@ -187,11 +195,6 @@ macro_rules! node {

type Pointer = $pointer:ty;

fn version(&self) -> Version {
$($default_version_getter:ident)?
$({ $getter_this:ident.$version_getter:ident })?
}

fn set_version(&mut self, version: Version) {
$(
self.$version_setter:ident = version;
Expand Down Expand Up @@ -243,7 +246,7 @@ macro_rules! node {
.field("key_offset", &self.key_offset)
.field("key_size", &key_size)
.field("height", &height)
// $(.field("version", &self.$version))?
$(.field("version", &self.$version_setter))?
.finish()
}
}
Expand Down Expand Up @@ -286,26 +289,10 @@ macro_rules! node {
self.key_offset = key_offset;
}

#[inline]
fn version(&self) -> Version {
$($default_version_getter)?
$(self.$version_getter)?
}

#[inline]
fn set_version(&mut self, _version: Version) {
$(self.$version_setter = _version)?
}

#[inline]
fn key_size_and_height(&self) -> u32 {
self.key_size_and_height
}

#[inline]
fn key_offset(&self) -> u32 {
self.key_offset
}
}

$($tt)*
Expand Down
29 changes: 23 additions & 6 deletions src/sync/full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,30 @@ mod tests {
mod concurrent_tests {
use super::*;

__full_map_tests!(go "sync_full_map": SkipMap<u64, Ascend>);
__full_map_tests!(go "sync_full_map": SkipMap<u64> => crate::tests::TEST_OPTIONS);
}

#[cfg(any(
all(test, not(miri)),
all_tests,
test_sync_full_concurrent_with_optimistic_freelist,
))]
mod concurrent_tests_with_optimistic_freelist {
use super::*;

__full_map_tests!(go "sync_full_map": SkipMap<u64> => crate::tests::TEST_OPTIONS_WITH_OPTIMISTIC_FREELIST);
}

#[cfg(any(
all(test, not(miri)),
all_tests,
test_sync_full_concurrent_with_pessimistic_freelist,
))]
mod concurrent_tests_with_pessimistic_freelist {
use super::*;

__full_map_tests!(go "sync_full_map": SkipMap<u64> => crate::tests::TEST_OPTIONS_WITH_PESSIMISTIC_FREELIST);
}
type Allocator<T> = GenericAllocator<VersionedMeta, FullNode<T>, Arena>;
type SkipList<T, C> = base::SkipList<Allocator<T>, C>;

Expand All @@ -31,10 +52,6 @@ node!(
type ValuePointer = AtomicValuePointer;
type Pointer = NodePointer<T>;

fn version(&self) -> Version {
{ self.version }
}

fn set_version(&mut self, version: Version) {
self.version = version;
}
Expand All @@ -55,7 +72,7 @@ node!(
}
);

/// A fast, lock-free, thread-safe ARENA based `SkipMap` that supports trailed structure, multiple versions, forward and backward iteration.
/// A fast, lock-free, thread-safe ARENA based `SkipMap` that supports full structure, multiple versions, forward and backward iteration.
///
/// If you want to use in non-concurrent environment, you can use [`unsync::full::SkipMap`].
#[repr(transparent)]
Expand Down
28 changes: 23 additions & 5 deletions src/sync/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,29 @@ mod tests {
mod concurrent_tests {
use super::*;

__map_tests!(go "sync_map": SkipMap);
__map_tests!(go "sync_map_map": SkipMap => crate::tests::TEST_OPTIONS);
}

#[cfg(any(
all(test, not(miri)),
all_tests,
test_sync_map_concurrent_with_optimistic_freelist,
))]
mod concurrent_tests_with_optimistic_freelist {
use super::*;

__map_tests!(go "sync_map_map": SkipMap => crate::tests::TEST_OPTIONS_WITH_OPTIMISTIC_FREELIST);
}

#[cfg(any(
all(test, not(miri)),
all_tests,
test_sync_map_concurrent_with_pessimistic_freelist,
))]
mod concurrent_tests_with_pessimistic_freelist {
use super::*;

__map_tests!(go "sync_map_map": SkipMap => crate::tests::TEST_OPTIONS_WITH_PESSIMISTIC_FREELIST);
}

type Allocator = GenericAllocator<Meta, RawNode, Arena>;
Expand All @@ -27,10 +49,6 @@ node!(
type ValuePointer = AtomicValuePointer;
type Pointer = NodePointer;

fn version(&self) -> Version {
MIN_VERSION
}

fn set_version(&mut self, version: Version) {}

node_pointer!(RawNode {{
Expand Down
Loading

0 comments on commit c6a3db4

Please sign in to comment.