I'm building a computation graph in Rust and I'm struggling with storing the cached results in the graph.
Imagine I have a computation node like this:
struct Node {
id: u32,
input_count: usize, // How many inputs this node takes
type_: String, // e.g. "+" for an add node.
value: f32, // for nodes that store their value in the node itself, e.g. value nodes
}
This is stored in a network like this:
struct Network {
nodes: Vec<Node>,
connections: Vec<Connection>,
results: HashMap<u32, f32>, // computed results
}
A Connection just stores the id's:
struct Connection {
output_id: u32,
input_id: u32,
input_index: u32,
}
I have "value" nodes that store a single value (0 inputs), and "add" nodes that add two inputs together. Here's an example graph:
I'm struggling with the process_node
function in my Network, which looks like this:
fn process_node(&mut self, id: u32) -> f32 {
// Check if the result was already calculated and return it.
if let Some(cached_result) = self.results.get(&id) {
return *cached_result;
}
// Find all dependencies of the node to be processed.
let mut dependencies = Vec::new();
for connection in self.connections.iter() {
if connection.input_id == id {
dependencies.push((connection.output_id, connection.input_index));
}
}
// Calculate all inputs for this node by processing its dependencies.
let node = self.get_node(id).unwrap();
let mut inputs = vec![0.0; node.input_count];
for (output_id, input_index) in dependencies {
// let node = self.get_node(output_id).unwrap();
let result = self.process_node(output_id);
inputs[input_index as usize] = result;
}
// Process the node itself.
let result = node.process(inputs);
// Store the result in the cache
self.results.insert(id, result);
result
}
At some point it borrows both the node (immutable), and the network graph (mutable) to store the cached results. I can't figure out how to solve this.
Here's a working version without caching (without the mutable borrow):
And here's the non-working version with caching:
Any ideas how I could solve this? My hunch is to store the cached results outside of the network, but I'm wondering if there is another way.