Clean up enum methods

next
Sayan Nandan 1 year ago
parent 9ceaa54abd
commit 9e9a7b9c9a
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -167,7 +167,7 @@ unsafe fn dc_op_str_add(dc: &Datacell, rhs: LitIR) -> (bool, Datacell) {
} }
static OPERATOR: [unsafe fn(&Datacell, LitIR) -> (bool, Datacell); { static OPERATOR: [unsafe fn(&Datacell, LitIR) -> (bool, Datacell); {
TagClass::max() * (AssignmentOperator::max() + 1) TagClass::MAX as usize * AssignmentOperator::VARIANTS
}] = [ }] = [
// bool // bool
dc_op_bool_ass, dc_op_bool_ass,
@ -212,7 +212,7 @@ static OPERATOR: [unsafe fn(&Datacell, LitIR) -> (bool, Datacell); {
#[inline(always)] #[inline(always)]
const fn opc(opr: TagClass, ope: AssignmentOperator) -> usize { const fn opc(opr: TagClass, ope: AssignmentOperator) -> usize {
(AssignmentOperator::count() * opr.word()) + ope.word() (AssignmentOperator::VARIANTS * opr.value_word()) + ope.value_word()
} }
#[cfg(test)] #[cfg(test)]

@ -345,7 +345,7 @@ impl Field {
// illegal states: (1) bad null (2) tags don't match // illegal states: (1) bad null (2) tags don't match
7 7
} else { } else {
dc.kind().word() dc.kind().value_word()
} }
} }
pub fn validate_data_fpath(&self, data: &Datacell) -> bool { pub fn validate_data_fpath(&self, data: &Datacell) -> bool {
@ -368,7 +368,7 @@ impl Field {
(TagClass::List, TagClass::List) if !layers.is_empty() => { (TagClass::List, TagClass::List) if !layers.is_empty() => {
let mut okay = unsafe { let mut okay = unsafe {
// UNSAFE(@ohsayan): we've verified this // UNSAFE(@ohsayan): we've verified this
LVERIFY[TagClass::List.word()](layer, data) LVERIFY[TagClass::List.value_word()](layer, data)
}; };
let list = unsafe { let list = unsafe {
// UNSAFE(@ohsayan): we verified tags // UNSAFE(@ohsayan): we verified tags
@ -385,7 +385,7 @@ impl Field {
(tag_a, tag_b) if tag_a == tag_b => { (tag_a, tag_b) if tag_a == tag_b => {
unsafe { unsafe {
// UNSAFE(@ohsayan): same tags; not-null for now so no extra handling required here // UNSAFE(@ohsayan): same tags; not-null for now so no extra handling required here
LVERIFY[tag_a.word()](layer, data) LVERIFY[tag_a.value_word()](layer, data)
} }
} }
_ => false, _ => false,
@ -452,7 +452,7 @@ impl Layer {
} }
#[inline(always)] #[inline(always)]
fn compute_index(&self, dc: &Datacell) -> usize { fn compute_index(&self, dc: &Datacell) -> usize {
self.tag.tag_class().word() * (dc.is_null() as usize) self.tag.tag_class().value_word() * (dc.is_null() as usize)
} }
const fn new(tag: FullTag) -> Self { const fn new(tag: FullTag) -> Self {
Self { tag } Self { tag }
@ -523,7 +523,7 @@ unsafe fn lverify_bool(_: Layer, _: &Datacell) -> bool {
unsafe fn lverify_uint(l: Layer, d: &Datacell) -> bool { unsafe fn lverify_uint(l: Layer, d: &Datacell) -> bool {
layertrace("uint"); layertrace("uint");
const MX: [u64; 4] = [u8::MAX as _, u16::MAX as _, u32::MAX as _, u64::MAX]; const MX: [u64; 4] = [u8::MAX as _, u16::MAX as _, u32::MAX as _, u64::MAX];
d.read_uint() <= MX[l.tag.tag_selector().word() - 1] d.read_uint() <= MX[l.tag.tag_selector().value_word() - 1]
} }
unsafe fn lverify_sint(l: Layer, d: &Datacell) -> bool { unsafe fn lverify_sint(l: Layer, d: &Datacell) -> bool {
layertrace("sint"); layertrace("sint");
@ -533,13 +533,13 @@ unsafe fn lverify_sint(l: Layer, d: &Datacell) -> bool {
(i32::MIN as _, i32::MAX as _), (i32::MIN as _, i32::MAX as _),
(i64::MIN, i64::MAX), (i64::MIN, i64::MAX),
]; ];
let (mn, mx) = MN_MX[l.tag.tag_selector().word() - 5]; let (mn, mx) = MN_MX[l.tag.tag_selector().value_word() - 5];
(d.read_sint() >= mn) & (d.read_sint() <= mx) (d.read_sint() >= mn) & (d.read_sint() <= mx)
} }
unsafe fn lverify_float(l: Layer, d: &Datacell) -> bool { unsafe fn lverify_float(l: Layer, d: &Datacell) -> bool {
layertrace("float"); layertrace("float");
const MN_MX: [(f64, f64); 2] = [(f32::MIN as _, f32::MAX as _), (f64::MIN, f64::MAX)]; const MN_MX: [(f64, f64); 2] = [(f32::MIN as _, f32::MAX as _), (f64::MIN, f64::MAX)];
let (mn, mx) = MN_MX[l.tag.tag_selector().word() - 9]; let (mn, mx) = MN_MX[l.tag.tag_selector().value_word() - 9];
(d.read_float() >= mn) & (d.read_float() <= mx) (d.read_float() >= mn) & (d.read_float() <= mx)
} }
unsafe fn lverify_bin(_: Layer, _: &Datacell) -> bool { unsafe fn lverify_bin(_: Layer, _: &Datacell) -> bool {

@ -24,9 +24,7 @@
* *
*/ */
use std::mem; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, sky_macros::EnumMethods)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
#[repr(u8)] #[repr(u8)]
pub enum AssignmentOperator { pub enum AssignmentOperator {
Assign = 0, Assign = 0,
@ -35,21 +33,3 @@ pub enum AssignmentOperator {
MulAssign = 3, MulAssign = 3,
DivAssign = 4, DivAssign = 4,
} }
impl AssignmentOperator {
pub const fn disc(&self) -> u8 {
unsafe {
// UNSAFE(@ohsayan): just go back to school already; dscr
mem::transmute(*self)
}
}
pub const fn max() -> usize {
Self::DivAssign.disc() as _
}
pub const fn word(&self) -> usize {
self.disc() as _
}
pub const fn count() -> usize {
5
}
}

@ -25,7 +25,7 @@
*/ */
#[repr(u8)] #[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord, sky_macros::EnumMethods)]
pub enum TagClass { pub enum TagClass {
Bool = 0, Bool = 0,
UnsignedInt = 1, UnsignedInt = 1,
@ -37,12 +37,8 @@ pub enum TagClass {
} }
impl TagClass { impl TagClass {
/// ☢WARNING☢: Don't forget offset
pub const fn max() -> usize {
Self::List.d() as _
}
pub const fn try_from_raw(v: u8) -> Option<Self> { pub const fn try_from_raw(v: u8) -> Option<Self> {
if v > Self::List.d() { if v > Self::MAX {
return None; return None;
} }
Some(unsafe { Self::from_raw(v) }) Some(unsafe { Self::from_raw(v) })
@ -59,12 +55,12 @@ impl TagClass {
TagUnique::Bin, TagUnique::Bin,
TagUnique::Str, TagUnique::Str,
TagUnique::Illegal, TagUnique::Illegal,
][self.d() as usize] ][self.value_word()]
} }
} }
#[repr(u8)] #[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord, sky_macros::EnumMethods)]
pub enum TagSelector { pub enum TagSelector {
Bool = 0, Bool = 0,
UInt8 = 1, UInt8 = 1,
@ -83,9 +79,6 @@ pub enum TagSelector {
} }
impl TagSelector { impl TagSelector {
pub const fn max_dscr() -> u8 {
Self::List.d()
}
pub const fn into_full(self) -> FullTag { pub const fn into_full(self) -> FullTag {
FullTag::new(self.tag_class(), self, self.tag_unique()) FullTag::new(self.tag_class(), self, self.tag_unique())
} }
@ -108,7 +101,7 @@ impl TagSelector {
TagUnique::Bin, TagUnique::Bin,
TagUnique::Str, TagUnique::Str,
TagUnique::Illegal, TagUnique::Illegal,
][self.d() as usize] ][self.value_word()]
} }
pub const fn tag_class(&self) -> TagClass { pub const fn tag_class(&self) -> TagClass {
[ [
@ -126,12 +119,12 @@ impl TagSelector {
TagClass::Bin, TagClass::Bin,
TagClass::Str, TagClass::Str,
TagClass::List, TagClass::List,
][self.d() as usize] ][self.value_word()]
} }
} }
#[repr(u8)] #[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord, sky_macros::EnumMethods)]
pub enum TagUnique { pub enum TagUnique {
UnsignedInt = 0, UnsignedInt = 0,
SignedInt = 1, SignedInt = 1,
@ -142,7 +135,7 @@ pub enum TagUnique {
impl TagUnique { impl TagUnique {
pub const fn is_unique(&self) -> bool { pub const fn is_unique(&self) -> bool {
self.d() != Self::Illegal.d() self.value_u8() != Self::Illegal.value_u8()
} }
pub const fn try_from_raw(raw: u8) -> Option<Self> { pub const fn try_from_raw(raw: u8) -> Option<Self> {
if raw > 3 { if raw > 3 {
@ -152,12 +145,6 @@ impl TagUnique {
} }
} }
macro_rules! d {
($($ty:ty),*) => {$(impl $ty { pub const fn d(&self) -> u8 {unsafe{::core::mem::transmute(*self)}} pub const fn word(&self) -> usize {Self::d(self) as usize} } )*}
}
d!(TagClass, TagSelector, TagUnique);
pub trait DataTag { pub trait DataTag {
const BOOL: Self; const BOOL: Self;
const UINT: Self; const UINT: Self;

@ -0,0 +1,85 @@
/*
* Created on Fri Sep 15 2023
*
* This file is a part of Skytable
* Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source
* NoSQL database written by Sayan Nandan ("the Author") with the
* vision to provide flexibility in data modelling without compromising
* on performance, queryability or scalability.
*
* Copyright (c) 2023, Sayan Nandan <ohsayan@outlook.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use core::{ptr, slice};
#[derive(Debug)]
pub struct BufferedScanner<'a> {
d: &'a [u8],
i: usize,
}
impl<'a> BufferedScanner<'a> {
pub const fn new(d: &'a [u8]) -> Self {
Self { d, i: 0 }
}
pub const fn remaining(&self) -> usize {
self.d.len() - self.i
}
pub const fn consumed(&self) -> usize {
self.i
}
pub const fn cursor(&self) -> usize {
self.i
}
pub(crate) fn has_left(&self, sizeof: usize) -> bool {
self.remaining() >= sizeof
}
unsafe fn _cursor(&self) -> *const u8 {
self.d.as_ptr().add(self.i)
}
pub fn eof(&self) -> bool {
self.remaining() == 0
}
unsafe fn _incr(&mut self, by: usize) {
self.i += by;
}
pub fn current(&self) -> &[u8] {
&self.d[self.i..]
}
}
impl<'a> BufferedScanner<'a> {
pub unsafe fn next_u64_le(&mut self) -> u64 {
u64::from_le_bytes(self.next_chunk())
}
pub unsafe fn next_chunk<const N: usize>(&mut self) -> [u8; N] {
let mut b = [0u8; N];
ptr::copy_nonoverlapping(self._cursor(), b.as_mut_ptr(), N);
self._incr(N);
b
}
pub unsafe fn next_chunk_variable(&mut self, size: usize) -> &[u8] {
let r = slice::from_raw_parts(self._cursor(), size);
self._incr(size);
r
}
pub unsafe fn next_byte(&mut self) -> u8 {
let r = *self._cursor();
self._incr(1);
r
}
}

@ -25,6 +25,7 @@
*/ */
mod astr; mod astr;
mod buf;
mod ll; mod ll;
mod stackop; mod stackop;
mod uarray; mod uarray;
@ -36,6 +37,7 @@ mod tests;
// re-exports // re-exports
pub use { pub use {
astr::AStr, astr::AStr,
buf::BufferedScanner,
ll::CachePadded, ll::CachePadded,
stackop::ByteStack, stackop::ByteStack,
uarray::UArray, uarray::UArray,

@ -156,7 +156,7 @@ impl<Fs: RawFSInterface> DataBatchPersistDriver<Fs> {
col_cnt: usize, col_cnt: usize,
) -> Result<(), SDSSError> { ) -> Result<(), SDSSError> {
self.f self.f
.unfsynced_write(&[MARKER_ACTUAL_BATCH_EVENT, pk_tag.d()])?; .unfsynced_write(&[MARKER_ACTUAL_BATCH_EVENT, pk_tag.value_u8()])?;
let observed_len_bytes = observed_len.u64_bytes_le(); let observed_len_bytes = observed_len.u64_bytes_le();
self.f.unfsynced_write(&observed_len_bytes)?; self.f.unfsynced_write(&observed_len_bytes)?;
self.f self.f

@ -39,7 +39,8 @@ use {
DictGeneric, DictGeneric,
}, },
idx::{IndexBaseSpec, IndexSTSeqCns, STIndex, STIndexSeq}, idx::{IndexBaseSpec, IndexSTSeqCns, STIndex, STIndexSeq},
storage::v1::{inf, rw::BufferedScanner, SDSSError, SDSSResult}, mem::BufferedScanner,
storage::v1::{inf, SDSSError, SDSSResult},
}, },
util::{copy_slice_to_array as memcpy, EndianQW}, util::{copy_slice_to_array as memcpy, EndianQW},
}, },

@ -41,7 +41,8 @@ use {
tag::{DataTag, TagClass}, tag::{DataTag, TagClass},
}, },
idx::{AsKey, AsValue}, idx::{AsKey, AsValue},
storage::v1::{rw::BufferedScanner, SDSSError, SDSSResult}, mem::BufferedScanner,
storage::v1::{SDSSError, SDSSResult},
}, },
std::mem, std::mem,
}; };
@ -64,13 +65,12 @@ pub enum PersistTypeDscr {
} }
impl PersistTypeDscr { impl PersistTypeDscr {
pub(super) const MAX: Self = Self::Dict;
/// translates the tag class definition into the dscr definition /// translates the tag class definition into the dscr definition
pub const fn translate_from_class(class: TagClass) -> Self { pub const fn translate_from_class(class: TagClass) -> Self {
unsafe { Self::from_raw(class.d() + 1) } unsafe { Self::from_raw(class.value_u8() + 1) }
} }
pub const fn try_from_raw(v: u8) -> Option<Self> { pub const fn try_from_raw(v: u8) -> Option<Self> {
if v > Self::MAX.value_u8() { if v > Self::MAX {
None None
} else { } else {
unsafe { Some(Self::from_raw(v)) } unsafe { Some(Self::from_raw(v)) }
@ -262,7 +262,7 @@ pub mod enc {
pub mod dec { pub mod dec {
use { use {
super::{map, PersistMapSpec, PersistObject}, super::{map, PersistMapSpec, PersistObject},
crate::engine::storage::v1::{rw::BufferedScanner, SDSSResult}, crate::engine::{mem::BufferedScanner, storage::v1::SDSSResult},
}; };
// obj // obj
pub fn dec_full<Obj: PersistObject>(data: &[u8]) -> SDSSResult<Obj::OutputType> { pub fn dec_full<Obj: PersistObject>(data: &[u8]) -> SDSSResult<Obj::OutputType> {
@ -288,7 +288,10 @@ pub mod dec {
<map::PersistMapImpl<PM> as PersistObject>::default_full_dec(scanner) <map::PersistMapImpl<PM> as PersistObject>::default_full_dec(scanner)
} }
pub mod utils { pub mod utils {
use crate::engine::storage::v1::{BufferedScanner, SDSSError, SDSSResult}; use crate::engine::{
mem::BufferedScanner,
storage::v1::{SDSSError, SDSSResult},
};
pub unsafe fn decode_string(s: &mut BufferedScanner, len: usize) -> SDSSResult<String> { pub unsafe fn decode_string(s: &mut BufferedScanner, len: usize) -> SDSSResult<String> {
String::from_utf8(s.next_chunk_variable(len).to_owned()) String::from_utf8(s.next_chunk_variable(len).to_owned())
.map_err(|_| SDSSError::InternalDecodeStructureCorruptedPayload) .map_err(|_| SDSSError::InternalDecodeStructureCorruptedPayload)

@ -24,23 +24,22 @@
* *
*/ */
use crate::engine::{core::model::delta::IRModel, data::DictGeneric};
use { use {
super::{PersistTypeDscr, PersistObject, VecU8}, super::{PersistObject, PersistTypeDscr, VecU8},
crate::{ crate::{
engine::{ engine::{
core::{ core::{
model::{Field, Layer, Model}, model::{delta::IRModel, Field, Layer, Model},
space::{Space, SpaceMeta}, space::{Space, SpaceMeta},
}, },
data::{ data::{
cell::Datacell, cell::Datacell,
tag::{DataTag, TagClass, TagSelector}, tag::{DataTag, TagClass, TagSelector},
uuid::Uuid, uuid::Uuid,
DictGeneric,
}, },
mem::VInline, mem::{BufferedScanner, VInline},
storage::v1::{inf, rw::BufferedScanner, SDSSError, SDSSResult}, storage::v1::{inf, SDSSError, SDSSResult},
}, },
util::EndianQW, util::EndianQW,
}, },
@ -111,7 +110,7 @@ impl<'a> PersistObject for LayerRef<'a> {
true true
} }
fn meta_enc(buf: &mut VecU8, LayerRef(layer): Self::InputType) { fn meta_enc(buf: &mut VecU8, LayerRef(layer): Self::InputType) {
buf.extend(layer.tag().tag_selector().d().u64_bytes_le()); buf.extend(layer.tag().tag_selector().value_qword().to_le_bytes());
buf.extend(0u64.to_le_bytes()); buf.extend(0u64.to_le_bytes());
} }
unsafe fn meta_dec(scanner: &mut BufferedScanner) -> SDSSResult<Self::Metadata> { unsafe fn meta_dec(scanner: &mut BufferedScanner) -> SDSSResult<Self::Metadata> {
@ -119,7 +118,7 @@ impl<'a> PersistObject for LayerRef<'a> {
} }
fn obj_enc(_: &mut VecU8, _: Self::InputType) {} fn obj_enc(_: &mut VecU8, _: Self::InputType) {}
unsafe fn obj_dec(_: &mut BufferedScanner, md: Self::Metadata) -> SDSSResult<Self::OutputType> { unsafe fn obj_dec(_: &mut BufferedScanner, md: Self::Metadata) -> SDSSResult<Self::OutputType> {
if (md.type_selector > TagSelector::List.d() as u64) | (md.prop_set_arity != 0) { if (md.type_selector > TagSelector::List.value_qword()) | (md.prop_set_arity != 0) {
return Err(SDSSError::InternalDecodeStructureCorruptedPayload); return Err(SDSSError::InternalDecodeStructureCorruptedPayload);
} }
Ok(Layer::new_empty_props( Ok(Layer::new_empty_props(
@ -253,7 +252,7 @@ impl<'a> PersistObject for ModelLayoutRef<'a> {
fn meta_enc(buf: &mut VecU8, ModelLayoutRef(v, irm): Self::InputType) { fn meta_enc(buf: &mut VecU8, ModelLayoutRef(v, irm): Self::InputType) {
buf.extend(v.get_uuid().to_le_bytes()); buf.extend(v.get_uuid().to_le_bytes());
buf.extend(v.p_key().len().u64_bytes_le()); buf.extend(v.p_key().len().u64_bytes_le());
buf.extend(v.p_tag().tag_selector().d().u64_bytes_le()); buf.extend(v.p_tag().tag_selector().value_qword().to_le_bytes());
buf.extend(irm.fields().len().u64_bytes_le()); buf.extend(irm.fields().len().u64_bytes_le());
} }
unsafe fn meta_dec(scanner: &mut BufferedScanner) -> SDSSResult<Self::Metadata> { unsafe fn meta_dec(scanner: &mut BufferedScanner) -> SDSSResult<Self::Metadata> {
@ -281,7 +280,7 @@ impl<'a> PersistObject for ModelLayoutRef<'a> {
scanner, scanner,
super::map::MapIndexSizeMD(md.field_c as usize), super::map::MapIndexSizeMD(md.field_c as usize),
)?; )?;
let ptag = if md.p_key_tag > TagSelector::max_dscr() as u64 { let ptag = if md.p_key_tag > TagSelector::MAX as u64 {
return Err(SDSSError::InternalDecodeStructureCorruptedPayload); return Err(SDSSError::InternalDecodeStructureCorruptedPayload);
} else { } else {
TagSelector::from_raw(md.p_key_tag as u8) TagSelector::from_raw(md.p_key_tag as u8)

@ -43,7 +43,7 @@ mod tests;
pub use { pub use {
journal::{open_journal, JournalAdapter, JournalWriter}, journal::{open_journal, JournalAdapter, JournalWriter},
memfs::NullFS, memfs::NullFS,
rw::{BufferedScanner, LocalFS, RawFSInterface, SDSSFileIO}, rw::{LocalFS, RawFSInterface, SDSSFileIO},
}; };
pub mod data_batch { pub mod data_batch {
pub use super::batch_jrnl::{DataBatchPersistDriver, DataBatchRestoreDriver}; pub use super::batch_jrnl::{DataBatchPersistDriver, DataBatchRestoreDriver};

@ -40,7 +40,6 @@ use {
std::{ std::{
fs::{self, File}, fs::{self, File},
io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write}, io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write},
ptr, slice,
}, },
}; };
@ -439,60 +438,3 @@ impl<Fs: RawFSInterface> SDSSFileIO<Fs> {
self.read_to_buffer(&mut r).map(|_| r[0]) self.read_to_buffer(&mut r).map(|_| r[0])
} }
} }
pub struct BufferedScanner<'a> {
d: &'a [u8],
i: usize,
}
impl<'a> BufferedScanner<'a> {
pub const fn new(d: &'a [u8]) -> Self {
Self { d, i: 0 }
}
pub const fn remaining(&self) -> usize {
self.d.len() - self.i
}
pub const fn consumed(&self) -> usize {
self.i
}
pub const fn cursor(&self) -> usize {
self.i
}
pub(crate) fn has_left(&self, sizeof: usize) -> bool {
self.remaining() >= sizeof
}
unsafe fn _cursor(&self) -> *const u8 {
self.d.as_ptr().add(self.i)
}
pub fn eof(&self) -> bool {
self.remaining() == 0
}
unsafe fn _incr(&mut self, by: usize) {
self.i += by;
}
pub fn current(&self) -> &[u8] {
&self.d[self.i..]
}
}
impl<'a> BufferedScanner<'a> {
pub unsafe fn next_u64_le(&mut self) -> u64 {
u64::from_le_bytes(self.next_chunk())
}
pub unsafe fn next_chunk<const N: usize>(&mut self) -> [u8; N] {
let mut b = [0u8; N];
ptr::copy_nonoverlapping(self._cursor(), b.as_mut_ptr(), N);
self._incr(N);
b
}
pub unsafe fn next_chunk_variable(&mut self, size: usize) -> &[u8] {
let r = slice::from_raw_parts(self._cursor(), size);
self._incr(size);
r
}
pub unsafe fn next_byte(&mut self) -> u8 {
let r = *self._cursor();
self._incr(1);
r
}
}

@ -32,11 +32,11 @@ use {
engine::{ engine::{
core::{space::Space, GlobalNS}, core::{space::Space, GlobalNS},
data::uuid::Uuid, data::uuid::Uuid,
mem::BufferedScanner,
storage::v1::{ storage::v1::{
self, header_meta, self, header_meta,
inf::{self, PersistObject}, inf::{self, PersistObject},
BufferedScanner, JournalAdapter, JournalWriter, LocalFS, RawFSInterface, JournalAdapter, JournalWriter, LocalFS, RawFSInterface, SDSSResult,
SDSSResult,
}, },
}, },
util::EndianQW, util::EndianQW,

@ -35,10 +35,11 @@ use {
}, },
data::uuid::Uuid, data::uuid::Uuid,
idx::{IndexST, IndexSTSeqCns, STIndex, STIndexSeq}, idx::{IndexST, IndexSTSeqCns, STIndex, STIndexSeq},
mem::BufferedScanner,
ql::lex::Ident, ql::lex::Ident,
storage::v1::{ storage::v1::{
inf::{self, map, obj, PersistObject}, inf::{self, map, obj, PersistObject},
BufferedScanner, SDSSError, SDSSResult, SDSSError, SDSSResult,
}, },
txn::TransactionError, txn::TransactionError,
}, },

@ -31,9 +31,10 @@ use {
core::{space::Space, GlobalNS}, core::{space::Space, GlobalNS},
data::DictGeneric, data::DictGeneric,
idx::STIndex, idx::STIndex,
mem::BufferedScanner,
storage::v1::{ storage::v1::{
inf::{self, map, obj, PersistObject}, inf::{self, map, obj, PersistObject},
BufferedScanner, SDSSResult, SDSSResult,
}, },
txn::{TransactionError, TransactionResult}, txn::{TransactionError, TransactionResult},
}, },

@ -243,14 +243,17 @@ pub fn derive_value_methods(input: TokenStream) -> TokenStream {
} }
} }
let repr_type = repr_type.expect("Must have repr(u8) or repr(u16) etc."); let repr_type = repr_type.expect("Must have repr(u8) or repr(u16) etc.");
let mut dscr_expressions = vec![];
// Ensure all variants have explicit discriminants // Ensure all variants have explicit discriminants
if let Data::Enum(data) = &ast.data { if let Data::Enum(data) = &ast.data {
for variant in &data.variants { for variant in &data.variants {
match &variant.fields { match &variant.fields {
Fields::Unit => { Fields::Unit => {
if variant.discriminant.as_ref().is_none() { let (_, dscr_expr) = variant
panic!("All enum variants must have explicit discriminants"); .discriminant
} .as_ref()
.expect("All enum variants must have explicit discriminants");
dscr_expressions.push(dscr_expr.clone());
} }
_ => panic!("All enum variants must be unit variants"), _ => panic!("All enum variants must be unit variants"),
} }
@ -259,6 +262,12 @@ pub fn derive_value_methods(input: TokenStream) -> TokenStream {
panic!("This derive macro only works on enums"); panic!("This derive macro only works on enums");
} }
let value_expressions = quote! {
[#(#dscr_expressions),*]
};
let variant_len = dscr_expressions.len();
let repr_type_ident = syn::Ident::new(&repr_type, proc_macro2::Span::call_site()); let repr_type_ident = syn::Ident::new(&repr_type, proc_macro2::Span::call_site());
let repr_type_ident_func = syn::Ident::new( let repr_type_ident_func = syn::Ident::new(
&format!("value_{repr_type}"), &format!("value_{repr_type}"),
@ -267,9 +276,23 @@ pub fn derive_value_methods(input: TokenStream) -> TokenStream {
let gen = quote! { let gen = quote! {
impl #enum_name { impl #enum_name {
pub const MAX: #repr_type_ident = Self::max_value();
pub const VARIANTS: usize = #variant_len;
pub const fn #repr_type_ident_func(&self) -> #repr_type_ident { unsafe { core::mem::transmute(*self) } } pub const fn #repr_type_ident_func(&self) -> #repr_type_ident { unsafe { core::mem::transmute(*self) } }
pub const fn value_word(&self) -> usize { self.#repr_type_ident_func() as usize } pub const fn value_word(&self) -> usize { self.#repr_type_ident_func() as usize }
pub const fn value_qword(&self) -> u64 { self.#repr_type_ident_func() as u64 } pub const fn value_qword(&self) -> u64 { self.#repr_type_ident_func() as u64 }
pub const fn max_value() -> #repr_type_ident {
let values = #value_expressions;
let mut i = 1;
let mut max = values[0];
while i < values.len() {
if values[i] > max {
max = values[i];
}
i = i + 1;
}
max
}
} }
}; };
gen.into() gen.into()

Loading…
Cancel
Save