DEV Community

Cover image for SolomonDB Weekly Update (#1): Baal
Tin Chung
Tin Chung

Posted on

SolomonDB Weekly Update (#1): Baal

Support my project by visiting SolomonDB Github and give me a star ⭐️

Weekly Update #1: Baal

Date: October 2022 (26-28/11/2022)

According to the Grand Grimoire, Baal (or Bael) is the head of the infernal powers. He is also the first demon listed in Wierus' Pseudomonarchia daemonum. According to Wierus, Bael is the first king of Hell with estates in the east. He has three heads: a toad, a man, and a cat. He also speaks in a raucous, but well-formed voice, and commands 66 legions. Bael teaches the art of invisibility, and may be the equivalent of Baal or Baalzebub, one of the Seven princes of Hell. - Wikipedia

Commits on Oct 26, 2022

Description

A soft beginning. I just spend some time to read graph database book and learning concepts, requirements needed to construct Solomon DB.

Detail explanation

There are a few interesting learning outcomes acquired here:

These concepts are not too complicated actually. Not talking about native graph database, non-native graph database is more like a database wrapper which has internals built on top of other databases.

-   Underlying storage
-   Processing engine
-   Graph compute engine
Enter fullscreen mode Exit fullscreen mode

Learnt and noted down these concepts in WIKI.md.

As this is the first commit, it only includes code to initialize a codebase and its basic layout for Rust project using cargo new.

// A simple hello world program (db/src/main.rs)
fn main() {
    println!("Hello, world!");
}
Enter fullscreen mode Exit fullscreen mode

Contributors


Commits on Oct 28, 2022

Description

Add StorageDriver, new type RocksDBDriver, macro impl_driver_core and misc implementation for StorageErr and Status.

Detail explanation

Things getting more exciting when we touch advanced syntaxes in Rust: New Type design pattern and Macro. Before jumping right into the main point of today changes, one of a missing features in Rust compared to other OOP languages must be mentioned first is the ability to do inheritance.

With what Rust provides so far, it is quite tricky to construct an inheritable struct object. At first, you may think doing OOP in Rust is quite bad as inheritance is a core component of any OOP design. However, if you learn more about OOP, you will know Inheritance < Composition. This is quite off topic, but there is a few discussions and articles related to the way Rust do OOP that you should read:

Briefly, even though Rust does not have an obvious OOP feature like inheritance, it still provides several approaches: Trait, New type, Macro or Enum to do thing in a inheritance way but cleaner as things are separated elegantly.

New Type design pattern for RocksDB Driver

"The newtype idiom gives compile time guarantees that the right type of value is supplied to a program" - Rust book.

I apply the design to implement RocksDB Driver. The idea is to have a parent struct called StorageDriver and we will build a new type RocksDBDriver from that.

pub struct StorageDriver<T> {
 pub db_instance: Option<T>,
 pub path: String,
}

pub struct RocksDBDriver(StorageDriver<DB>);
Enter fullscreen mode Exit fullscreen mode

However, NewType design does not exactly like inheritance. For example, if you want to get field db_instance from RocksDBDriver, you can't do self.db_instance but self.0.db.instance. Can imagine db_instance is inside StorageDriver while StorageDriver is wrapped inside new type RocksDBDriver. This would make the syntax looks a bit dirty. The solution I used to handle this case is Macro.

Macro provides an ability to maximize the power of Rust syntax. I wrote a macro to implement all below methods used inside any impl calling to impl_driver_core. Then to get the inner of new type, we just have to use get_core.

macro_rules! impl_driver_core {
 ($DbType: ty) => {
  fn get_core(self: &mut Self) -> &mut StorageDriver<$DbType> {
   &mut self.0
  }
 };
}

pub(crate) use impl_driver_core;
Enter fullscreen mode Exit fullscreen mode

Struct RocksDBDriver now becomes:

impl RocksDBDriver {
 super::core::impl_driver_core!(DB);

 /// # Initializing RocksDB driver
 pub fn initialize(self: &mut Self, cf_name: &String, options: rocksdb::Options) {
  let core = self.get_core();
  ...
 }
}
Enter fullscreen mode Exit fullscreen mode

Contributors

Top comments (0)