Skip to content

Commit

Permalink
0.4.0 (#10)
Browse files Browse the repository at this point in the history
* Add `K: ?Sized` and `V: ?Sized` for generic wal

* Use `flush_header_and_range` instead of `flush_range`
  • Loading branch information
al8n authored Sep 30, 2024
1 parent 9ee3375 commit b129d2f
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 208 deletions.
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

0 comments on commit b129d2f

Please sign in to comment.