diff --git a/src/data/compare.rs b/src/data/compare.rs index dd16f62e..905fce32 100644 --- a/src/data/compare.rs +++ b/src/data/compare.rs @@ -2,31 +2,19 @@ use crate::data::encode::{ decode_ae_key, decode_attr_key_by_id, decode_attr_key_by_kw, decode_ea_key, decode_unique_attr_val, decode_vae_key, decode_value_from_key, StorageTag, }; -use crate::data::id::{EntityId, TxId}; -use lazy_static::lazy_static; use std::cmp::Ordering; -// #[no_mangle] -// extern "C" fn rusty_cmp(a: &cozorocks::Slice, b: &cozorocks::Slice) -> cozorocks::c_int { -// let a = cozorocks::convert_slice_back(a); -// let b = cozorocks::convert_slice_back(b); -// cozorocks::c_int(match compare_key(a, b) { -// Ordering::Greater => 1, -// Ordering::Equal => 0, -// Ordering::Less => -1, -// }) -// } +#[allow(improper_ctypes_definitions)] +#[no_mangle] +extern "C" fn rusty_cmp(a: &[u8], b: &[u8]) -> i8 { + match compare_key(a, b) { + Ordering::Greater => 1, + Ordering::Equal => 0, + Ordering::Less => -1, + } +} pub(crate) const DB_KEY_PREFIX_LEN: usize = 4; -// -// lazy_static! { -// pub(crate) static ref RUSTY_COMPARATOR: cozorocks::UniquePtr = { -// unsafe { -// let f_ptr = rusty_cmp as *const cozorocks::c_void; -// cozorocks::new_rust_comparator("cozo_rusty_cmp_v1", false, f_ptr) -// } -// }; -// } macro_rules! return_if_resolved { ($o:expr) => { @@ -140,9 +128,7 @@ fn compare_key_attr_by_kw(a: &[u8], b: &[u8]) -> Ordering { #[inline] fn compare_key_tx(a: &[u8], b: &[u8]) -> Ordering { - let a_t = TxId::from_bytes(a); - let b_t = TxId::from_bytes(b); - a_t.cmp(&b_t).reverse() + a.cmp(b).reverse() } #[inline] diff --git a/src/data/encode.rs b/src/data/encode.rs index 12e68dbc..3adbc04a 100644 --- a/src/data/encode.rs +++ b/src/data/encode.rs @@ -6,7 +6,7 @@ use anyhow::Result; use rmp_serde::Serializer; use serde::Serialize; use smallvec::SmallVec; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; #[repr(u8)] #[derive(Ord, PartialOrd, Eq, PartialEq, Debug)] @@ -30,6 +30,60 @@ pub enum StorageTagError { UnexpectedValue(u8), } +pub(crate) struct Encoded { + inner: SmallVec<[u8; N]>, +} + +impl Encoded { + pub(crate) fn encoded_entity_amend_tx(&mut self, tx: TxId) { + let tx_bytes = tx.0.to_be_bytes(); + #[allow(clippy::needless_range_loop)] + for i in 1..8 { + self.inner[VEC_SIZE_12 + i] = tx_bytes[i]; + } + } + pub(crate) fn encoded_entity_amend_tx_to_last(&mut self) { + self.encoded_entity_amend_tx(TxId(u64::MAX)) + } + pub(crate) fn encoded_entity_amend_tx_to_first(&mut self) { + self.encoded_entity_amend_tx(TxId(0)) + } + + pub(crate) fn encoded_attr_amend_tx(&mut self, tx: TxId) { + let tx_bytes = tx.0.to_be_bytes(); + #[allow(clippy::needless_range_loop)] + for i in 1..8 { + self.inner[VEC_SIZE_4 + i] = tx_bytes[i]; + } + } + pub(crate) fn encoded_attr_amend_tx_to_last(&mut self) { + self.encoded_attr_amend_tx(TxId(u64::MAX)) + } + pub(crate) fn encoded_attr_amend_tx_to_first(&mut self) { + self.encoded_attr_amend_tx(TxId(0)) + } +} + +impl Deref for Encoded { + type Target = SmallVec<[u8; N]>; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for Encoded { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl From> for Encoded { + fn from(inner: SmallVec<[u8; N]>) -> Self { + Self { inner } + } +} + impl TryFrom for StorageTag { type Error = StorageTagError; fn try_from(value: u8) -> std::result::Result { @@ -49,11 +103,18 @@ impl TryFrom for StorageTag { } } +const LARGE_VEC_SIZE: usize = 60; +const VEC_SIZE_28: usize = 28; +const VEC_SIZE_20: usize = 20; +const VEC_SIZE_12: usize = 12; +const VEC_SIZE_8: usize = 8; +const VEC_SIZE_4: usize = 4; + #[inline] -pub(crate) fn encode_value(val: Value) -> impl Deref { - let mut ret = SmallVec::<[u8; 60]>::new(); +pub(crate) fn encode_value(val: Value) -> Encoded { + let mut ret = SmallVec::<[u8; LARGE_VEC_SIZE]>::new(); val.serialize(&mut Serializer::new(&mut ret)).unwrap(); - ret + ret.into() } #[inline] @@ -63,7 +124,7 @@ pub(crate) fn decode_value(src: &[u8]) -> Result { #[inline] pub(crate) fn decode_value_from_key(src: &[u8]) -> Result { - Ok(rmp_serde::from_slice(&src[20..])?) + Ok(rmp_serde::from_slice(&src[VEC_SIZE_20..])?) } /// eid: 8 bytes (incl. tag) @@ -77,8 +138,8 @@ pub(crate) fn encode_eav_key( val: Value, tx: TxId, op: StoreOp, -) -> impl Deref { - let mut ret = SmallVec::<[u8; 60]>::new(); +) -> Encoded { + let mut ret = SmallVec::<[u8; LARGE_VEC_SIZE]>::new(); ret.extend(eid.0.to_be_bytes()); ret[0] = StorageTag::TripleEntityAttrValue as u8; @@ -86,20 +147,20 @@ pub(crate) fn encode_eav_key( ret.extend(aid.0.to_be_bytes()); ret.extend(tx.0.to_be_bytes()); - ret[12] = op as u8; - debug_assert_eq!(ret.len(), 20); + ret[VEC_SIZE_12] = op as u8; + debug_assert_eq!(ret.len(), VEC_SIZE_20); val.serialize(&mut Serializer::new(&mut ret)).unwrap(); - ret + ret.into() } #[inline] pub(crate) fn decode_ea_key(src: &[u8]) -> Result<(EntityId, AttrId, TxId, StoreOp)> { - let eid = EntityId::from_bytes(&src[0..8]); - let aid = AttrId::from_bytes(&src[8..12]); - let tx = TxId::from_bytes(&src[12..20]); - let op = src[12].try_into()?; + let eid = EntityId::from_bytes(&src[0..VEC_SIZE_8]); + let aid = AttrId::from_bytes(&src[VEC_SIZE_8..VEC_SIZE_12]); + let tx = TxId::from_bytes(&src[VEC_SIZE_12..VEC_SIZE_20]); + let op = src[VEC_SIZE_12].try_into()?; Ok((eid, aid, tx, op)) } @@ -115,28 +176,28 @@ pub(crate) fn encode_aev_key( val: Value, tx: TxId, op: StoreOp, -) -> impl Deref { - let mut ret = SmallVec::<[u8; 60]>::new(); +) -> Encoded { + let mut ret = SmallVec::<[u8; LARGE_VEC_SIZE]>::new(); ret.extend(aid.0.to_be_bytes()); ret[0] = StorageTag::TripleAttrEntityValue as u8; ret.extend(eid.0.to_be_bytes()); ret.extend(tx.0.to_be_bytes()); - ret[12] = op as u8; - debug_assert_eq!(ret.len(), 20); + ret[VEC_SIZE_12] = op as u8; + debug_assert_eq!(ret.len(), VEC_SIZE_20); val.serialize(&mut Serializer::new(&mut ret)).unwrap(); - ret + ret.into() } #[inline] pub(crate) fn decode_ae_key(src: &[u8]) -> Result<(AttrId, EntityId, TxId, StoreOp)> { - let aid = AttrId::from_bytes(&src[0..4]); - let eid = EntityId::from_bytes(&src[4..12]); - let tx = TxId::from_bytes(&src[12..20]); - let op = src[12].try_into()?; + let aid = AttrId::from_bytes(&src[0..VEC_SIZE_4]); + let eid = EntityId::from_bytes(&src[VEC_SIZE_4..VEC_SIZE_12]); + let tx = TxId::from_bytes(&src[VEC_SIZE_12..VEC_SIZE_20]); + let op = src[VEC_SIZE_12].try_into()?; Ok((aid, eid, tx, op)) } @@ -152,20 +213,20 @@ pub(crate) fn encode_ave_key( eid: EntityId, tx: TxId, op: StoreOp, -) -> impl Deref { - let mut ret = SmallVec::<[u8; 60]>::new(); +) -> Encoded { + let mut ret = SmallVec::<[u8; LARGE_VEC_SIZE]>::new(); ret.extend(aid.0.to_be_bytes()); ret[0] = StorageTag::TripleAttrValueEntity as u8; ret.extend(eid.0.to_be_bytes()); ret.extend(tx.0.to_be_bytes()); - ret[12] = op as u8; - debug_assert_eq!(ret.len(), 20); + ret[VEC_SIZE_12] = op as u8; + debug_assert_eq!(ret.len(), VEC_SIZE_20); val.serialize(&mut Serializer::new(&mut ret)).unwrap(); - ret + ret.into() } /// val: 8 bytes (incl. tag) @@ -179,29 +240,29 @@ pub(crate) fn encode_vae_key( eid: EntityId, tx: TxId, op: StoreOp, -) -> impl Deref { - let mut ret = SmallVec::<[u8; 60]>::new(); +) -> Encoded { + let mut ret = SmallVec::<[u8; LARGE_VEC_SIZE]>::new(); ret.extend(val.0.to_be_bytes()); ret[0] = StorageTag::TripleAttrValueEntity as u8; ret.extend(aid.0.to_be_bytes()); ret.extend(tx.0.to_be_bytes()); - ret[12] = op as u8; - debug_assert_eq!(ret.len(), 20); + ret[VEC_SIZE_12] = op as u8; + debug_assert_eq!(ret.len(), VEC_SIZE_20); ret.extend(eid.0.to_be_bytes()); - debug_assert_eq!(ret.len(), 28); + debug_assert_eq!(ret.len(), VEC_SIZE_28); - ret + ret.into() } #[inline] pub(crate) fn decode_vae_key(src: &[u8]) -> Result<(EntityId, AttrId, EntityId, TxId, StoreOp)> { - let vid = EntityId::from_bytes(&src[0..8]); - let aid = AttrId::from_bytes(&src[8..12]); - let tx = TxId::from_bytes(&src[12..20]); - let eid = EntityId::from_bytes(&src[20..28]); - let op = src[12].try_into()?; + let vid = EntityId::from_bytes(&src[0..VEC_SIZE_8]); + let aid = AttrId::from_bytes(&src[VEC_SIZE_8..VEC_SIZE_12]); + let tx = TxId::from_bytes(&src[VEC_SIZE_12..VEC_SIZE_20]); + let eid = EntityId::from_bytes(&src[VEC_SIZE_20..VEC_SIZE_28]); + let op = src[VEC_SIZE_12].try_into()?; Ok((vid, aid, eid, tx, op)) } @@ -209,21 +270,21 @@ pub(crate) fn decode_vae_key(src: &[u8]) -> Result<(EntityId, AttrId, EntityId, /// aid: 4 bytes (incl. tag) /// tx: 8 bytes (incl. op) #[inline] -pub(crate) fn encode_attr_by_id(aid: AttrId, tx: TxId, op: StoreOp) -> impl Deref { - let mut ret = SmallVec::<[u8; 12]>::new(); +pub(crate) fn encode_attr_by_id(aid: AttrId, tx: TxId, op: StoreOp) -> Encoded { + let mut ret = SmallVec::<[u8; VEC_SIZE_12]>::new(); ret.extend(aid.0.to_be_bytes()); ret[0] = StorageTag::AttrById as u8; ret.extend(tx.0.to_be_bytes()); - ret[4] = op as u8; - debug_assert_eq!(ret.len(), 12); - ret + ret[VEC_SIZE_4] = op as u8; + debug_assert_eq!(ret.len(), VEC_SIZE_12); + ret.into() } #[inline] pub(crate) fn decode_attr_key_by_id(src: &[u8]) -> Result<(AttrId, TxId, StoreOp)> { - let aid = AttrId::from_bytes(&src[0..4]); - let tx = TxId::from_bytes(&src[4..12]); - let op = src[4].try_into()?; + let aid = AttrId::from_bytes(&src[0..VEC_SIZE_4]); + let tx = TxId::from_bytes(&src[VEC_SIZE_4..VEC_SIZE_12]); + let op = src[VEC_SIZE_4].try_into()?; Ok((aid, tx, op)) } @@ -231,73 +292,69 @@ pub(crate) fn decode_attr_key_by_id(src: &[u8]) -> Result<(AttrId, TxId, StoreOp /// tx: 8 bytes (incl. op) /// attr as kw: variable (segmented by \0) #[inline] -pub(crate) fn encode_attr_by_kw( - attr_name: Keyword, - tx: TxId, - op: StoreOp, -) -> impl Deref { - let mut ret = SmallVec::<[u8; 12]>::new(); +pub(crate) fn encode_attr_by_kw(attr_name: Keyword, tx: TxId, op: StoreOp) -> Encoded { + let mut ret = SmallVec::<[u8; VEC_SIZE_12]>::new(); ret.push(StorageTag::AttrByKeyword as u8); let ns_bytes = attr_name.ns.as_bytes(); ret.push(ns_bytes.get(0).cloned().unwrap_or(0)); ret.push(ns_bytes.get(1).cloned().unwrap_or(0)); ret.push(ns_bytes.get(2).cloned().unwrap_or(0)); ret.extend(tx.0.to_be_bytes()); - ret[4] = op as u8; + ret[VEC_SIZE_4] = op as u8; ret.extend_from_slice(ns_bytes); ret.push(b'/'); ret.extend_from_slice(attr_name.ident.as_bytes()); - ret + ret.into() } #[inline] pub(crate) fn decode_attr_key_by_kw(src: &[u8]) -> Result<(Keyword, TxId, StoreOp)> { - let tx = TxId::from_bytes(&src[4..12]); - let op = src[4].try_into()?; - let kw = Keyword::try_from(&src[12..])?; + let tx = TxId::from_bytes(&src[VEC_SIZE_4..VEC_SIZE_12]); + let op = src[VEC_SIZE_4].try_into()?; + let kw = Keyword::try_from(&src[VEC_SIZE_12..])?; Ok((kw, tx, op)) } /// tx: 8 bytes (incl. tag) #[inline] -pub(crate) fn encode_tx(tx: TxId) -> impl Deref { - let mut ret = SmallVec::<[u8; 8]>::new(); +pub(crate) fn encode_tx(tx: TxId) -> Encoded { + let mut ret = SmallVec::<[u8; VEC_SIZE_8]>::new(); ret.extend(tx.0.to_be_bytes()); ret[0] = StorageTag::Tx as u8; - ret + ret.into() } #[inline] -pub(crate) fn encode_unique_entity_placeholder(eid: EntityId) -> impl Deref { - let mut ret = SmallVec::<[u8; 8]>::new(); +pub(crate) fn encode_unique_entity_placeholder(eid: EntityId) -> Encoded { + let mut ret = SmallVec::<[u8; VEC_SIZE_8]>::new(); ret.extend(eid.0.to_be_bytes()); ret[0] = StorageTag::UniqueEntity as u8; - ret + ret.into() } #[inline] -pub(crate) fn encode_unique_attr_val(aid: AttrId, val: Value) -> impl Deref { - let mut ret = SmallVec::<[u8; 60]>::new(); +pub(crate) fn encode_unique_attr_val(aid: AttrId, val: Value) -> Encoded { + let mut ret = SmallVec::<[u8; LARGE_VEC_SIZE]>::new(); ret.extend(aid.0.to_be_bytes()); ret[0] = StorageTag::UniqueAttrValue as u8; val.serialize(&mut Serializer::new(&mut ret)).unwrap(); - ret + ret.into() } #[inline] pub(crate) fn decode_unique_attr_val(src: &[u8]) -> Result<(AttrId, Value)> { - let a_id = AttrId::from_bytes(&src[..4]); - let val = rmp_serde::from_slice(&src[4..])?; + let a_id = AttrId::from_bytes(&src[..VEC_SIZE_4]); + let val = rmp_serde::from_slice(&src[VEC_SIZE_4..])?; Ok((a_id, val)) } #[inline] -pub(crate) fn encode_unique_attr_by_id(aid: AttrId) -> impl Deref { - let mut ret = SmallVec::<[u8; 4]>::new(); +pub(crate) fn encode_unique_attr_by_id(aid: AttrId) -> Encoded { + let mut ret = SmallVec::<[u8; VEC_SIZE_4]>::new(); ret.extend(aid.0.to_be_bytes()); ret[0] = StorageTag::UniqueAttrById as u8; - debug_assert_eq!(ret.len(), 4); - ret + debug_assert_eq!(ret.len(), VEC_SIZE_4); + ret.into() } pub(crate) fn decode_unique_attr_by_id(src: &[u8]) -> Result { @@ -305,13 +362,13 @@ pub(crate) fn decode_unique_attr_by_id(src: &[u8]) -> Result { } #[inline] -pub(crate) fn encode_unique_attr_by_kw(kw: Keyword) -> impl Deref { - let mut ret = SmallVec::<[u8; 60]>::new(); +pub(crate) fn encode_unique_attr_by_kw(kw: Keyword) -> Encoded { + let mut ret = SmallVec::<[u8; LARGE_VEC_SIZE]>::new(); ret.push(StorageTag::UniqueAttrByKeyword as u8); ret.extend_from_slice(kw.ns.as_bytes()); ret.push(b'/'); ret.extend_from_slice(kw.ident.as_bytes()); - ret + ret.into() } #[inline] diff --git a/src/runtime/instance.rs b/src/runtime/instance.rs index 8acda540..283a0f35 100644 --- a/src/runtime/instance.rs +++ b/src/runtime/instance.rs @@ -5,12 +5,12 @@ // use std::sync::{Arc, Mutex}; // // pub struct DbInstance { -// pub destroy_on_close: bool, +//x pub destroy_on_close: bool, // db: SharedPtr, -// db_opts: UniquePtr, -// tdb_opts: Option>, -// odb_opts: Option>, -// path: String, +//x db_opts: UniquePtr, +//x tdb_opts: Option>, +//x odb_opts: Option>, +//x path: String, // last_attr_id: Arc, // last_ent_id: Arc, // last_tx_id: Arc,