Implement delete and add impls required for other dml queries

next
Sayan Nandan 1 year ago
parent 361acccc09
commit 2488053318
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -0,0 +1,46 @@
/*
* Created on Sat May 06 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 crate::engine::{
core::GlobalNS,
error::{DatabaseError, DatabaseResult},
ql::dml::del::DeleteStatement,
sync,
};
pub fn delete(gns: &GlobalNS, mut delete: DeleteStatement) -> DatabaseResult<()> {
gns.with_model(delete.entity(), |model| {
let g = sync::atm::cpin();
if model
.primary_index()
.remove(model.resolve_where(delete.clauses_mut())?, &g)
{
Ok(())
} else {
Err(DatabaseError::DmlEntryNotFound)
}
})
}

@ -27,7 +27,7 @@
use crate::engine::{
core::{
index::{DcFieldIndex, PrimaryIndexKey},
model::{Fields, ModelView},
model::{Fields, ModelData},
GlobalNS,
},
error::{DatabaseError, DatabaseResult},
@ -53,7 +53,7 @@ pub fn insert(gns: &GlobalNS, insert: InsertStatement) -> DatabaseResult<()> {
}
fn prepare_insert(
model: &ModelView,
model: &ModelData,
fields: &Fields,
insert: InsertData,
) -> DatabaseResult<(PrimaryIndexKey, DcFieldIndex)> {

@ -24,4 +24,31 @@
*
*/
mod del;
mod ins;
use crate::engine::{
core::model::ModelData,
data::{lit::LitIR, spec::DataspecMeta1D, tag::DataTag},
error::{DatabaseError, DatabaseResult},
ql::dml::WhereClause,
};
pub use {del::delete, ins::insert};
impl ModelData {
pub(self) fn resolve_where<'a>(
&self,
where_clause: &mut WhereClause<'a>,
) -> DatabaseResult<LitIR<'a>> {
match where_clause.clauses_mut().remove(self.p_key().as_bytes()) {
Some(clause)
if clause.filter_hint_none()
& (clause.rhs().kind().tag_unique() == self.p_tag().tag_unique()) =>
{
Ok(clause.rhs())
}
_ => Err(DatabaseError::DmlWhereClauseUnindexedExpr),
}
}
}

@ -207,6 +207,12 @@ impl<'a> Comparable<LitIR<'a>> for PrimaryIndexKey {
}
}
impl<'a> Comparable<PrimaryIndexKey> for LitIR<'a> {
fn cmp_eq(&self, key: &PrimaryIndexKey) -> bool {
key == self
}
}
impl fmt::Debug for PrimaryIndexKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut dbg_struct = f.debug_struct("PrimaryIndexKey");

@ -25,11 +25,11 @@
*/
mod key;
mod result_set;
mod row;
use crate::engine::{
core::model::DeltaVersion,
data::lit::LitIR,
idx::{IndexBaseSpec, IndexMTRaw, MTIndex},
sync::atm::Guard,
};
@ -60,4 +60,14 @@ impl PrimaryIndex {
self.data
.mt_insert(Row::new(key, data, delta_version, delta_version), g)
}
pub fn remove<'a>(&self, key: LitIR<'a>, g: &Guard) -> bool {
self.data.mt_delete(&key, g)
}
pub fn select<'a, 'v, 't: 'v, 'g: 't>(
&'t self,
key: LitIR<'a>,
g: &'g Guard,
) -> Option<&'v Row> {
self.data.mt_get_element(&key, g)
}
}

