Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add K: ?Sized and V: ?Sized for generic wal #10

Merged
merged 3 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# 0.1.0 (Sep 14th, 2024)
# Rleases

- Publish version `0.1.0`
## 0.4.0 (Sep 30th, 2024)

FEATURES

- Support `K: ?Sized` and `V: ?Sized` for `GenericOrderWal`.
- Use `flush_header_and_range` instead of `flush_range` when insertion.

## 0.1.0 (Sep 14th, 2024)

- Publish version `0.1.0`
14 changes: 7 additions & 7 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,11 @@ impl<C, S> Builder<C, S> {
/// use orderwal::Builder;
///
/// let options = Builder::new();
/// assert_eq!(options.sync_on_write(), true);
/// assert_eq!(options.sync(), true);
/// ```
#[inline]
pub const fn sync_on_write(&self) -> bool {
self.opts.sync_on_write()
pub const fn sync(&self) -> bool {
self.opts.sync()
}

/// Sets the capacity of the WAL.
Expand Down Expand Up @@ -316,12 +316,12 @@ impl<C, S> Builder<C, S> {
/// ```rust
/// use orderwal::Builder;
///
/// let options = Builder::new().with_sync_on_write(false);
/// assert_eq!(options.sync_on_write(), false);
/// let options = Builder::new().with_sync(false);
/// assert_eq!(options.sync(), false);
/// ```
#[inline]
pub const fn with_sync_on_write(mut self, sync: bool) -> Self {
self.opts = self.opts.with_sync_on_write(sync);
pub const fn with_sync(mut self, sync: bool) -> Self {
self.opts = self.opts.with_sync(sync);
self
}

Expand Down
77 changes: 34 additions & 43 deletions src/entry.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use core::borrow::Borrow;

use among::Among;
use crossbeam_skiplist::set::Entry as SetEntry;
use dbutils::traits::{Type, TypeRef};
use rarena_allocator::either::Either;

use super::{
pointer::{GenericPointer, Pointer},
wal::r#type::{Type, TypeRef},
KeyBuilder, ValueBuilder,
};

Expand Down Expand Up @@ -263,42 +262,36 @@ impl<KB, VB, C> EntryWithBuilders<KB, VB, C> {

/// A wrapper around a generic type that can be used to construct a [`GenericEntry`].
#[repr(transparent)]
pub struct Generic<'a, T> {
data: Among<T, &'a T, &'a [u8]>,
pub struct Generic<'a, T: ?Sized> {
data: Either<&'a T, &'a [u8]>,
}

impl<T: Type> Generic<'_, T> {
impl<T: Type + ?Sized> Generic<'_, T> {
#[inline]
pub(crate) fn encoded_len(&self) -> usize {
match &self.data {
Among::Left(val) => val.encoded_len(),
Among::Middle(val) => val.encoded_len(),
Among::Right(val) => val.len(),
Either::Left(val) => val.encoded_len(),
Either::Right(val) => val.len(),
}
}

#[inline]
pub(crate) fn encode(&self, buf: &mut [u8]) -> Result<usize, T::Error> {
match &self.data {
Among::Left(val) => val.encode(buf),
Among::Middle(val) => val.encode(buf),
Among::Right(val) => {
Either::Left(val) => val.encode(buf),
Either::Right(val) => {
buf.copy_from_slice(val);
Ok(buf.len())
}
}
}
}

impl<'a, T> Generic<'a, T> {
impl<'a, T: ?Sized> Generic<'a, T> {
/// Returns the value contained in the generic.
#[inline]
pub const fn data(&self) -> Either<&T, &'a [u8]> {
match &self.data {
Among::Left(val) => Either::Left(val),
Among::Middle(val) => Either::Left(val),
Among::Right(val) => Either::Right(val),
}
self.data
}

/// Creates a new generic from bytes for querying or inserting into the [`GenericOrderWal`](crate::swmr::GenericOrderWal).
Expand All @@ -308,43 +301,29 @@ impl<'a, T> Generic<'a, T> {
#[inline]
pub const unsafe fn from_slice(slice: &'a [u8]) -> Self {
Self {
data: Among::Right(slice),
data: Either::Right(slice),
}
}

#[inline]
pub(crate) fn into_among(self) -> Among<T, &'a T, &'a [u8]> {
self.data
}
}

impl<'a, T> From<&'a T> for Generic<'a, T> {
impl<'a, T: ?Sized> From<&'a T> for Generic<'a, T> {
#[inline]
fn from(value: &'a T) -> Self {
Self {
data: Among::Middle(value),
}
}
}

impl<T> From<T> for Generic<'_, T> {
#[inline]
fn from(value: T) -> Self {
Self {
data: Among::Left(value),
data: Either::Left(value),
}
}
}

/// An entry in the [`GenericOrderWal`](crate::swmr::GenericOrderWal).
pub struct GenericEntry<'a, K, V> {
pub struct GenericEntry<'a, K: ?Sized, V: ?Sized> {
pub(crate) key: Generic<'a, K>,
pub(crate) value: Generic<'a, V>,
pub(crate) pointer: Option<GenericPointer<K, V>>,
pub(crate) meta: BatchEncodedEntryMeta,
}

impl<'a, K, V> GenericEntry<'a, K, V> {
impl<'a, K: ?Sized, V: ?Sized> GenericEntry<'a, K, V> {
/// Creates a new entry.
#[inline]
pub fn new(key: impl Into<Generic<'a, K>>, value: impl Into<Generic<'a, V>>) -> Self {
Expand Down Expand Up @@ -377,15 +356,19 @@ impl<'a, K, V> GenericEntry<'a, K, V> {

/// The reference to an entry in the [`GenericOrderWal`](crate::swmr::GenericOrderWal).
#[repr(transparent)]
pub struct GenericEntryRef<'a, K, V> {
pub struct GenericEntryRef<'a, K, V>
where
K: ?Sized,
V: ?Sized,
{
ent: SetEntry<'a, GenericPointer<K, V>>,
}

impl<'a, K, V> core::fmt::Debug for GenericEntryRef<'a, K, V>
where
K: Type,
K: Type + ?Sized,
K::Ref<'a>: core::fmt::Debug,
V: Type,
V: Type + ?Sized,
V::Ref<'a>: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Expand All @@ -396,7 +379,11 @@ where
}
}

impl<K, V> Clone for GenericEntryRef<'_, K, V> {
impl<K, V> Clone for GenericEntryRef<'_, K, V>
where
K: ?Sized,
V: ?Sized,
{
#[inline]
fn clone(&self) -> Self {
Self {
Expand All @@ -405,7 +392,11 @@ impl<K, V> Clone for GenericEntryRef<'_, K, V> {
}
}

impl<'a, K, V> GenericEntryRef<'a, K, V> {
impl<'a, K, V> GenericEntryRef<'a, K, V>
where
K: ?Sized,
V: ?Sized,
{
#[inline]
pub(super) fn new(ent: SetEntry<'a, GenericPointer<K, V>>) -> Self {
Self { ent }
Expand All @@ -414,8 +405,8 @@ impl<'a, K, V> GenericEntryRef<'a, K, V> {

impl<'a, K, V> GenericEntryRef<'a, K, V>
where
K: Type,
V: Type,
K: Type + ?Sized,
V: Type + ?Sized,
{
/// Returns the key of the entry.
#[inline]
Expand Down
18 changes: 9 additions & 9 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pub struct Options {
maximum_key_size: u32,
maximum_value_size: u32,
sync_on_write: bool,
sync: bool,
magic_version: u16,
cap: Option<u32>,
reserved: u32,
Expand Down Expand Up @@ -46,7 +46,7 @@ impl Options {
Self {
maximum_key_size: u16::MAX as u32,
maximum_value_size: u32::MAX,
sync_on_write: true,
sync: true,
magic_version: 0,
huge: None,
cap: None,
Expand Down Expand Up @@ -229,11 +229,11 @@ impl Options {
/// use orderwal::Options;
///
/// let options = Options::new();
/// assert_eq!(options.sync_on_write(), true);
/// assert_eq!(options.sync(), true);
/// ```
#[inline]
pub const fn sync_on_write(&self) -> bool {
self.sync_on_write
pub const fn sync(&self) -> bool {
self.sync
}

/// Sets the capacity of the WAL.
Expand Down Expand Up @@ -297,12 +297,12 @@ impl Options {
/// ```rust
/// use orderwal::Options;
///
/// let options = Options::new().with_sync_on_write(false);
/// assert_eq!(options.sync_on_write(), false);
/// let options = Options::new().with_sync(false);
/// assert_eq!(options.sync(), false);
/// ```
#[inline]
pub const fn with_sync_on_write(mut self, sync: bool) -> Self {
self.sync_on_write = sync;
pub const fn with_sync(mut self, sync: bool) -> Self {
self.sync = sync;
self
}

Expand Down
41 changes: 29 additions & 12 deletions src/pointer.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use core::{borrow::Borrow, cmp, marker::PhantomData, slice};

use dbutils::Comparator;

use super::wal::r#type::{KeyRef, Type};
use dbutils::{
traits::{KeyRef, Type},
Comparator,
};

#[doc(hidden)]
pub struct Pointer<C> {
Expand Down Expand Up @@ -94,7 +95,7 @@ impl<C> super::wal::sealed::Pointer for Pointer<C> {

#[doc(hidden)]
#[derive(Debug)]
pub struct GenericPointer<K, V> {
pub struct GenericPointer<K: ?Sized, V: ?Sized> {
/// The pointer to the start of the entry.
ptr: *const u8,
/// The length of the key.
Expand All @@ -104,7 +105,7 @@ pub struct GenericPointer<K, V> {
_m: PhantomData<(fn() -> K, fn() -> V)>,
}

impl<K, V> crate::wal::sealed::Pointer for GenericPointer<K, V> {
impl<K: ?Sized, V: ?Sized> crate::wal::sealed::Pointer for GenericPointer<K, V> {
type Comparator = ();

#[inline]
Expand All @@ -113,18 +114,19 @@ impl<K, V> crate::wal::sealed::Pointer for GenericPointer<K, V> {
}
}

impl<K: Type, V> PartialEq for GenericPointer<K, V> {
impl<K: Type + ?Sized, V: ?Sized> PartialEq for GenericPointer<K, V> {
fn eq(&self, other: &Self) -> bool {
self.as_key_slice() == other.as_key_slice()
}
}

impl<K: Type, V> Eq for GenericPointer<K, V> {}
impl<K: Type + ?Sized, V: ?Sized> Eq for GenericPointer<K, V> {}

impl<K, V> PartialOrd for GenericPointer<K, V>
where
K: Type + Ord,
K: Type + Ord + ?Sized,
for<'a> K::Ref<'a>: KeyRef<'a, K>,
V: ?Sized,
{
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
Expand All @@ -133,19 +135,34 @@ where

impl<K, V> Ord for GenericPointer<K, V>
where
K: Type + Ord,
K: Type + Ord + ?Sized,
for<'a> K::Ref<'a>: KeyRef<'a, K>,
V: ?Sized,
{
fn cmp(&self, other: &Self) -> cmp::Ordering {
// SAFETY: WALs guarantee that the self and other must be the same as the result returned by `<K as Type>::encode`.
unsafe { <K::Ref<'_> as KeyRef<K>>::compare_binary(self.as_key_slice(), other.as_key_slice()) }
}
}

unsafe impl<K, V> Send for GenericPointer<K, V> {}
unsafe impl<K, V> Sync for GenericPointer<K, V> {}
unsafe impl<K, V> Send for GenericPointer<K, V>
where
K: ?Sized,
V: ?Sized,
{
}
unsafe impl<K, V> Sync for GenericPointer<K, V>
where
K: ?Sized,
V: ?Sized,
{
}

impl<K, V> GenericPointer<K, V> {
impl<K, V> GenericPointer<K, V>
where
K: ?Sized,
V: ?Sized,
{
#[inline]
pub(crate) const fn new(key_len: usize, value_len: usize, ptr: *const u8) -> Self {
Self {
Expand Down
Loading
Loading