forked from kent/consciousness
store: add weight to index, index-only key matching
- 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>
This commit is contained in:
parent
fc978e2f2e
commit
ba4e01b6f3
9 changed files with 776 additions and 502 deletions
105
src/bin/dump-table.rs
Normal file
105
src/bin/dump-table.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue