herodb/instructions/redb.md
2025-08-16 06:58:04 +02:00

2.4 KiB
Raw Blame History

======================== CODE SNIPPETS

TITLE: 1PC+C Commit Strategy Vulnerability Example DESCRIPTION: Illustrates a scenario where a partially committed transaction might appear complete due to the non-cryptographic checksum (XXH3) used in the 1PC+C commit strategy. This requires controlling page flush order, introducing a crash during fsync, and ensuring valid checksums for partially written data.

SOURCE: https://github.com/cberner/redb/blob/master/docs/design.md#_snippet_9

LANGUAGE: rust CODE:

table.insert(malicious_key, malicious_value);
table.insert(good_key, good_value);
txn.commit();

LANGUAGE: rust CODE:

table.insert(malicious_key, malicious_value);
txn.commit();

TITLE: Basic Key-Value Operations in redb DESCRIPTION: Demonstrates the fundamental usage of redb for creating a database, opening a table, inserting a key-value pair, and retrieving the value within separate read and write transactions.

SOURCE: https://github.com/cberner/redb/blob/master/README.md#_snippet_0

LANGUAGE: rust CODE:

use redb::{Database, Error, ReadableTable, TableDefinition};

const TABLE: TableDefinition<&str, u64> = TableDefinition::new("my_data");

fn main() -> Result<(), Error> {
    let db = Database::create("my_db.redb")?;
    let write_txn = db.begin_write()?;
    {
        let mut table = write_txn.open_table(TABLE)?;
        table.insert("my_key", &123)?;
    }
    write_txn.commit()?;

    let read_txn = db.begin_read()?;
    let table = read_txn.open_table(TABLE)?;
    assert_eq!(table.get("my_key")?.unwrap().value(), 123);

    Ok(())
}

What redb currently supports:

  • Simple operations like creating databases, inserting key-value pairs, opening and reading tables ([GitHub][1]).

  • No mention of operations such as:

    • Iterating over keys with a given prefix.
    • Range queries based on string prefixes.
    • Specialized prefixfiltered lookups.

implement range scans as follows

You can implement prefix-like functionality using range scans combined with manual checks, similar to using a BTreeSet in Rust:

for key in table.range(prefix..).keys() {
    if !key.starts_with(prefix) {
        break;
    }
    // process key
}

This pattern iterates keys starting at the prefix, and stops once a key no longer matches the prefix—this works because the keys are sorted ([GitHub][1]).