store: read nodes via index instead of HashMap
- Add get_node() and contains_key() methods that read via redb index - Migrate all store/ reads to use index lookup - Remove HashMap cache updates from mutations (write-through to capnp+index only) - Remove replay_nodes() - load no longer builds HashMap - Update db_is_healthy to validate by spot-checking offsets - Fix set_weight bug: now persists weight changes to capnp Store.nodes HashMap still exists for code outside store/ module, but store/ itself no longer uses it. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
ba53597cf2
commit
7eb86656d4
4 changed files with 167 additions and 112 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// Read-only access abstraction for the memory store
|
||||
|
||||
use super::types::*;
|
||||
use super::{capnp, index, types::*};
|
||||
use super::Store;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -19,21 +19,42 @@ pub trait StoreView {
|
|||
|
||||
/// Node weight by key, or the default weight if missing.
|
||||
fn node_weight(&self, key: &str) -> f64;
|
||||
|
||||
/// Node content by key.
|
||||
fn node_content(&self, key: &str) -> Option<&str>;
|
||||
}
|
||||
|
||||
impl StoreView for Store {
|
||||
fn for_each_node<F: FnMut(&str, &str, f32)>(&self, mut f: F) {
|
||||
for (key, node) in &self.nodes {
|
||||
f(key, &node.content, node.weight);
|
||||
let db = match self.db.as_ref() {
|
||||
Some(db) => db,
|
||||
None => return,
|
||||
};
|
||||
let keys = match index::all_keys(db) {
|
||||
Ok(keys) => keys,
|
||||
Err(_) => return,
|
||||
};
|
||||
for key in keys {
|
||||
if let Ok(Some(offset)) = index::get_offset(db, &key) {
|
||||
if let Ok(node) = capnp::read_node_at_offset(offset) {
|
||||
f(&key, &node.content, node.weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn for_each_node_meta<F: FnMut(&str, NodeType, i64)>(&self, mut f: F) {
|
||||
for (key, node) in &self.nodes {
|
||||
f(key, node.node_type, node.timestamp);
|
||||
let db = match self.db.as_ref() {
|
||||
Some(db) => db,
|
||||
None => return,
|
||||
};
|
||||
let keys = match index::all_keys(db) {
|
||||
Ok(keys) => keys,
|
||||
Err(_) => return,
|
||||
};
|
||||
for key in keys {
|
||||
if let Ok(Some(offset)) = index::get_offset(db, &key) {
|
||||
if let Ok(node) = capnp::read_node_at_offset(offset) {
|
||||
f(&key, node.node_type, node.timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,10 +67,10 @@ impl StoreView for Store {
|
|||
|
||||
fn node_weight(&self, key: &str) -> f64 {
|
||||
let cfg = crate::config::get();
|
||||
self.nodes.get(key).map(|n| n.weight as f64).unwrap_or(cfg.default_node_weight)
|
||||
}
|
||||
|
||||
fn node_content(&self, key: &str) -> Option<&str> {
|
||||
self.nodes.get(key).map(|n| n.content.as_str())
|
||||
self.get_node(key)
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|n| n.weight as f64)
|
||||
.unwrap_or(cfg.default_node_weight)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue