forked from kent/consciousness
- KEY_TO_UUID now stores weight (30 bytes: uuid+type+ts+deleted+weight) - UUID_OFFSETS changed to composite key for O(log n) max-offset lookup - Add NODES_BY_TYPE index for efficient type+date range queries - Add for_each_key_weight() to StoreView for index-only iteration - match_seeds uses index-only path when content not needed - Fix transaction consistency in ops (single txn for related updates) - rebuild() now records all uuid→offset mappings for version history - Backwards compatible: old index formats decoded with default weight Co-Authored-By: Proof of Concept <poc@bcachefs.org> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
105 lines
4.5 KiB
Rust
105 lines
4.5 KiB
Rust
// Dump a redb table in text form
|
|
// Usage: dump-table <table-name>
|
|
// Tables: key_to_uuid, uuid_offsets, nodes_by_provenance, nodes_by_type, rels
|
|
|
|
use consciousness::store::{
|
|
memory_dir,
|
|
KEY_TO_UUID, UUID_OFFSETS, NODES_BY_PROVENANCE, NODES_BY_TYPE, RELS,
|
|
unpack_node_meta, unpack_provenance_value, unpack_rel,
|
|
};
|
|
use redb::{Database, ReadableDatabase, ReadableTable, ReadableMultimapTable};
|
|
|
|
fn format_uuid(uuid: &[u8; 16]) -> String {
|
|
format!("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
|
|
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
|
|
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15])
|
|
}
|
|
|
|
fn main() {
|
|
let args: Vec<String> = std::env::args().collect();
|
|
if args.len() != 2 {
|
|
eprintln!("usage: dump-table <table-name>");
|
|
eprintln!("tables: key_to_uuid, uuid_offsets, nodes_by_provenance, nodes_by_type, rels");
|
|
std::process::exit(1);
|
|
}
|
|
let table_name = &args[1];
|
|
|
|
let db_path = memory_dir().join("index.redb");
|
|
let db = Database::open(&db_path).expect("open db");
|
|
let txn = db.begin_read().expect("begin read");
|
|
|
|
match table_name.as_str() {
|
|
"key_to_uuid" => {
|
|
let table = txn.open_table(KEY_TO_UUID).expect("open");
|
|
for entry in table.iter().expect("iter") {
|
|
let (key, data) = entry.expect("entry");
|
|
let (uuid, node_type, ts, deleted, weight) = unpack_node_meta(data.value());
|
|
println!("{}\t{}\ttype={}\tts={}\tdel={}\tw={:.3}", key.value(), format_uuid(&uuid), node_type, ts, deleted, weight);
|
|
}
|
|
}
|
|
"uuid_offsets" => {
|
|
// Key: [uuid:16][offset:8 BE], Value: ()
|
|
let table = txn.open_table(UUID_OFFSETS).expect("open");
|
|
for entry in table.iter().expect("iter") {
|
|
let (key_bytes, _) = entry.expect("entry");
|
|
let key = key_bytes.value();
|
|
if key.len() >= 24 {
|
|
let mut uuid = [0u8; 16];
|
|
uuid.copy_from_slice(&key[0..16]);
|
|
let offset = u64::from_be_bytes([
|
|
key[16], key[17], key[18], key[19],
|
|
key[20], key[21], key[22], key[23],
|
|
]);
|
|
println!("{}\t{}", format_uuid(&uuid), offset);
|
|
}
|
|
}
|
|
}
|
|
"nodes_by_provenance" => {
|
|
let table = txn.open_multimap_table(NODES_BY_PROVENANCE).expect("open");
|
|
for entry in table.iter().expect("iter") {
|
|
let (prov, values) = entry.expect("entry");
|
|
for val in values {
|
|
let (ts, uuid) = unpack_provenance_value(val.expect("val").value());
|
|
println!("{}\t{}\t{}", prov.value(), ts, format_uuid(&uuid));
|
|
}
|
|
}
|
|
}
|
|
"nodes_by_type" => {
|
|
// Key: [type:1][neg_timestamp:8], Value: uuid
|
|
let table = txn.open_table(NODES_BY_TYPE).expect("open");
|
|
for entry in table.iter().expect("iter") {
|
|
let (key_bytes, uuid_bytes) = entry.expect("entry");
|
|
let key = key_bytes.value();
|
|
let node_type = key[0];
|
|
let neg_ts = i64::from_be_bytes([key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8]]);
|
|
let ts = !neg_ts;
|
|
let mut uuid = [0u8; 16];
|
|
uuid.copy_from_slice(uuid_bytes.value());
|
|
println!("type={}\tts={}\t{}", node_type, ts, format_uuid(&uuid));
|
|
}
|
|
}
|
|
"rels" => {
|
|
let table = txn.open_multimap_table(RELS).expect("open");
|
|
for entry in table.iter().expect("iter") {
|
|
let (uuid_bytes, values) = entry.expect("entry");
|
|
let uuid = uuid_bytes.value();
|
|
let uuid_str = if uuid.len() >= 16 {
|
|
let mut arr = [0u8; 16];
|
|
arr.copy_from_slice(&uuid[..16]);
|
|
format_uuid(&arr)
|
|
} else {
|
|
format!("{:02x?}", uuid)
|
|
};
|
|
for val in values {
|
|
let (other, strength, rel_type, is_out) = unpack_rel(val.expect("val").value());
|
|
println!("{}\t{}\tstr={:.3}\ttype={}\tout={}",
|
|
uuid_str, format_uuid(&other), strength, rel_type, is_out);
|
|
}
|
|
}
|
|
}
|
|
_ => {
|
|
eprintln!("unknown table: {}", table_name);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|