In lmdb and mdbx implementations there is a concept of an environment. An environment supports multiple databases, all residing in the same shared-memory map. For redb, no such concept exists
I think we want to create an Environment struct for our redb implementation (see code snippets below)
For now we created an Environment struct thats simply a wrapper around redb::Builder
(the redb Builder allows us to create/open databases.)
pub struct Environment {
builder: redb::Builder,
}
impl Environment {
pub fn new(config: &Config) -> Result<Environment, Error> {
let builder = redb::Builder::new();
Ok(Environment { builder })
}
pub fn create_databases(&self) -> Result<OpenDatabases, Error> {
let indexed_attestation_db = self.builder.create(INDEXED_ATTESTATION_DB).unwrap();
let indexed_attestation_id_db = self.builder.create(INDEXED_ATTESTATION_ID_DB).unwrap();
let attesters_db = self.builder.create(ATTESTERS_DB).unwrap();
let attesters_max_targets_db = self.builder.create(ATTESTERS_MAX_TARGETS_DB).unwrap();
let min_targets_db = self.builder.create(MIN_TARGETS_DB).unwrap();
let max_targets_db = self.builder.create(MAX_TARGETS_DB).unwrap();
let current_epochs_db = self.builder.create(CURRENT_EPOCHS_DB).unwrap();
let proposers_db = self.builder.create(PROPOSERS_DB).unwrap();
let metadata_db = self.builder.create(METADATA_DB).unwrap();
let wrap = |db| {
crate::Database::Redb(Database {
db,
_phantom: PhantomData,
})
};
Ok(OpenDatabases {
indexed_attestation_db: wrap(indexed_attestation_db),
indexed_attestation_id_db: wrap(indexed_attestation_id_db),
attesters_db: wrap(attesters_db),
attesters_max_targets_db: wrap(attesters_max_targets_db),
min_targets_db: wrap(min_targets_db),
max_targets_db: wrap(max_targets_db),
current_epochs_db: wrap(current_epochs_db),
proposers_db: wrap(proposers_db),
metadata_db: wrap(metadata_db),
})
}
pub fn begin_rw_txn(&self) -> Result<RwTransaction, Error> {
todo!()
}
pub fn filenames(&self, config: &Config) -> Vec<PathBuf> {
vec![
config.database_path.join("data.mdb"),
config.database_path.join("lock.mdb"),
]
}
The cursor is another tricky issue. The cursor in the other db implementations allows for searching. There is no such concept in redb. For example, the cursor in other db implementations allows for fetching the first key in the db, or the last key. There might be a trick to doing this in redb, not sure if this is the best idea though…
Pretty much we begin a write transaction so we can use the pop_first method to port the first key in the table. We then abort the txn so we dont actually write to the db and someohow return the key value… Seems hacky
pub struct Cursor<'env> {
db: redb::Database,
_phantom: PhantomData<&'env ()>,
}
impl<'env> Cursor<'env> {
pub fn first_key(&mut self) {
let table_definition: TableDefinition<u64, u64> = TableDefinition::new("example");
let txn = self.db.begin_write().unwrap();
{
let mut table = txn.open_table(table_definition).unwrap();
let first_key = table.pop_first().unwrap();
}
txn.abort();
}
}
Readwrite transactions in redb may be simple to deal with. In redb there is a concept of database tables. However in lmdb there is no conecept of tables. We can assume each database only consists of one table. We may then be able to do something like
const TABLE: TableDefinition<u8, u8> = TableDefinition::new("data");
impl<'db> RwTransaction<'db> {
pub fn get<K: std::borrow::Borrow<u8>>(
&'db self,
db: &Database<'db>,
key: &K,
) {
let tx = db.db.begin_read().unwrap();
let table = tx.open_table(TABLE).unwrap();
table.get(*key.clone());
}
}
Symas LMDB (Lightning Memory-Mapped Database) does not use traditional database tables like those found in relational database systems. LMDB is a key-value store, where data is stored in a hierarchical key-value structure without the concept of tables.
In LMDB, the data is organized in a tree-like structure known as a database environment. Within the environment, multiple databases can be created, each identified by a unique name. The key-value pairs are stored within these databases.
Think of the databases in LMDB as analogous to namespaces or containers that hold key-value pairs. You can create separate databases within the LMDB environment to logically group related data or for different purposes.
It's worth noting that LMDB's design focuses on providing high-performance, low-latency, and efficient key-value storage. It excels in scenarios where you need to handle large amounts of data with high concurrency and minimal resource usage.
If you're coming from a relational database background, it's important to understand that LMDB has a different data model and doesn't directly support tables, SQL queries, or relational features.
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing