Skip to content

Commit

Permalink
Split the db module out into its own crate.
Browse files Browse the repository at this point in the history
  • Loading branch information
rdaum committed Sep 26, 2023
1 parent 3666827 commit 25a9f01
Show file tree
Hide file tree
Showing 38 changed files with 188 additions and 96 deletions.
35 changes: 35 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ resolver = "2"
members = [
"crates/values",
"crates/kernel",
"crates/db",
"crates/rpc-common",
"crates/daemon",
"crates/telnet-host",
Expand Down
6 changes: 4 additions & 2 deletions crates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ Binaries:
Libraries:
* `values` - crate that implements the core MOO discriminated union (`Var`) value type,
plus all associated types and traits.
* `kernel` - the actual implementation of the system: database, compiler, virtual machine,
task scheduler, implementations of all builtin functions, etc.
* `db` - implementation of the `WorldState` object database trait w/ a (for now) RocksDB backend, along with mock/testing
database implementations.
* `kernel` - the kernel of the MOO driver: compiler, virtual machine, task scheduler, implementations of all builtin
functions
* `rpc-common` - provides types & functions used by both `daemon` and each host binary, for the RPC interface
* `regexpr-binding` - provides bindings to the old regular expressions library used by
the LambdaMOO server, for compatibility with existing cores. This is a temporary measure until
Expand Down
1 change: 1 addition & 0 deletions crates/daemon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ repository.workspace = true

[dependencies]
moor-kernel = { path = "../kernel" }
moor-db = { path = "../db" }
moor-values = { path = "../values" }
rpc-common = { path = "../rpc-common" }

Expand Down
2 changes: 1 addition & 1 deletion crates/daemon/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use tokio::select;
use tokio::signal::unix::{signal, SignalKind};
use tracing::info;

use moor_kernel::db::{DatabaseBuilder, DatabaseType};
use moor_db::{DatabaseBuilder, DatabaseType};
use moor_kernel::tasks::scheduler::Scheduler;
use moor_kernel::textdump::load_db::textdump_load;
use rpc_common::{RpcRequestError, RpcResponse, RpcResult};
Expand Down
52 changes: 52 additions & 0 deletions crates/db/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[package]
name = "moor-db"
version = "0.1.0"
edition.workspace = true
license.workspace = true
repository.workspace = true

[dev-dependencies]
tempfile.workspace = true
inventory.workspace = true
test-case.workspace = true
unindent.workspace = true
pretty_assertions.workspace = true


[dependencies]

## Own
moor-values = { path = "../values" }

## General usefullness
itertools.workspace = true
lazy_static.workspace = true
enum-primitive-derive.workspace = true
async-trait.workspace = true
decorum.workspace = true
text_io.workspace = true
bytes.workspace = true
strum.workspace = true
uuid.workspace = true

## Error declaration/ handling
thiserror.workspace = true

## For macro-ing
paste.workspace = true

## Asynchrony and/or networking
tokio.workspace = true
tokio-test.workspace = true

## Logging & tracing
tracing.workspace = true
tracing-test.workspace = true
metrics.workspace = true
metrics-util.workspace = true
metrics-macros.workspace = true

# For the DB layer.
rocksdb.workspace = true
crossbeam-channel.workspace = true
bincode.workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use moor_values::util::bitenum::BitEnum;
use moor_values::var::objid::Objid;
use moor_values::var::Var;

use crate::db::db_message::DbMessage;
use crate::db_message::DbMessage;
use moor_values::model::verbdef::VerbDefs;

pub(crate) struct DbTxClient {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use moor_values::util::bitenum::BitEnum;
use moor_values::var::objid::Objid;
use moor_values::var::Var;

use crate::db::loader::LoaderInterface;
use crate::db::DbTxWorldState;
use crate::loader::LoaderInterface;
use crate::DbTxWorldState;

#[async_trait]
impl LoaderInterface for DbTxWorldState {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use moor_values::var::variant::Variant;
use moor_values::var::{v_int, v_list, v_objid, Var};
use moor_values::NOTHING;

use crate::db::DbTxWorldState;
use crate::DbTxWorldState;

// all of this right now is direct-talk to physical DB transaction, and should be fronted by a
// cache.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/// "local" in-memory transient "db" implementation. For testing.
/// no persistence, no transactions, just a write lock and some hash tables.
use crate::db::db_client::DbTxClient;
use crate::db::db_message::DbMessage;
use crate::db::inmemtransient::transient_store::TransientStore;
use crate::db::loader::LoaderInterface;
use crate::db::{Database, DbTxWorldState};
use crate::db_client::DbTxClient;
use crate::db_message::DbMessage;
use crate::inmemtransient::transient_store::TransientStore;
use crate::loader::LoaderInterface;
use crate::{Database, DbTxWorldState};
use async_trait::async_trait;
use crossbeam_channel::Receiver;
use moor_values::model::world_state::{WorldState, WorldStateSource};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ impl TransientStore {

#[cfg(test)]
mod tests {
use crate::db::inmemtransient::transient_store::TransientStore;
use crate::inmemtransient::transient_store::TransientStore;
use moor_values::model::defset::HasUuid;
use moor_values::model::objects::ObjAttrs;
use moor_values::model::objset::ObjSet;
Expand Down
11 changes: 4 additions & 7 deletions crates/kernel/src/db/mod.rs → crates/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,19 @@ use std::thread;

use strum::{Display, EnumIter, EnumString, EnumVariantNames};

use crate::db::db_client::DbTxClient;
use crate::db::inmemtransient::InMemTransientDatabase;
use crate::db::loader::LoaderInterface;
use crate::db::rocksdb::db_server::RocksDbServer;
use crate::db_client::DbTxClient;
use crate::inmemtransient::InMemTransientDatabase;
use crate::loader::LoaderInterface;
use crate::rocksdb::db_server::RocksDbServer;
use moor_values::model::world_state::WorldStateSource;
use moor_values::model::WorldStateError;

pub mod matching;

mod db_client;
mod db_loader_client;
mod db_message;
mod db_worldstate;
pub mod inmemtransient;
pub mod loader;
pub mod match_env;
pub mod mock;
pub mod rocksdb;

Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions crates/db/src/mock/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ use moor_values::model::world_state::{WorldState, WorldStateSource};
use moor_values::model::WorldStateError;
use moor_values::SYSTEM_OBJECT;

use crate::db::db_client::DbTxClient;
use crate::db::loader::LoaderInterface;
use crate::db::rocksdb::tx_db_impl::oid_key;
use crate::db::rocksdb::tx_server::run_tx_server;
use crate::db::rocksdb::ColumnFamilies;
use crate::db::{Database, DbTxWorldState};
use crate::db_client::DbTxClient;
use crate::loader::LoaderInterface;
use crate::rocksdb::tx_db_impl::oid_key;
use crate::rocksdb::tx_server::run_tx_server;
use crate::rocksdb::ColumnFamilies;
use crate::{Database, DbTxWorldState};

// Rocks implementation of 'WorldStateSource' -- opens the physical database and provides
// transactional 'WorldState' implementations for each new transaction.
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use moor_values::util::slice_ref::SliceRef;
use moor_values::var::objid::Objid;
use moor_values::{AsByteBuffer, NOTHING};

use crate::db::rocksdb::ColumnFamilies;
use crate::rocksdb::ColumnFamilies;

pub fn oid_key(o: Objid) -> [u8; 8] {
o.0.to_be_bytes()
Expand Down Expand Up @@ -147,8 +147,8 @@ mod tests {
use moor_values::var::v_str;
use moor_values::NOTHING;

use crate::db::rocksdb::tx_db_impl::RocksDbTx;
use crate::db::rocksdb::ColumnFamilies;
use crate::rocksdb::tx_db_impl::RocksDbTx;
use crate::rocksdb::ColumnFamilies;

struct TestDb {
db: Arc<OptimisticTransactionDB>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ use moor_values::util::bitenum::BitEnum;
use moor_values::util::slice_ref::SliceRef;
use moor_values::var::objid::Objid;

use crate::db::rocksdb::tx_db_impl::{
use crate::rocksdb::tx_db_impl::{
cf_for, composite_key_for, get_objset, get_oid_or_nothing, get_oid_value, oid_key, set_objset,
set_oid_value, write_cf, RocksDbTx,
};
use crate::db::rocksdb::ColumnFamilies;
use crate::rocksdb::ColumnFamilies;

// Methods for manipulation of objects, their owners, flags, contents, parents, etc.
impl<'a> RocksDbTx<'a> {
Expand All @@ -41,7 +41,7 @@ impl<'a> RocksDbTx<'a> {
Some(oid) => {
// If this object already exists, that's an error.
if self.object_valid(oid)? {
return Err(WorldStateError::ObjectAlreadyExists(oid).into());
return Err(WorldStateError::ObjectAlreadyExists(oid));
}
oid
}
Expand Down Expand Up @@ -270,7 +270,7 @@ impl<'a> RocksDbTx<'a> {
let ok = oid_key(o);
let name_bytes = self.tx.get_cf(cf, ok).expect("Unable to get object name");
let Some(name_bytes) = name_bytes else {
return Err(WorldStateError::ObjectNotFound(o).into());
return Err(WorldStateError::ObjectNotFound(o));
};
Ok(String::from_sliceref(SliceRef::from_bytes(&name_bytes)))
}
Expand All @@ -287,7 +287,7 @@ impl<'a> RocksDbTx<'a> {
let ok = oid_key(o);
let flag_bytes = self.tx.get_cf(cf, ok).expect("Unable to get object flags");
let Some(flag_bytes) = flag_bytes else {
return Err(WorldStateError::ObjectNotFound(o).into());
return Err(WorldStateError::ObjectNotFound(o));
};
Ok(BitEnum::from_sliceref(SliceRef::from_bytes(&flag_bytes)))
}
Expand Down Expand Up @@ -340,7 +340,7 @@ impl<'a> RocksDbTx<'a> {
break;
}
if oid == what {
return Err(WorldStateError::RecursiveMove(what, new_location).into());
return Err(WorldStateError::RecursiveMove(what, new_location));
}
oid = self.get_object_location(oid).unwrap_or(NOTHING);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use moor_values::var::objid::Objid;
use moor_values::var::{v_none, Var};
use moor_values::{AsByteBuffer, NOTHING};

use crate::db::rocksdb::tx_db_impl::{
use crate::rocksdb::tx_db_impl::{
composite_key_uuid, get_oid_or_nothing, get_oid_value, oid_key, write_cf, RocksDbTx,
};
use crate::db::rocksdb::ColumnFamilies;
use crate::rocksdb::ColumnFamilies;

// Methods related to properties; definitions and values.
impl<'a> RocksDbTx<'a> {
Expand Down Expand Up @@ -43,7 +43,7 @@ impl<'a> RocksDbTx<'a> {
.expect("Unable to read property value");
let Some(var_bytes) = var_bytes else {
let u_uuid_str = u.to_string();
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str).into());
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str));
};
let var = Var::from_sliceref(SliceRef::from_bytes(&var_bytes));
Ok(var)
Expand Down Expand Up @@ -72,7 +72,7 @@ impl<'a> RocksDbTx<'a> {
.expect("Unable to read property definitions");
let Some(props_bytes) = props_bytes else {
let u_uuid_str = u.to_string();
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str).into());
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str));
};
let props = PropDefs::from_sliceref(SliceRef::from_bytes(&props_bytes));
let Some(new_props) = props.with_updated(u, |p| {
Expand All @@ -90,7 +90,7 @@ impl<'a> RocksDbTx<'a> {
)
}) else {
let u_uuid_str = u.to_string();
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str).into());
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str));
};

self.update_propdefs(o, new_props)?;
Expand All @@ -105,12 +105,12 @@ impl<'a> RocksDbTx<'a> {
.get_cf(p_cf, ok)
.expect("Unable to read property definitions");
let Some(props_bytes) = props_bytes else {
return Err(WorldStateError::ObjectNotFound(o).into());
return Err(WorldStateError::ObjectNotFound(o));
};
let props = PropDefs::from_sliceref(SliceRef::from_bytes(&props_bytes));
let Some(new_props) = props.with_removed(u) else {
let u_uuid_str = u.to_string();
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str).into());
return Err(WorldStateError::PropertyNotFound(o, u_uuid_str));
};
self.update_propdefs(o, new_props)?;

Expand Down Expand Up @@ -167,7 +167,7 @@ impl<'a> RocksDbTx<'a> {

// Verify we don't already have a property with this name. If we do, return an error.
if props.find_first_named(name.as_str()).is_some() {
return Err(WorldStateError::DuplicatePropertyDefinition(location, name).into());
return Err(WorldStateError::DuplicatePropertyDefinition(location, name));
}

let prop = PropDef::new(u, definer, location, name.as_str(), perms, owner);
Expand All @@ -194,7 +194,7 @@ impl<'a> RocksDbTx<'a> {

let propdef = self.seek_property_definition(obj, n.clone())?;
let Some(propdef) = propdef else {
return Err(WorldStateError::PropertyNotFound(obj, n).into());
return Err(WorldStateError::PropertyNotFound(obj, n));
};

// Then we're going to resolve the value up the tree, skipping 'clear' (un-found) until we
Expand Down
Loading

0 comments on commit 25a9f01

Please sign in to comment.