@ -1,67 +0,0 @@
/*
* Created on Tue May 02 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/>.
*
*/
/*
ISOLATION WARNING
----------------
I went with a rather suboptimal solution for v1. Once we have CC
we can do much better (at the cost of more complexity, ofcourse).
We'll roll that out in 0.8.1, I think.
FIXME(@ohsayan): Fix this
*/
use {
crate::engine::core::index::{DcFieldIndex, PrimaryIndexKey, Row, RowData},
parking_lot::RwLockReadGuard,
};
pub struct RowSnapshot<'a> {
key: &'a PrimaryIndexKey,
data: RwLockReadGuard<'a, RowData>,
}
impl<'a> RowSnapshot<'a> {
/// The moment you take a snapshot, you essentially "freeze" the row and prevent any changes from happening.
///
/// HOWEVER: This is very inefficient subject to isolation level scrutiny
#[inline(always)]
pub fn snapshot(row: &'a Row) -> RowSnapshot<'a> {
Self::new_manual(row.d_key(), row.d_data().read())
}
pub fn new_manual(key: &'a PrimaryIndexKey, data: RwLockReadGuard<'a, RowData>) -> Self {
Self { key, data }
}
#[inline(always)]
pub fn row_key(&self) -> &'a PrimaryIndexKey {
self.key
}
#[inline(always)]
pub fn row_data(&self) -> &DcFieldIndex {
&self.data.fields()
}
}

@ -25,7 +25,7 @@
*/
use {
super::{key::PrimaryIndexKey, result_set::RowSnapshot},
super::key::PrimaryIndexKey,
crate::{
engine::{
core::model::{DeltaKind, DeltaState, DeltaVersion},
@ -35,7 +35,7 @@ use {
},
util::compiler,
},
parking_lot::{RwLock, RwLockUpgradableReadGuard, RwLockWriteGuard},
parking_lot::{RwLock, RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard},
std::mem::ManuallyDrop,
};
@ -48,7 +48,7 @@ pub struct Row {
rc: RawRC<RwLock<RowData>>,
}
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct RowData {
fields: DcFieldIndex,
txn_revised: DeltaVersion,
@ -119,14 +119,14 @@ impl Row {
}
impl Row {
pub fn resolve_deltas_and_freeze<'g>(&'g self, delta_state: &DeltaState) -> RowSnapshot<'g> {
pub fn resolve_deltas_and_freeze<'g>(
&'g self,
delta_state: &DeltaState,
) -> RwLockReadGuard<'g, RowData> {
let rwl_ug = self.d_data().upgradable_read();
let current_version = delta_state.current_version();
if compiler::likely(current_version <= rwl_ug.txn_revised) {
return RowSnapshot::new_manual(
self.d_key(),
RwLockUpgradableReadGuard::downgrade(rwl_ug),
);
return RwLockUpgradableReadGuard::downgrade(rwl_ug);
}
// we have deltas to apply
let mut wl = RwLockUpgradableReadGuard::upgrade(rwl_ug);
@ -144,7 +144,7 @@ impl Row {
max_delta = *delta_id;
}
wl.txn_revised = max_delta;
return RowSnapshot::new_manual(self.d_key(), RwLockWriteGuard::downgrade(wl));
return RwLockWriteGuard::downgrade(wl);
}
}

