diff options
| -rw-r--r-- | Cargo.lock | 38 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | README.md | 22 | ||||
| -rw-r--r-- | autere_db/Cargo.toml (renamed from log_db/Cargo.toml) | 2 | ||||
| -rw-r--r-- | autere_db/benches/benchmark.rs (renamed from log_db/benches/benchmark.rs) | 2 | ||||
| -rw-r--r-- | autere_db/benches/utils.rs (renamed from log_db/benches/utils.rs) | 2 | ||||
| -rw-r--r-- | autere_db/src/common.rs (renamed from log_db/src/common.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/config.rs (renamed from log_db/src/config.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/engine.rs (renamed from log_db/src/engine.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/lib.rs (renamed from log_db/src/lib.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/lock.rs (renamed from log_db/src/lock.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/log_reader_forward.rs (renamed from log_db/src/log_reader_forward.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/memtable_primary.rs (renamed from log_db/src/memtable_primary.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/memtable_secondary.rs (renamed from log_db/src/memtable_secondary.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/record.rs (renamed from log_db/src/record.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/row.rs (renamed from log_db/src/row.rs) | 0 | ||||
| -rw-r--r-- | autere_db/src/schema.rs (renamed from log_db/src/schema.rs) | 0 | ||||
| -rw-r--r-- | autere_db/tests/integration.rs (renamed from log_db/tests/integration.rs) | 2 | ||||
| -rw-r--r-- | autere_db/tests/resources/test_data_1 (renamed from log_db/tests/resources/test_data_1) | bin | 266 -> 266 bytes | |||
| -rw-r--r-- | autere_db/tests/resources/test_metadata_1 (renamed from log_db/tests/resources/test_metadata_1) | bin | 40 -> 40 bytes | |||
| -rw-r--r-- | demo/app.py | 2 | ||||
| -rw-r--r-- | py_bindings/Cargo.toml | 2 | ||||
| -rw-r--r-- | py_bindings/example.py | 6 | ||||
| -rw-r--r-- | py_bindings/pyproject.toml | 2 | ||||
| -rw-r--r-- | py_bindings/src/lib.rs | 66 |
25 files changed, 74 insertions, 74 deletions
@@ -85,6 +85,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] +name = "autere_db" +version = "0.1.0" +dependencies = [ + "criterion", + "ctor", + "env_logger", + "fs2", + "log", + "once_cell", + "rand", + "rust_decimal", + "serial_test", + "tempfile", + "thiserror", + "uuid", +] + +[[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -609,24 +627,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] -name = "log_db" -version = "0.1.0" -dependencies = [ - "criterion", - "ctor", - "env_logger", - "fs2", - "log", - "once_cell", - "rand", - "rust_decimal", - "serial_test", - "tempfile", - "thiserror", - "uuid", -] - -[[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -782,7 +782,7 @@ dependencies = [ name = "py_bindings" version = "0.1.0" dependencies = [ - "log_db", + "autere_db", "pyo3", "rust_decimal", ] @@ -1,3 +1,3 @@ [workspace] resolver = "2" -members = ["log_db", "py_bindings"] +members = ["autere_db", "py_bindings"] @@ -1,8 +1,8 @@ -# LogDB +# AutereDB -An educational endeavor in implementing a log-structured database with a focus on simplicity, understandability and performance. +AutereDB is an educational endeavor in implementing a log-structured database engine with a focus on simplicity, understandability and performance. -LogDB has the following features: +AutereDB has the following features: - Log-structured single-table storage, based on a durable append-only log - In-memory indexes for fast lookups (primary and secondary) @@ -13,37 +13,37 @@ LogDB has the following features: - Transactions based on eager exclusive locking - Batch read operations for improved performance -LogDB does not support: +AutereDB does not support: - Authentication or authorization in any capacity - Multiple tables - Type checking or schema evolution. These are outsourced to the application layer. -See the [ARCHITECTURE.md](ARCHITECTURE.md) document for more details on the design and implementation of LogDB. +For production workloads, AutereDB would benefit from a porcelain layer that provides features such as query language, networking, and monitoring. AutereDB does not come with such a layer. See the [ARCHITECTURE.md](ARCHITECTURE.md) document for more details on the design and implementation. ## Inspiration -The most significant sources of inspiration for LogDB are: +The most significant sources of inspiration for AutereDB are: - [SQLite](https://www.sqlite.org/index.html) for its filesystem storage and locking mechanisms. - [Designing Data-Intensive Applications (book)](https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/) for its excellent overview of database internals and in-depth analysis of log-structured storage. - LogDB is heavily based on the design outlined in chapter 3. + AutereDB is heavily based on the design outlined in chapter 3. ## Usage in Rust -Add LogDB as a dependency in your `Cargo.toml`. +Add AutereDB as a dependency in your `Cargo.toml`. ```toml [dependencies] -log_db = { git = "https://github.com/jantuomi/log_db.git" } +autere_db = { git = "https://github.com/jantuomi/autere_db.git" } ``` Then use it in your code like so: ```rust -use log_db::*; +use autere_db::*; // Define a type that represents your fields (columns) #[derive(Eq, PartialEq, Clone, Debug)] @@ -170,4 +170,4 @@ db.upsert([Value.int(10)]) ## Copyright and license -LogDB is licensed under the Apache License, Version 2.0. © 2024 Jan Tuomi. +AutereDB is licensed under the Apache License, Version 2.0. © 2024 Jan Tuomi. diff --git a/log_db/Cargo.toml b/autere_db/Cargo.toml index 45df64d..c9ae7d2 100644 --- a/log_db/Cargo.toml +++ b/autere_db/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "log_db" +name = "autere_db" version = "0.1.0" edition = "2021" diff --git a/log_db/benches/benchmark.rs b/autere_db/benches/benchmark.rs index d8e6280..648c9f6 100644 --- a/log_db/benches/benchmark.rs +++ b/autere_db/benches/benchmark.rs @@ -2,8 +2,8 @@ mod utils; use std::collections::HashSet; +use autere_db::*; use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; -use log_db::*; use tempfile; use utils::*; diff --git a/log_db/benches/utils.rs b/autere_db/benches/utils.rs index 33a45cf..9b0a0ea 100644 --- a/log_db/benches/utils.rs +++ b/autere_db/benches/utils.rs @@ -1,4 +1,4 @@ -use log_db::*; +use autere_db::*; use rand::distributions::Alphanumeric; use rand::Rng; use std::fmt::Debug; diff --git a/log_db/src/common.rs b/autere_db/src/common.rs index 0f6a058..0f6a058 100644 --- a/log_db/src/common.rs +++ b/autere_db/src/common.rs diff --git a/log_db/src/config.rs b/autere_db/src/config.rs index e8c6fa1..e8c6fa1 100644 --- a/log_db/src/config.rs +++ b/autere_db/src/config.rs diff --git a/log_db/src/engine.rs b/autere_db/src/engine.rs index 6fb9edf..6fb9edf 100644 --- a/log_db/src/engine.rs +++ b/autere_db/src/engine.rs diff --git a/log_db/src/lib.rs b/autere_db/src/lib.rs index 006056c..006056c 100644 --- a/log_db/src/lib.rs +++ b/autere_db/src/lib.rs diff --git a/log_db/src/lock.rs b/autere_db/src/lock.rs index f00429f..f00429f 100644 --- a/log_db/src/lock.rs +++ b/autere_db/src/lock.rs diff --git a/log_db/src/log_reader_forward.rs b/autere_db/src/log_reader_forward.rs index f3fc16c..f3fc16c 100644 --- a/log_db/src/log_reader_forward.rs +++ b/autere_db/src/log_reader_forward.rs diff --git a/log_db/src/memtable_primary.rs b/autere_db/src/memtable_primary.rs index 573592e..573592e 100644 --- a/log_db/src/memtable_primary.rs +++ b/autere_db/src/memtable_primary.rs diff --git a/log_db/src/memtable_secondary.rs b/autere_db/src/memtable_secondary.rs index e1ca835..e1ca835 100644 --- a/log_db/src/memtable_secondary.rs +++ b/autere_db/src/memtable_secondary.rs diff --git a/log_db/src/record.rs b/autere_db/src/record.rs index b349853..b349853 100644 --- a/log_db/src/record.rs +++ b/autere_db/src/record.rs diff --git a/log_db/src/row.rs b/autere_db/src/row.rs index d8140d2..d8140d2 100644 --- a/log_db/src/row.rs +++ b/autere_db/src/row.rs diff --git a/log_db/src/schema.rs b/autere_db/src/schema.rs index 98d0df7..98d0df7 100644 --- a/log_db/src/schema.rs +++ b/autere_db/src/schema.rs diff --git a/log_db/tests/integration.rs b/autere_db/tests/integration.rs index 2012faf..2150ea1 100644 --- a/log_db/tests/integration.rs +++ b/autere_db/tests/integration.rs @@ -3,9 +3,9 @@ extern crate log; extern crate ctor; extern crate tempfile; +use autere_db::*; use ctor::ctor; use env_logger; -use log_db::*; use serial_test::serial; use std::fs::{self}; use std::path::Path; diff --git a/log_db/tests/resources/test_data_1 b/autere_db/tests/resources/test_data_1 Binary files differindex 5365384..5365384 100644 --- a/log_db/tests/resources/test_data_1 +++ b/autere_db/tests/resources/test_data_1 diff --git a/log_db/tests/resources/test_metadata_1 b/autere_db/tests/resources/test_metadata_1 Binary files differindex 98dd35e..98dd35e 100644 --- a/log_db/tests/resources/test_metadata_1 +++ b/autere_db/tests/resources/test_metadata_1 diff --git a/demo/app.py b/demo/app.py index bab20f0..ce305e9 100644 --- a/demo/app.py +++ b/demo/app.py @@ -13,7 +13,7 @@ import datetime from dataclasses import dataclass import uuid -from log_db import DB, Bound, Value +from autere_db import DB, Bound, Value app = Flask(__name__) Compress(app) diff --git a/py_bindings/Cargo.toml b/py_bindings/Cargo.toml index a84ccd6..1ddc264 100644 --- a/py_bindings/Cargo.toml +++ b/py_bindings/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" crate-type = ["lib"] [dependencies] -log_db = { path = "../log_db" } +autere_db = { path = "../autere_db" } pyo3 = "0.22.3" rust_decimal = { version = "1.36.0", features = [] } diff --git a/py_bindings/example.py b/py_bindings/example.py index 233d111..96040a9 100644 --- a/py_bindings/example.py +++ b/py_bindings/example.py @@ -1,8 +1,8 @@ import tempfile from pprint import pformat, pprint -from log_db import Value, Bound, DB +from autere_db import Value, Bound, DB -# TODO: This should be imported from the log_db module +# TODO: This should be imported from the autere_db module # but exporting type aliases does not work automatically Record = list[Value] @@ -40,7 +40,7 @@ db = DB \ db.upsert(Inst(1, "foo").into_record()) -#res = db.find_by("name", log_db.Value.string("foo")) +#res = db.find_by("name", autere_db.Value.string("foo")) #insts = [Inst.from_record(r) for r in res] res = db.range_by("name", Bound.unbounded(), diff --git a/py_bindings/pyproject.toml b/py_bindings/pyproject.toml index 6f5b437..113464a 100644 --- a/py_bindings/pyproject.toml +++ b/py_bindings/pyproject.toml @@ -3,7 +3,7 @@ requires = ["maturin>=1.7,<2.0"] build-backend = "maturin" [project] -name = "log_db" +name = "autere_db" requires-python = ">=3.8" classifiers = [ "Programming Language :: Rust", diff --git a/py_bindings/src/lib.rs b/py_bindings/src/lib.rs index 4e125ec..5a1c26a 100644 --- a/py_bindings/src/lib.rs +++ b/py_bindings/src/lib.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use std::usize; -use log_db::{self, OwnedBounds, QueryParams, Record, DEFAULT_QUERY_PARAMS}; +use autere_db::{self, OwnedBounds, QueryParams, Record, DEFAULT_QUERY_PARAMS}; use pyo3::exceptions::PyException; use pyo3::prelude::*; use rust_decimal::Decimal; @@ -20,8 +20,8 @@ pub const READ_CONSISTENCY_STRONG: u8 = 1; struct Config { data_dir: Option<PyField>, segment_size: Option<usize>, - write_durability: Option<log_db::WriteDurability>, - read_consistency: Option<log_db::ReadConsistency>, + write_durability: Option<autere_db::WriteDurability>, + read_consistency: Option<autere_db::ReadConsistency>, fields: Option<Vec<PyField>>, primary_key: Option<PyField>, secondary_keys: Option<Vec<PyField>>, @@ -50,8 +50,8 @@ impl Config { write_durability: u8, ) -> PyResult<PyRefMut<'a, Self>> { slf.write_durability = Some(match write_durability { - WRITE_DURABILITY_FLUSH => log_db::WriteDurability::Flush, - WRITE_DURABILITY_FLUSH_SYNC => log_db::WriteDurability::FlushSync, + WRITE_DURABILITY_FLUSH => autere_db::WriteDurability::Flush, + WRITE_DURABILITY_FLUSH_SYNC => autere_db::WriteDurability::FlushSync, _ => { return Err(PyException::new_err(format!( "Invalid write_durability value: {}", @@ -67,8 +67,8 @@ impl Config { read_consistency: u8, ) -> PyResult<PyRefMut<'a, Self>> { slf.read_consistency = Some(match read_consistency { - READ_CONSISTENCY_EVENTUAL => log_db::ReadConsistency::Eventual, - READ_CONSISTENCY_STRONG => log_db::ReadConsistency::Strong, + READ_CONSISTENCY_EVENTUAL => autere_db::ReadConsistency::Eventual, + READ_CONSISTENCY_STRONG => autere_db::ReadConsistency::Strong, _ => { return Err(PyException::new_err(format!( "Invalid read_consistency value: {}", @@ -104,7 +104,7 @@ impl Config { } pub fn initialize(&self) -> PyResult<DB> { - let mut config = log_db::DB::configure(); + let mut config = autere_db::DB::configure(); if self.data_dir.is_some() { config = config.data_dir(&self.data_dir.as_ref().unwrap().to_string()); } @@ -157,7 +157,7 @@ fn py_into_record(record: Vec<Value>) -> Record { record .into_iter() .map(|value| value.record_value) - .collect::<Vec<log_db::Value>>() + .collect::<Vec<autere_db::Value>>() .into() } @@ -170,34 +170,34 @@ const VALUE_NULL: u8 = 4; #[pyclass] #[derive(Clone, PartialEq, Eq)] pub struct Value { - record_value: log_db::Value, + record_value: autere_db::Value, } #[pymethods] impl Value { fn __repr__(&self) -> String { match &self.record_value { - log_db::Value::Int(value) => format!("Value.int({})", value), - log_db::Value::Decimal(value) => format!("Value.decimal({})", value), - log_db::Value::String(value) => { + autere_db::Value::Int(value) => format!("Value.int({})", value), + autere_db::Value::Decimal(value) => format!("Value.decimal({})", value), + autere_db::Value::String(value) => { format!("Value.string(\"{}\")", value.replace("\"", "\\\"")) } - log_db::Value::Bytes(value) => format!("Value.bytes({:?})", value), - log_db::Value::Null => "Value.null()".to_string(), + autere_db::Value::Bytes(value) => format!("Value.bytes({:?})", value), + autere_db::Value::Null => "Value.null()".to_string(), } } #[staticmethod] fn int(value: i64) -> Self { Value { - record_value: log_db::Value::Int(value), + record_value: autere_db::Value::Int(value), } } #[staticmethod] fn decimal(value: String) -> Self { Value { - record_value: log_db::Value::Decimal( + record_value: autere_db::Value::Decimal( Decimal::from_str(&value).expect(&format!("Invalid Decimal: {}", value)), ), } @@ -206,65 +206,65 @@ impl Value { #[staticmethod] fn string(value: String) -> Self { Value { - record_value: log_db::Value::String(value), + record_value: autere_db::Value::String(value), } } #[staticmethod] fn bytes(value: &[u8]) -> Self { Value { - record_value: log_db::Value::Bytes(value.to_vec()), + record_value: autere_db::Value::Bytes(value.to_vec()), } } #[staticmethod] fn null() -> Self { Value { - record_value: log_db::Value::Null, + record_value: autere_db::Value::Null, } } pub fn kind(&self) -> u8 { match &self.record_value { - log_db::Value::Int(_) => VALUE_INT, - log_db::Value::Decimal(_) => VALUE_DECIMAL, - log_db::Value::String(_) => VALUE_STRING, - log_db::Value::Bytes(_) => VALUE_BYTES, - log_db::Value::Null => VALUE_NULL, + autere_db::Value::Int(_) => VALUE_INT, + autere_db::Value::Decimal(_) => VALUE_DECIMAL, + autere_db::Value::String(_) => VALUE_STRING, + autere_db::Value::Bytes(_) => VALUE_BYTES, + autere_db::Value::Null => VALUE_NULL, } } pub fn as_int(&self) -> PyResult<i64> { match &self.record_value { - log_db::Value::Int(value) => Ok(*value), + autere_db::Value::Int(value) => Ok(*value), _ => Err(PyException::new_err("Value is not an Int")), } } pub fn as_decimal(&self) -> PyResult<String> { match &self.record_value { - log_db::Value::Decimal(value) => Ok(value.to_string()), + autere_db::Value::Decimal(value) => Ok(value.to_string()), _ => Err(PyException::new_err("Value is not a Decimal")), } } pub fn as_string(&self) -> PyResult<String> { match &self.record_value { - log_db::Value::String(value) => Ok(value.clone()), + autere_db::Value::String(value) => Ok(value.clone()), _ => Err(PyException::new_err("Value is not a String")), } } pub fn as_bytes(&self) -> PyResult<Vec<u8>> { match &self.record_value { - log_db::Value::Bytes(value) => Ok(value.clone()), + autere_db::Value::Bytes(value) => Ok(value.clone()), _ => Err(PyException::new_err("Value is not Bytes")), } } pub fn as_null(&self) -> PyResult<()> { match &self.record_value { - log_db::Value::Null => Ok(()), + autere_db::Value::Null => Ok(()), _ => Err(PyException::new_err("Value is not Null")), } } @@ -272,7 +272,7 @@ impl Value { #[pyclass] struct DB { - db: log_db::DB, + db: autere_db::DB, } #[pymethods] @@ -349,7 +349,7 @@ impl DB { limit, sort_asc, }; - let keys: Vec<log_db::Value> = keys.into_iter().map(|key| key.record_value).collect(); + let keys: Vec<autere_db::Value> = keys.into_iter().map(|key| key.record_value).collect(); let recs = self .db .batch_find_by_with_params(&field, &keys, ¶ms) @@ -480,7 +480,7 @@ impl PyRangeBound { } } -#[pymodule(name = "log_db")] +#[pymodule(name = "autere_db")] fn log_db_py(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::<DB>()?; m.add_class::<Value>()?; |
