1use core::ops::{Add, AddAssign, Sub, SubAssign};
2
3use arbitrary_int::{u27, u5, Number, TryNewError};
4pub use dbutils::buffer::*;
5
6const MAX_U5: u8 = (1 << 5) - 1;
7const MAX_U27: u32 = (1 << 27) - 1;
8
9pub type Version = u64;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub struct Header {
15 meta_offset: u32,
16 head_node_offset: u32,
17 tail_node_offset: u32,
18}
19
20impl Header {
21 #[inline]
23 pub const fn new(meta_offset: u32, head_node_offset: u32, tail_node_offset: u32) -> Self {
24 Self {
25 meta_offset,
26 head_node_offset,
27 tail_node_offset,
28 }
29 }
30
31 #[inline]
33 pub const fn meta_offset(&self) -> u32 {
34 self.meta_offset
35 }
36
37 #[inline]
39 pub const fn head_node_offset(&self) -> u32 {
40 self.head_node_offset
41 }
42
43 #[inline]
45 pub const fn tail_node_offset(&self) -> u32 {
46 self.tail_node_offset
47 }
48}
49
50pub(crate) mod internal {
51 use core::{ptr::NonNull, sync::atomic::Ordering};
52
53 use crate::ref_counter::RefCounter;
54
55 #[derive(Debug)]
57 pub struct ValuePointer {
58 pub(crate) value_offset: u32,
59 pub(crate) value_len: u32,
60 }
61
62 impl Clone for ValuePointer {
63 fn clone(&self) -> Self {
64 *self
65 }
66 }
67
68 impl Copy for ValuePointer {}
69
70 impl ValuePointer {
71 #[inline]
72 pub(crate) const fn new(value_offset: u32, value_len: u32) -> Self {
73 Self {
74 value_offset,
75 value_len,
76 }
77 }
78 }
79
80 bitflags::bitflags! {
81 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
82 pub struct Flags: u8 {
83 const MULTIPLE_VERSION = 0b0000_0001;
85 }
86 }
87
88 #[doc(hidden)]
90 pub(crate) struct RefMeta<M, R: RefCounter> {
91 unify: bool,
92 meta: NonNull<M>,
93 ref_counter: R,
94 }
95
96 impl<M: core::fmt::Debug, R: RefCounter> core::fmt::Debug for RefMeta<M, R> {
97 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
98 f.debug_struct("RefMeta")
99 .field("meta", unsafe { &*self.meta.as_ptr() })
100 .field("refs", &self.ref_counter.load(Ordering::Acquire))
101 .field("unify", &self.unify)
102 .finish()
103 }
104 }
105
106 impl<M, R: RefCounter> core::ops::Deref for RefMeta<M, R> {
107 type Target = M;
108
109 #[inline]
110 fn deref(&self) -> &Self::Target {
111 unsafe { self.meta.as_ref() }
112 }
113 }
114
115 impl<M, R: RefCounter> core::ops::DerefMut for RefMeta<M, R> {
116 #[inline]
117 fn deref_mut(&mut self) -> &mut Self::Target {
118 unsafe { self.meta.as_mut() }
119 }
120 }
121
122 impl<M, R> RefMeta<M, R>
123 where
124 R: RefCounter,
125 {
126 #[inline]
127 pub(crate) fn new(meta: NonNull<M>, unify: bool) -> Self {
128 Self {
129 meta,
130 ref_counter: R::new(),
131 unify,
132 }
133 }
134
135 #[inline]
136 pub(crate) fn refs(&self) -> usize {
137 self.ref_counter.load(Ordering::Acquire)
138 }
139 }
140
141 impl<M, R: RefCounter> Clone for RefMeta<M, R> {
142 #[inline]
143 fn clone(&self) -> Self {
144 let old_size = self.ref_counter.fetch_add(Ordering::Release);
145 if old_size > usize::MAX >> 1 {
146 dbutils::abort();
147 }
148
149 Self {
153 meta: self.meta,
154 ref_counter: self.ref_counter.clone(),
155 unify: self.unify,
156 }
157 }
158 }
159
160 impl<M, R: RefCounter> Drop for RefMeta<M, R> {
161 fn drop(&mut self) {
162 if self.ref_counter.fetch_sub(Ordering::Release) != 1 {
163 return;
164 }
165
166 if self.unify {
167 return;
168 }
169
170 unsafe {
171 self.ref_counter.load(Ordering::Acquire);
192 let _ = std::boxed::Box::from_raw(self.meta.as_ptr());
194 }
195 }
196 }
197}
198
199macro_rules! impl_eq_and_ord {
200 ($name:ident($inner:ident < $upper:ident) -> [$($target:ident),+ $(,)?]) => {
201 $(
202 paste::paste! {
203 impl PartialEq<$target> for $name {
204 #[inline]
205 fn eq(&self, other: &$target) -> bool {
206 let val: $upper = self.0.into();
207 val.eq(&(*other as $upper))
208 }
209 }
210
211 impl PartialOrd<$target> for $name {
212 #[inline]
213 fn partial_cmp(&self, other: &$target) -> Option<core::cmp::Ordering> {
214 let val: $upper = self.0.into();
215 val.partial_cmp(&(*other as $upper))
216 }
217 }
218 }
219 )*
220 };
221}
222
223macro_rules! impl_signed_eq_and_ord {
224 ($name:ident($inner:ident < $upper:ident) -> [$($target:ident),+ $(,)?]) => {
225 $(
226 paste::paste! {
227 impl PartialEq<$target> for $name {
228 #[inline]
229 fn eq(&self, other: &$target) -> bool {
230 let val: $upper = self.0.into();
231 (val as i64).eq(&(*other as i64))
232 }
233 }
234
235 impl PartialOrd<$target> for $name {
236 #[inline]
237 fn partial_cmp(&self, other: &$target) -> Option<core::cmp::Ordering> {
238 let val: $upper = self.0.into();
239 (val as i64).partial_cmp(&(*other as i64))
240 }
241 }
242
243 impl PartialEq<$name> for $target {
244 #[inline]
245 fn eq(&self, other: &$name) -> bool {
246 let val: $upper = other.0.into();
247 (*self as i64).eq(&(val as i64))
248 }
249 }
250
251 impl PartialOrd<$name> for $target {
252 #[inline]
253 fn partial_cmp(&self, other: &$name) -> Option<core::cmp::Ordering> {
254 let val: $upper = other.0.into();
255 (*self as i64).partial_cmp(&(val as i64))
256 }
257 }
258 }
259 )*
260 };
261}
262
263macro_rules! impl_ops_for_ux_wrapper {
264 ($name:ident($inner:ident < $upper:ident) -> [$($target:ident),+ $(,)?]) => {
265 $(
266 paste::paste! {
267 impl Add<$target> for $name {
268 type Output = Self;
269
270 fn add(self, rhs: $target) -> Self::Output {
271 let res = rhs as $upper + $upper::from(self.0);
272
273 if res > [<MAX_ $inner:upper>] {
274 panic!("attempt to add with overflow");
275 }
276
277 Self($inner::new(res))
278 }
279 }
280
281 impl AddAssign<$target> for $name {
282 fn add_assign(&mut self, rhs: $target) {
283 let res = rhs as $upper + $upper::from(self.0);
284
285 if res > [<MAX_ $inner:upper>] {
286 panic!("attempt to add with overflow");
287 }
288
289 self.0 = $inner::new(res);
290 }
291 }
292
293 impl Sub<$target> for $name {
294 type Output = Self;
295
296 fn sub(self, rhs: $target) -> Self::Output {
297 let res = rhs as $upper - $upper::from(self.0);
298
299 if res > [<MAX_ $inner:upper>] {
300 panic!("attempt to substract with overflow");
301 }
302
303 Self($inner::new(res))
304 }
305 }
306
307 impl SubAssign<$target> for $name {
308 fn sub_assign(&mut self, rhs: $target) {
309 let res = rhs as $upper - $upper::from(self.0);
310
311 if res > [<MAX_ $inner:upper>] {
312 panic!("attempt to substract with overflow");
313 }
314
315 self.0 = $inner::new(res);
316 }
317 }
318 }
319 )*
320 };
321}
322
323macro_rules! impl_try_from_for_ux_wrapper {
324 ($name:ident($inner:ident < $upper:ident) -> [$($target:ident),+ $(,)?]) => {
325 $(
326 paste::paste! {
327 impl TryFrom<$target> for $name {
328 type Error = TryNewError;
329
330 #[inline]
331 fn try_from(value: $target) -> Result<Self, Self::Error> {
332 $inner::try_new(value as $upper).map(Self)
333 }
334 }
335
336 impl $name {
337 #[doc = "Try to create a" $name " from the given `" $target "`"]
338 #[inline]
339 pub fn [< try_from_ $target >](val: $target) -> Result<Self, TryNewError> {
340 $inner::try_new(val as $upper).map(Self)
341 }
342
343 #[doc = " Creates a new " $name " from the given `" $target "`."]
344 #[doc = "- If the given value is greater than `" $inner "::MAX`."]
347 #[inline]
348 pub const fn [< from_ $target _unchecked>](val: $target) -> Self {
349 Self($inner::new(val as $upper))
350 }
351 }
352 }
353 )*
354 };
355}
356
357macro_rules! impl_from_for_ux_wrapper {
358 ($name:ident($inner:ident < $upper:ident) -> [$($target:ident),+ $(,)?]) => {
359 $(
360 paste::paste! {
361 impl From<$target> for $name {
362 #[inline]
363 fn from(version: $target) -> Self {
364 Self($inner::from(version))
365 }
366 }
367
368 impl $name {
369 #[doc = "Creates a new " $name " from the given `" $target "`."]
370 #[inline]
371 pub const fn [< from_ $target>](version: $target) -> Self {
372 Self($inner::new(version as $upper))
373 }
374 }
375 }
376 )*
377 };
378}
379
380macro_rules! impl_into_for_ux_wrapper {
381 ($name:ident($inner:ident < $upper:ident) -> [$($target:ident),+ $(,)?]) => {
382 $(
383 paste::paste! {
384 impl From<$name> for $target {
385 #[inline]
386 fn from(version: $name) -> Self {
387 version.[< to_ $target>]()
388 }
389 }
390
391 impl $name {
392 #[doc = "Converts the " $name " to a `" $target "`."]
393 #[inline]
394 pub fn [< to_ $target>](&self) -> $target {
395 let val: $upper = self.0.into();
396 val as $target
397 }
398 }
399 }
400 )*
401 };
402}
403
404macro_rules! ux_wrapper {
405 (
406 $(
407 $([$meta:meta])*
408 $name:ident($inner:ident < $upper:ident) {
409 min: $min:expr,
410 default: $default:expr,
411 $(bits: $bits:expr,)?
412 $(ord: [$($ord_target:ident),* $(,)?],)?
413 $(signed_ord: [$($signed_ord_target:ident),* $(,)?],)?
414 $(ops: [$($ops_target:ident),* $(,)?],)?
415 $(try_from: [$($try_from_target:ident),* $(,)?],)?
416 $(from: [$($from_target:ident),* $(,)?],)?
417 $(into: [$($into_target:ident),* $(,)?],)?
418 }
419 ),+ $(,)?
420 ) => {
421 $(
422 $(#[$meta])*
423 #[derive(
424 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
425 )]
426 pub struct $name($inner);
427
428 impl core::fmt::Display for $name {
429 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
430 write!(f, "{}", self.0)
431 }
432 }
433
434 paste::paste! {
435 impl $name {
436 #[doc = "The maximum value of the " $name "."]
437 pub const MAX: Self = Self($inner::MAX);
438
439 #[doc = "The minimum value of the " $name "."]
440 pub const MIN: Self = Self($inner::new($min));
441
442 #[doc = "Creates a new " $name " with the default value."]
443 #[inline]
444 pub const fn new() -> Self {
445 Self($inner::new($default))
446 }
447
448 #[doc = "Creates a new " $name " with the given value."]
449 #[doc = ""]
450 #[doc = "## Panics"]
451 #[doc = "If the given value is greater than `" $inner "::MAX`."]
452 #[inline]
453 pub const fn with(val: $upper) -> Self {
454 Self($inner::new(val))
455 }
456
457 #[inline]
459 pub fn checked_add(self, rhs: Self) -> Option<Self> {
460 self.0.checked_add(rhs.0).map(Self)
461 }
462
463 #[inline]
465 pub fn checked_sub(self, rhs: Self) -> Option<Self> {
466 self.0.checked_sub(rhs.0).and_then(|val| {
467 if val < $inner::new($min) {
468 None
469 } else {
470 Some(Self(val))
471 }
472 })
473 }
474
475 #[inline]
477 pub fn wrapping_add(self, rhs: Self) -> Self {
478 Self(self.0.wrapping_add(rhs.0).max($inner::new($min)))
479 }
480
481 #[inline]
483 pub fn wrapping_sub(self, rhs: Self) -> Self {
484 let val = self.0.wrapping_sub(rhs.0);
485 if val < $inner::MIN {
486 Self::MAX
487 } else {
488 Self(val)
489 }
490 }
491
492 $(
493 #[inline]
495 pub const fn from_be_bytes(bytes: [u8; { $bits >> 3 }]) -> Self {
496 Self(UInt::<$upper, $bits>::from_be_bytes(bytes))
497 }
498
499 #[inline]
501 pub const fn from_le_bytes(bytes: [u8; { $bits >> 3 }]) -> Self {
502 Self(UInt::<$upper, $bits>::from_le_bytes(bytes))
503 }
504
505 #[inline]
507 pub const fn to_be_bytes(self) -> [u8; { $bits >> 3 }] {
508 self.0.to_be_bytes()
509 }
510
511 #[inline]
513 pub const fn to_le_bytes(self) -> [u8; { $bits >> 3 }] {
514 self.0.to_le_bytes()
515 }
516 )?
517 }
518 }
519
520 impl Default for $name {
521 #[inline]
522 fn default() -> Self {
523 Self($inner::new($default))
524 }
525 }
526
527 $(
528 impl From<[u8; { $bits >> 3 }]> for $name {
529 #[inline]
530 fn from(bytes: [u8; { $bits >> 3 }]) -> Self {
531 Self($inner::from_be_bytes(bytes))
532 }
533 }
534
535 impl From<$name> for [u8; { $bits >> 3 }] {
536 #[inline]
537 fn from(value: $name) -> Self {
538 value.to_be_bytes()
539 }
540 }
541 )?
542
543 impl From<$inner> for $name {
544 #[inline]
545 fn from(val: $inner) -> Self {
546 Self(val)
547 }
548 }
549
550 impl From<$name> for $inner {
551 #[inline]
552 fn from(value: $name) -> Self {
553 value.0
554 }
555 }
556
557 impl Add for $name {
558 type Output = Self;
559
560 #[inline]
561 fn add(self, rhs: Self) -> Self::Output {
562 Self(self.0.checked_add(rhs.0).expect("attempt to add with overflow"))
563 }
564 }
565
566 impl AddAssign for $name {
567 #[inline]
568 fn add_assign(&mut self, rhs: Self) {
569 self.0 = self.0.checked_add(rhs.0).expect("attempt to add with overflow");
570 }
571 }
572
573 impl Sub for $name {
574 type Output = Self;
575
576 fn sub(self, rhs: Self) -> Self::Output {
577 let val = self.0.checked_sub(rhs.0).expect("attempt to subtract with overflow");
578 if val < $inner::MIN {
579 panic!("attempt to subtract with overflow");
580 }
581
582 Self(val)
583 }
584 }
585
586 impl SubAssign for $name {
587 fn sub_assign(&mut self, rhs: Self) {
588 let val = self.0.checked_sub(rhs.0).expect("attempt to subtract with overflow");
589 if val < $inner::MIN {
590 panic!("attempt to subtract with overflow");
591 }
592 self.0 = val;
593 }
594 }
595
596 $(impl_eq_and_ord!($name($inner < $upper) -> [$($ord_target),*]);)?
597
598 $(impl_signed_eq_and_ord!($name($inner < $upper) -> [$($signed_ord_target),*]);)?
599
600 $(impl_ops_for_ux_wrapper!($name($inner < $upper) -> [$($ops_target),*]);)?
601
602 $(impl_try_from_for_ux_wrapper!($name($inner < $upper) -> [$($try_from_target),*]);)?
603
604 $(impl_from_for_ux_wrapper!($name($inner < $upper) -> [$($from_target),*]);)?
605
606 $(impl_into_for_ux_wrapper!($name($inner < $upper) -> [$($into_target),*]);)?
607 )*
608 };
609}
610
611ux_wrapper! {
612 [doc = "Height which is used to configure the maximum tower height of a skiplist, it is a 5-bit unsigned integer."]
613 Height(u5 < u8) {
614 min: 1,
615 default: 20,
616 ord: [u8, u16, u32, u64, usize],
617 signed_ord: [i8, i16, i32, i64, isize],
618 ops: [u8, u16, u32, u64, usize],
619 try_from: [u8, u16, u32, u64, usize],
620 into: [u8, u16, u32, u64, usize, u128],
621 },
622 [doc = "KeySize which is used to represent a length of a key stored in the skiplist, it is a 27-bit unsigned integer."]
623 KeySize(u27 < u32) {
624 min: 0,
625 default: u16::MAX as u32,
626 ord: [u8, u16, u32, u64, usize],
627 signed_ord: [i8, i16, i32, i64, isize],
628 ops: [u8, u16, u32, u64, usize],
629 try_from: [u32, usize],
630 from: [u8, u16],
631 into: [u32, u64, usize],
632 },
633}
634
635dbutils::builder!(
636 pub ValueBuilder;
638 pub KeyBuilder;
640);