@ -34,7 +34,7 @@ mod util;
mod tests;
// imports
use {
self::{model::ModelView, util::EntityLocator},
self::{model::ModelData, util::EntityLocator},
crate::engine::{
core::space::Space,
error::{DatabaseError, DatabaseResult},
@ -81,7 +81,7 @@ impl GlobalNS {
}
pub fn with_model<'a, T, E, F>(&self, entity: E, f: F) -> DatabaseResult<T>
where
F: FnOnce(&ModelView) -> DatabaseResult<T>,
F: FnOnce(&ModelData) -> DatabaseResult<T>,
E: 'a + EntityLocator<'a>,
{
entity

@ -25,7 +25,7 @@
*/
use {
super::{Field, IWModel, Layer, ModelView},
super::{Field, IWModel, Layer, ModelData},
crate::{
engine::{
core::GlobalNS,
@ -89,7 +89,7 @@ fn check_nullable(props: &mut HashMap<Box<str>, Option<DictEntryGeneric>>) -> Da
impl<'a> AlterPlan<'a> {
pub fn fdeltas(
mv: &ModelView,
mv: &ModelData,
wm: &IWModel,
AlterModel { model, kind }: AlterModel<'a>,
) -> DatabaseResult<AlterPlan<'a>> {
@ -246,7 +246,7 @@ impl<'a> AlterPlan<'a> {
}
}
impl ModelView {
impl ModelData {
pub fn exec_alter(gns: &GlobalNS, alter: AlterModel) -> DatabaseResult<()> {
gns.with_model(alter.model, |model| {
// make intent

@ -25,7 +25,7 @@
*/
use {
super::{Fields, ModelView},
super::{Fields, ModelData},
parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard},
std::{
collections::btree_map::{BTreeMap, Range},
@ -62,7 +62,7 @@ pub struct IRModelSMData<'a> {
}
impl<'a> IRModelSMData<'a> {
pub fn new(m: &'a ModelView) -> Self {
pub fn new(m: &'a ModelData) -> Self {
let rmodel = m.sync_matrix().v_priv_model_alter.read();
let mdata = m.sync_matrix().v_priv_data_new_or_revise.read();
Self {
@ -86,7 +86,7 @@ pub struct IRModel<'a> {
}
impl<'a> IRModel<'a> {
pub fn new(m: &'a ModelView) -> Self {
pub fn new(m: &'a ModelData) -> Self {
Self {
rmodel: m.sync_matrix().v_priv_model_alter.read(),
fields: unsafe {
@ -107,7 +107,7 @@ pub struct IWModel<'a> {
}
impl<'a> IWModel<'a> {
pub fn new(m: &'a ModelView) -> Self {
pub fn new(m: &'a ModelData) -> Self {
Self {
wmodel: m.sync_matrix().v_priv_model_alter.write(),
fields: unsafe {

@ -39,7 +39,7 @@ use {
tag::{DataTag, FullTag, TagClass, TagSelector},
},
error::{DatabaseError, DatabaseResult},
idx::{IndexSTSeqCns, STIndex, STIndexSeq},
idx::{IndexBaseSpec, IndexSTCOrdRC, STIndex, STIndexSeq},
mem::VInline,
ql::ddl::{
crt::CreateModel,
@ -51,10 +51,10 @@ use {
};
pub(in crate::engine::core) use self::delta::{DeltaKind, DeltaState, DeltaVersion};
pub(in crate::engine::core) type Fields = IndexSTSeqCns<Box<str>, Field>;
pub(in crate::engine::core) type Fields = IndexSTCOrdRC<Box<str>, Field>;
#[derive(Debug)]
pub struct ModelView {
pub struct ModelData {
p_key: Box<str>,
p_tag: FullTag,
fields: UnsafeCell<Fields>,
@ -64,7 +64,7 @@ pub struct ModelView {
}
#[cfg(test)]
impl PartialEq for ModelView {
impl PartialEq for ModelData {
fn eq(&self, m: &Self) -> bool {
let mdl1 = self.intent_read_model();
let mdl2 = m.intent_read_model();
@ -72,7 +72,7 @@ impl PartialEq for ModelView {
}
}
impl ModelView {
impl ModelData {
pub fn p_key(&self) -> &str {
&self.p_key
}
@ -122,7 +122,7 @@ impl ModelView {
}
}
impl ModelView {
impl ModelData {
pub fn process_create(
CreateModel {
model_name: _,
@ -133,7 +133,7 @@ impl ModelView {
let mut okay = props.is_empty() & !fields.is_empty();
// validate fields
let mut field_spec = fields.into_iter();
let mut fields = IndexSTSeqCns::with_capacity(field_spec.len());
let mut fields = Fields::idx_init_cap(field_spec.len());
let mut last_pk = None;
let mut pk_cnt = 0;
while (field_spec.len() != 0) & okay {
@ -170,7 +170,7 @@ impl ModelView {
}
}
impl ModelView {
impl ModelData {
pub fn exec_create(gns: &super::GlobalNS, stmt: CreateModel) -> DatabaseResult<()> {
let (space_name, model_name) = stmt.model_name.parse_entity()?;
let model = Self::process_create(stmt)?;

@ -26,7 +26,7 @@
use {
crate::engine::{
core::{model::ModelView, RWLIdx},
core::{model::ModelData, RWLIdx},
data::{md_dict, DictEntryGeneric, MetaDict},
error::{DatabaseError, DatabaseResult},
idx::{IndexST, STIndex},
@ -38,7 +38,7 @@ use {
#[derive(Debug)]
/// A space with the model namespace
pub struct Space {
mns: RWLIdx<Box<str>, ModelView>,
mns: RWLIdx<Box<str>, ModelData>,
pub(super) meta: SpaceMeta,
}
@ -74,7 +74,7 @@ impl ProcedureCreate {
}
impl Space {
pub fn _create_model(&self, name: &str, model: ModelView) -> DatabaseResult<()> {
pub fn _create_model(&self, name: &str, model: ModelData) -> DatabaseResult<()> {
if self
.mns
.write()
@ -85,13 +85,13 @@ impl Space {
Err(DatabaseError::DdlModelAlreadyExists)
}
}
pub(super) fn models(&self) -> &RWLIdx<Box<str>, ModelView> {
pub(super) fn models(&self) -> &RWLIdx<Box<str>, ModelData> {
&self.mns
}
pub fn with_model<T>(
&self,
model: &str,
f: impl FnOnce(&ModelView) -> DatabaseResult<T>,
f: impl FnOnce(&ModelData) -> DatabaseResult<T>,
) -> DatabaseResult<T> {
let mread = self.mns.read();
let Some(model) = mread.st_get(model) else {
@ -106,7 +106,7 @@ impl Space {
Space::new(Default::default(), SpaceMeta::with_env(into_dict! {}))
}
#[inline(always)]
pub fn new(mns: IndexST<Box<str>, ModelView>, meta: SpaceMeta) -> Self {
pub fn new(mns: IndexST<Box<str>, ModelData>, meta: SpaceMeta) -> Self {
Self {
mns: RWLIdx::new(mns),
meta,

@ -25,7 +25,5 @@
*/
// ddl
// space
mod space;
// model
mod model;
mod space;

@ -26,7 +26,7 @@
use crate::engine::{
core::{
model::{alt::AlterPlan, ModelView},
model::{alt::AlterPlan, ModelData},
tests::model::{create, exec_create},
GlobalNS,
},
@ -51,13 +51,13 @@ fn exec_plan(
new_space: bool,
model: &str,
plan: &str,
f: impl Fn(&ModelView),
f: impl Fn(&ModelData),
) -> DatabaseResult<()> {
exec_create(gns, model, new_space)?;
let tok = lex_insecure(plan.as_bytes()).unwrap();
let alter = parse_ast_node_full::<AlterModel>(&tok[2..]).unwrap();
let (_space, model_name) = alter.model.into_full().unwrap();
ModelView::exec_alter(gns, alter)?;
ModelData::exec_alter(gns, alter)?;
let gns_read = gns.spaces().read();
let space = gns_read.st_get("myspace").unwrap();
let model = space.models().read();

@ -29,16 +29,16 @@ mod crt;
mod layer;
use crate::engine::{
core::{model::ModelView, space::Space, GlobalNS},
core::{model::ModelData, space::Space, GlobalNS},
error::DatabaseResult,
idx::STIndex,
ql::{ast::parse_ast_node_full, ddl::crt::CreateModel, tests::lex_insecure},
};
fn create(s: &str) -> DatabaseResult<ModelView> {
fn create(s: &str) -> DatabaseResult<ModelData> {
let tok = lex_insecure(s.as_bytes()).unwrap();
let create_model = parse_ast_node_full(&tok[2..]).unwrap();
ModelView::process_create(create_model)
ModelData::process_create(create_model)
}
pub fn exec_create(
@ -51,7 +51,7 @@ pub fn exec_create(
if create_new_space {
gns.test_new_empty_space(&create_model.model_name.into_full().unwrap().0);
}
ModelView::exec_create(gns, create_model)
ModelData::exec_create(gns, create_model)
}
pub fn exec_create_new_space(gns: &GlobalNS, create_stmt: &str) -> DatabaseResult<()> {
@ -68,7 +68,7 @@ fn with_space(gns: &GlobalNS, space_name: &str, f: impl Fn(&Space)) {
f(space);
}
fn with_model(gns: &GlobalNS, space_id: &str, model_name: &str, f: impl Fn(&ModelView)) {
fn with_model(gns: &GlobalNS, space_id: &str, model_name: &str, f: impl Fn(&ModelData)) {
with_space(gns, space_id, |space| {
let space_rl = space.models().read();
let model = space_rl.st_get(model_name).unwrap();

@ -24,6 +24,8 @@
*
*/
use std::{marker::PhantomData, ops::Deref};
use {
crate::engine::{
self,
@ -236,7 +238,10 @@ impl<'a> From<LitIR<'a>> for Datacell {
let mut bin = ManuallyDrop::new(l.read_bin_uck().to_owned().into_boxed_slice());
Datacell::new(
CUTag::from(l.kind()),
DataRaw::word(WordIO::store((bin.len(), bin.as_mut_ptr()))),
DataRaw::word(DwordQN::dwordqn_store_qw_nw(
bin.len() as u64,
bin.as_mut_ptr() as usize,
)),
)
},
_ => unsafe {
@ -309,6 +314,13 @@ impl Datacell {
unsafe fn _new(tag: CUTag, data: DataRaw, init: bool) -> Self {
Self { init, tag, data }
}
pub unsafe fn upgrade_from(a: u64, b: usize, tag: CUTag) -> Self {
Self {
init: true,
tag,
data: DataRaw::word(DwordQN::dwordqn_store_qw_nw(a, b)),
}
}
unsafe fn new(tag: CUTag, data: DataRaw) -> Self {
Self::_new(tag, data, true)
}
@ -416,22 +428,19 @@ impl Clone for Datacell {
TagClass::Str | TagClass::Bin => unsafe {
// UNSAFE(@ohsayan): we have checked that the cell is initialized (uninit will not satisfy this class), and we have checked its class
let mut block = ManuallyDrop::new(self.read_bin().to_owned().into_boxed_slice());
DataRaw {
word: ManuallyDrop::new(WordIO::store((block.len(), block.as_mut_ptr()))),
}
DataRaw::word(DwordQN::dwordqn_store_qw_nw(
block.len() as u64,
block.as_mut_ptr() as usize,
))
},
TagClass::List => unsafe {
// UNSAFE(@ohsayan): we have checked that the cell is initialized (uninit will not satisfy this class), and we have checked its class
let data = self.read_list().read().iter().cloned().collect();
DataRaw {
rwl: ManuallyDrop::new(RwLock::new(data)),
}
DataRaw::rwl(RwLock::new(data))
},
_ => unsafe {
// UNSAFE(@ohsayan): we have checked that the cell is a stack class
DataRaw {
word: ManuallyDrop::new(mem::transmute_copy(&self.data.word)),
}
DataRaw::word(mem::transmute_copy(&self.data.word))
},
};
unsafe {
@ -440,3 +449,55 @@ impl Clone for Datacell {
}
}
}
#[derive(Debug)]
pub struct VirtualDatacell<'a> {
dc: ManuallyDrop<Datacell>,
_lt: PhantomData<LitIR<'a>>,
}
impl<'a> VirtualDatacell<'a> {
pub fn new(litir: LitIR<'a>) -> Self {
Self {
dc: ManuallyDrop::new(unsafe {
// UNSAFE(@ohsayan): this is a "reference" to a "virtual" aka fake DC. this just works because of memory layouts
Datacell::new(
CUTag::from(litir.kind()),
DataRaw::word(litir.data().dwordqn_promote()),
)
}),
_lt: PhantomData,
}
}
}
impl<'a> From<LitIR<'a>> for VirtualDatacell<'a> {
fn from(l: LitIR<'a>) -> Self {
Self::new(l)
}
}
impl<'a> Deref for VirtualDatacell<'a> {
type Target = Datacell;
fn deref(&self) -> &Self::Target {
&self.dc
}
}
impl<'a> PartialEq<Datacell> for VirtualDatacell<'a> {
fn eq(&self, other: &Datacell) -> bool {
self.dc.deref() == other
}
}
impl<'a> Clone for VirtualDatacell<'a> {
fn clone(&self) -> Self {
unsafe { core::mem::transmute_copy(self) }
}
}
#[test]
fn virtual_dc_damn() {
let dc = LitIR::Str("hello, world");
assert_eq!(VirtualDatacell::from(dc), Datacell::from("hello, world"));
}

@ -271,6 +271,7 @@ impl<'a, T: DataspecMethods1D> PartialEq<T> for LitIR<'a> {
<Self as DataspecMethods1D>::self_eq(self, other)
}
}
impl<'a> fmt::Debug for LitIR<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut f = f.debug_struct("LitIR");

@ -124,4 +124,8 @@ pub enum DatabaseError {
DmlConstraintViolationDuplicate,
/// data validation error
DmlDataValidationError,
/// The expression in a where clause is not indexed (in the way the expression expects it to be)
DmlWhereClauseUnindexedExpr,
/// The entry was not found
DmlEntryNotFound,
}

@ -41,6 +41,8 @@ use {
// re-exports
pub type IndexSTSeqCns<K, V> = stord::IndexSTSeqDll<K, V, stord::config::ConservativeConfig<K, V>>;
pub type IndexSTCOrdRC<K, V> =
stord::shared::OrderedIdxRC<K, V, stord::config::ConservativeConfig<K, V>>;
pub type IndexSTSeqLib<K, V> = stord::IndexSTSeqDll<K, V, stord::config::LiberalConfig<K, V>>;
pub type IndexMTRC<K, V> = mtchm::imp::ChmArc<K, V, mtchm::meta::DefConfig>;
pub type IndexMTRaw<E> = mtchm::imp::Raw<E, mtchm::meta::DefConfig>;
@ -167,6 +169,11 @@ pub trait MTIndex<E, K, V>: IndexBaseSpec {
Q: ?Sized + Comparable<K>;
/// Returns a reference to the value corresponding to the key, if it exists
fn mt_get<'t, 'g, 'v, Q>(&'t self, key: &Q, g: &'g Guard) -> Option<&'v V>
where
Q: ?Sized + Comparable<K>,
't: 'v,
'g: 't + 'v;
fn mt_get_element<'t, 'g, 'v, Q>(&'t self, key: &Q, g: &'g Guard) -> Option<&'v E>
where
Q: ?Sized + Comparable<K>,
't: 'v,

@ -93,3 +93,33 @@ impl<'re, T: TreeElement, U: Comparable<T::Key> + ?Sized> ReadMode<T> for RModeR
None
}
}
pub struct RModeElementRef<'a, T, U: ?Sized> {
target: &'a U,
_d: PhantomData<T>,
}
impl<'a, T, U: ?Sized> RModeElementRef<'a, T, U> {
pub fn new(target: &'a U) -> Self {
Self {
target,
_d: PhantomData,
}
}
}
impl<'re, T: TreeElement, U: Comparable<T::Key> + ?Sized> ReadMode<T>
for RModeElementRef<'re, T, U>
{
type Ret<'a> = Option<&'a T>;
type Target = U;
fn target(&self) -> &Self::Target {
self.target
}
fn ex(c: &T) -> Self::Ret<'_> {
Some(c)
}
fn nx<'a>() -> Self::Ret<'a> {
None
}
}

@ -121,6 +121,15 @@ impl<E: TreeElement, C: Config> MTIndex<E, E::Key, E::Value> for Raw<E, C> {
self.get(key, g)
}
fn mt_get_element<'t, 'g, 'v, Q>(&'t self, key: &Q, g: &'g Guard) -> Option<&'v E>
where
Q: ?Sized + Comparable<E::Key>,
't: 'v,
'g: 't + 'v,
{
self.get_full(key, g)
}
fn mt_get_cloned<Q>(&self, key: &Q, g: &Guard) -> Option<E::Value>
where
Q: ?Sized + Comparable<E::Key>,

@ -421,6 +421,13 @@ impl<T: TreeElement, C: Config> RawTree<T, C> {
) -> Option<&'g T::Value> {
self._lookup(access::RModeRef::new(k), g)
}
fn get_full<'g, Q: ?Sized + Comparable<T::Key>>(
&'g self,
k: &Q,
g: &'g Guard,
) -> Option<&'g T> {
self._lookup(access::RModeElementRef::new(k), g)
}
fn _lookup<'g, R: access::ReadMode<T>>(&'g self, r: R, g: &'g Guard) -> R::Ret<'g> {
let mut hash = self.hash(r.target());
let mut current = &self.root;

@ -26,6 +26,7 @@
pub(super) mod config;
mod iter;
pub(super) mod shared;
use {
self::{

@ -0,0 +1,131 @@
/*
* Created on Mon May 08 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/>.
*
*/
#[cfg(debug_assertions)]
use super::IndexSTSeqDllMetrics;
use {
super::{config::Config, IndexSTSeqDll},
crate::engine::{
idx::{AsKey, AsValue, IndexBaseSpec},
sync::smart::EArc,
},
std::{
mem::ManuallyDrop,
ops::{Deref, DerefMut},
},
};
#[derive(Debug)]
pub struct OrderedIdxRC<K, V, C: Config<K, V>> {
base: ManuallyDrop<IndexSTSeqDll<K, V, C>>,
rc: EArc,
}
impl<K, V, C: Config<K, V>> OrderedIdxRC<K, V, C> {
fn new() -> Self {
Self::new_with(IndexSTSeqDll::new())
}
fn new_with(idx: IndexSTSeqDll<K, V, C>) -> Self {
Self {
base: ManuallyDrop::new(idx),
rc: unsafe {
// UNSAFE(@ohsayan): we'll clean this up
EArc::new()
},
}
}
}
impl<K, V, C: Config<K, V>> Deref for OrderedIdxRC<K, V, C> {
type Target = IndexSTSeqDll<K, V, C>;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl<K, V, C: Config<K, V>> DerefMut for OrderedIdxRC<K, V, C> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl<K, V, C: Config<K, V>> Clone for OrderedIdxRC<K, V, C> {
fn clone(&self) -> Self {
let rc = unsafe {
// UNSAFE(@ohsayan): called at clone position
self.rc.rc_clone()
};
Self {
base: unsafe {
// UNSAFE(@ohsayan): just a raw clone. no big deal since this is an RC
core::mem::transmute_copy(&self.base)
},
rc,
}
}
}
impl<K, V, C: Config<K, V>> Drop for OrderedIdxRC<K, V, C> {
fn drop(&mut self) {
unsafe {
// UNSAFE(@ohsayan): this is the dtor
self.rc.rc_drop(|| ManuallyDrop::drop(&mut self.base))
}
}
}
impl<K, V, C: Config<K, V>> IndexBaseSpec for OrderedIdxRC<K, V, C> {
const PREALLOC: bool = true;
#[cfg(debug_assertions)]
type Metrics = IndexSTSeqDllMetrics;
fn idx_init_cap(cap: usize) -> Self {
Self::new_with(IndexSTSeqDll::with_capacity(cap))
}
fn idx_init() -> Self {
Self::new()
}
fn idx_init_with(s: Self) -> Self {
s
}
#[cfg(debug_assertions)]
fn idx_metrics(&self) -> &Self::Metrics {
self.base.idx_metrics()
}
}
impl<K: AsKey, V: AsValue + PartialEq, C: Config<K, V>> PartialEq for OrderedIdxRC<K, V, C> {
fn eq(&self, other: &Self) -> bool {
self.len() == other.len()
&& self
._iter_unord_kv()
.all(|(k, v)| other._get(k).unwrap().eq(v))
}
}

@ -145,3 +145,9 @@ macro_rules! into_dict {
.collect()
}};
}
#[cfg(test)]
#[allow(unused_macros)]
macro_rules! into_vec {
($($val:expr),* $(,)?) => { vec![$(::core::convert::From::from($val),)*]};
}

@ -50,6 +50,18 @@ pub struct DeleteStatement<'a> {
pub(super) wc: WhereClause<'a>,
}
impl<'a> DeleteStatement<'a> {
pub const fn entity(&self) -> Entity<'a> {
self.entity
}
pub const fn clauses(&self) -> &WhereClause {
&self.wc
}
pub fn clauses_mut(&mut self) -> &mut WhereClause<'a> {
&mut self.wc
}
}
impl<'a> DeleteStatement<'a> {
#[inline(always)]
pub(super) fn new(entity: Entity<'a>, wc: WhereClause<'a>) -> Self {

@ -74,9 +74,12 @@ impl<'a> RelationalExpr<'a> {
pub(super) const OP_GE: u8 = 4;
pub(super) const OP_LT: u8 = 5;
pub(super) const OP_LE: u8 = 6;
fn filter_hint_none(&self) -> bool {
pub fn filter_hint_none(&self) -> bool {
self.opc == Self::OP_EQ
}
pub fn rhs(&self) -> LitIR<'a> {
self.rhs.clone()
}
#[inline(always)]
fn parse_operator<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> u8 {
let tok = state.current();
@ -127,6 +130,9 @@ impl<'a> WhereClause<'a> {
pub(super) fn new(c: WhereClauseCollection<'a>) -> Self {
Self { c }
}
pub fn clauses_mut(&mut self) -> &mut WhereClauseCollection<'a> {
&mut self.c
}
#[inline(always)]
fn parse_where_and_append_to<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
@ -152,6 +158,9 @@ impl<'a> WhereClause<'a> {
state.poison_if(c.is_empty());
Self { c }
}
pub fn clauses(&self) -> &WhereClauseCollection {
&self.c
}
}
#[cfg(test)]

@ -78,6 +78,21 @@ impl<'a> SelectStatement<'a> {
clause: WhereClause::new(clauses),
}
}
pub fn entity(&self) -> Entity<'a> {
self.entity
}
pub fn clauses(&self) -> &WhereClause<'a> {
&self.clause
}
pub fn clauses_mut(&mut self) -> &mut WhereClause<'a> {
&mut self.clause
}
pub fn is_wildcard(&self) -> bool {
self.wildcard
}
pub fn into_fields(self) -> Vec<Ident<'a>> {
self.fields
}
}
impl<'a> SelectStatement<'a> {

@ -219,6 +219,7 @@ unsafe impl<T: Send> Send for SliceRC<T> {}
unsafe impl<T: Sync> Sync for SliceRC<T> {}
/// A simple rc
#[derive(Debug)]
pub struct EArc {
base: RawRC<()>,
}

Loading…
Cancel
Save