Reduce memory usage per GNS index item

next
Sayan Nandan 1 year ago
parent 1586b05bbd
commit f98c5d3aa4
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -30,7 +30,7 @@ mod space;
mod tests;
// imports
use {
crate::engine::{core::space::Space, data::ItemID, idx::IndexST},
crate::engine::{core::space::Space, idx::IndexST},
parking_lot::RwLock,
};
// re-exports
@ -43,11 +43,11 @@ type RWLIdx<K, V> = RwLock<IndexST<K, V>>;
// FIXME(@ohsayan): Make sure we update what all structures we're making use of here
pub struct GlobalNS {
index_space: RWLIdx<ItemID, Space>,
index_space: RWLIdx<Box<str>, Space>,
}
impl GlobalNS {
pub(self) fn spaces(&self) -> &RWLIdx<ItemID, Space> {
pub(self) fn spaces(&self) -> &RWLIdx<Box<str>, Space> {
&self.index_space
}
pub fn empty() -> Self {

@ -252,11 +252,11 @@ impl ModelView {
return Err(DatabaseError::ExpectedEntity);
};
let gns = gns.spaces().read();
let Some(space) = gns.st_get(space.as_bytes()) else {
let Some(space) = gns.st_get(space.as_str()) else {
return Err(DatabaseError::DdlSpaceNotFound)
};
let space = space.models().read();
let Some(model) = space.st_get(model.as_bytes()) else {
let Some(model) = space.st_get(model.as_str()) else {
return Err(DatabaseError::DdlModelNotFound);
};
// make intent

@ -33,10 +33,7 @@ use std::cell::RefCell;
use {
crate::engine::{
core::model::cell::Datacell,
data::{
tag::{DataTag, FullTag, TagClass, TagSelector},
ItemID,
},
data::tag::{DataTag, FullTag, TagClass, TagSelector},
error::{DatabaseError, DatabaseResult},
idx::{IndexSTSeqCns, STIndex, STIndexSeq},
mem::VInline,
@ -115,13 +112,12 @@ impl ModelView {
impl ModelView {
pub fn process_create(
CreateModel {
model_name,
model_name: _,
fields,
props,
}: CreateModel,
) -> DatabaseResult<Self> {
let mut okay =
props.is_empty() & !fields.is_empty() & ItemID::check(model_name.any_single().as_str());
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());
@ -167,21 +163,21 @@ impl ModelView {
let Some((space_name, model_name)) = name.into_full() else {
return Err(DatabaseError::ExpectedEntity);
};
let Some(space) = space_rl.get(space_name.as_bytes()) else {
let Some(space) = space_rl.get(space_name.as_str()) else {
return Err(DatabaseError::DdlSpaceNotFound)
};
space._create_model(ItemID::new(model_name.as_str()), model)
space._create_model(model_name.as_str(), model)
}
pub fn exec_drop(gns: &super::GlobalNS, stmt: DropModel) -> DatabaseResult<()> {
let Some((space, model)) = stmt.entity.into_full() else {
return Err(DatabaseError::ExpectedEntity);
};
let spaces = gns.spaces().read();
let Some(space) = spaces.st_get(space.as_bytes()) else {
let Some(space) = spaces.st_get(space.as_str()) else {
return Err(DatabaseError::DdlSpaceNotFound);
};
let mut w_space = space.models().write();
match w_space.st_delete_if(model.as_bytes(), |mdl| !mdl.is_empty_atomic()) {
match w_space.st_delete_if(model.as_str(), |mdl| !mdl.is_empty_atomic()) {
Some(true) => Ok(()),
Some(false) => Err(DatabaseError::DdlModelViewNotEmpty),
None => Err(DatabaseError::DdlModelNotFound),

@ -26,7 +26,7 @@
use {
crate::engine::{
core::{model::ModelView, ItemID, RWLIdx},
core::{model::ModelView, 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<ItemID, ModelView>,
mns: RWLIdx<Box<str>, ModelView>,
pub(super) meta: SpaceMeta,
}
@ -61,27 +61,31 @@ impl SpaceMeta {
#[cfg_attr(test, derive(PartialEq))]
/// Procedure for `create space`
struct ProcedureCreate {
space_name: ItemID,
space_name: Box<str>,
space: Space,
}
impl ProcedureCreate {
#[inline(always)]
/// Define the procedure
fn new(space_name: ItemID, space: Space) -> Self {
fn new(space_name: Box<str>, space: Space) -> Self {
Self { space_name, space }
}
}
impl Space {
pub fn _create_model(&self, name: ItemID, model: ModelView) -> DatabaseResult<()> {
if self.mns.write().st_insert(name, model) {
pub fn _create_model(&self, name: &str, model: ModelView) -> DatabaseResult<()> {
if self
.mns
.write()
.st_insert(name.to_string().into_boxed_str(), model)
{
Ok(())
} else {
Err(DatabaseError::DdlModelAlreadyExists)
}
}
pub(super) fn models(&self) -> &RWLIdx<ItemID, ModelView> {
pub(super) fn models(&self) -> &RWLIdx<Box<str>, ModelView> {
&self.mns
}
}
@ -91,7 +95,7 @@ impl Space {
Space::new(Default::default(), SpaceMeta::with_env(into_dict! {}))
}
#[inline(always)]
pub fn new(mns: IndexST<ItemID, ModelView>, meta: SpaceMeta) -> Self {
pub fn new(mns: IndexST<Box<str>, ModelView>, meta: SpaceMeta) -> Self {
Self {
mns: RWLIdx::new(mns),
meta,
@ -105,7 +109,7 @@ impl Space {
mut props,
}: CreateSpace,
) -> DatabaseResult<ProcedureCreate> {
let space_name = ItemID::try_new(&space_name).ok_or(DatabaseError::SysBadItemID)?;
let space_name = space_name.to_string().into_boxed_str();
// check env
let env = match props.remove(SpaceMeta::KEY_ENV) {
Some(Some(DictEntryGeneric::Map(m))) if props.is_empty() => m,
@ -146,7 +150,7 @@ impl Space {
mut updated_props,
}: AlterSpace,
) -> DatabaseResult<()> {
match gns.spaces().read().st_get(space_name.as_bytes()) {
match gns.spaces().read().st_get(space_name.as_str()) {
Some(space) => {
let mut space_env = space.meta.env.write();
match updated_props.remove(SpaceMeta::KEY_ENV) {
@ -173,7 +177,7 @@ impl Space {
match gns
.spaces()
.write()
.st_delete_if(space.as_bytes(), |space| space.mns.read().len() == 0)
.st_delete_if(space.as_str(), |space| space.mns.read().len() == 0)
{
Some(true) => Ok(()),
Some(false) => Err(DatabaseError::DdlSpaceRemoveNonEmpty),

@ -59,9 +59,9 @@ fn exec_plan(
let (_space, model_name) = alter.model.into_full().unwrap();
ModelView::exec_alter(gns, alter)?;
let gns_read = gns.spaces().read();
let space = gns_read.st_get("myspace".as_bytes()).unwrap();
let space = gns_read.st_get("myspace").unwrap();
let model = space.models().read();
f(model.st_get(model_name.as_bytes()).unwrap());
f(model.st_get(model_name.as_str()).unwrap());
Ok(())
}

@ -64,14 +64,14 @@ pub fn exec_create_no_create(gns: &GlobalNS, create_stmt: &str) -> DatabaseResul
fn with_space(gns: &GlobalNS, space_name: &str, f: impl Fn(&Space)) {
let rl = gns.spaces().read();
let space = rl.st_get(space_name.as_bytes()).unwrap();
let space = rl.st_get(space_name).unwrap();
f(space);
}
fn with_model(gns: &GlobalNS, space_id: &str, model_name: &str, f: impl Fn(&ModelView)) {
with_space(gns, space_id, |space| {
let space_rl = space.models().read();
let model = space_rl.st_get(model_name.as_bytes()).unwrap();
let model = space_rl.st_get(model_name).unwrap();
f(model)
})
}

@ -47,7 +47,7 @@ fn exec_verify(
let ast_node = compile_test(&tok).unwrap();
let (res, space_name) = exec(gns, ast_node);
let rl = gns.spaces().read();
let space_ref = rl.st_get(space_name.as_bytes());
let space_ref = rl.st_get(&space_name);
let r = res.map(|_| space_ref.unwrap());
verify(r);
}

@ -33,8 +33,4 @@ pub mod tag;
#[cfg(test)]
mod tests;
use crate::engine::mem::AStr;
pub use md_dict::{DictEntryGeneric, DictGeneric, MetaDict};
const IDENT_MX: usize = 64;
pub type ItemID = AStr<IDENT_MX>;

@ -25,25 +25,3 @@
*/
mod md_dict_tests;
use crate::engine::{data::ItemID, ql::lex::Ident};
#[test]
fn item_id_okay() {
let _ = ItemID::from(Ident::from("hello"));
}
#[test]
fn test_item_id_exact() {
let _ = ItemID::from(Ident::from(
"Abe76d912c6e205aa05edf974cd21cd48061d86d12d92ac1028e5b90f3132f4e",
));
}
#[test]
#[should_panic(expected = "length overflow")]
fn item_id_too_long() {
let _ = ItemID::from(Ident::from(
"Abe76d912c6e205aa05edf974cd21cd48061d86d12d92ac1028e5b90f3132f4e_",
));
}

Loading…
Cancel
Save