Store document node inputs in Arc to reduce memory consumption (#3086)

Store values in memo hash contanier in arc
This commit is contained in:
Dennis Kobert 2025-08-23 17:24:41 +02:00 committed by GitHub
parent 469f0a6c30
commit 354bf93364
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 11 additions and 9 deletions

View File

@ -25,6 +25,7 @@ use kurbo::BezPath;
use serde_json::{Value, json};
use std::collections::{HashMap, HashSet, VecDeque};
use std::hash::{DefaultHasher, Hash, Hasher};
use std::ops::Deref;
/// All network modifications should be done through this API, so the fields cannot be public. However, all fields within this struct can be public since it it not possible to have a public mutable reference.
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
@ -1281,7 +1282,7 @@ impl NodeNetworkInterface {
let artboard = self.document_node(&artboard_node_identifier.to_node(), &[]);
let clip_input = artboard.unwrap().inputs.get(5).unwrap();
if let NodeInput::Value { tagged_value, .. } = clip_input {
if tagged_value.clone().into_inner() == TaggedValue::Bool(true) {
if tagged_value.clone().deref() == &TaggedValue::Bool(true) {
return Some(Quad::clip(
self.document_metadata.bounding_box_document(layer).unwrap_or_default(),
self.document_metadata.bounding_box_document(artboard_node_identifier).unwrap_or_default(),

View File

@ -156,10 +156,10 @@ pub mod monitor {
pub const IDENTIFIER: crate::ProtoNodeIdentifier = crate::ProtoNodeIdentifier::new("graphene_core::memo::MonitorNode");
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct MemoHash<T: Hash> {
hash: u64,
value: T,
value: Arc<T>,
}
impl<'de, T: serde::Deserialize<'de> + Hash> serde::Deserialize<'de> for MemoHash<T> {
@ -183,10 +183,10 @@ impl<T: Hash + serde::Serialize> serde::Serialize for MemoHash<T> {
impl<T: Hash> MemoHash<T> {
pub fn new(value: T) -> Self {
let hash = Self::calc_hash(&value);
Self { hash, value }
Self { hash, value: value.into() }
}
pub fn new_with_hash(value: T, hash: u64) -> Self {
Self { hash, value }
Self { hash, value: value.into() }
}
fn calc_hash(data: &T) -> u64 {
@ -198,7 +198,7 @@ impl<T: Hash> MemoHash<T> {
pub fn inner_mut(&mut self) -> MemoHashGuard<'_, T> {
MemoHashGuard { inner: self }
}
pub fn into_inner(self) -> T {
pub fn into_inner(self) -> Arc<T> {
self.value
}
pub fn hash_code(&self) -> u64 {
@ -244,8 +244,8 @@ impl<T: Hash> Deref for MemoHashGuard<'_, T> {
}
}
impl<T: Hash> std::ops::DerefMut for MemoHashGuard<'_, T> {
impl<T: Hash + Clone> std::ops::DerefMut for MemoHashGuard<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner.value
Arc::make_mut(&mut self.inner.value)
}
}

View File

@ -392,7 +392,8 @@ impl<'input> Node<'input, DAny<'input>> for UpcastNode {
type Output = FutureAny<'input>;
fn eval(&'input self, _: DAny<'input>) -> Self::Output {
Box::pin(async move { self.value.clone().into_inner().to_dynany() })
let memo_clone = MemoHash::clone(&self.value);
Box::pin(async move { memo_clone.into_inner().as_ref().clone().to_dynany() })
}
}
impl UpcastNode {