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 serde_json::{Value, json};
use std::collections::{HashMap, HashSet, VecDeque}; use std::collections::{HashMap, HashSet, VecDeque};
use std::hash::{DefaultHasher, Hash, Hasher}; 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. /// 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)] #[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
@ -1281,7 +1282,7 @@ impl NodeNetworkInterface {
let artboard = self.document_node(&artboard_node_identifier.to_node(), &[]); let artboard = self.document_node(&artboard_node_identifier.to_node(), &[]);
let clip_input = artboard.unwrap().inputs.get(5).unwrap(); let clip_input = artboard.unwrap().inputs.get(5).unwrap();
if let NodeInput::Value { tagged_value, .. } = clip_input { 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( return Some(Quad::clip(
self.document_metadata.bounding_box_document(layer).unwrap_or_default(), self.document_metadata.bounding_box_document(layer).unwrap_or_default(),
self.document_metadata.bounding_box_document(artboard_node_identifier).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"); 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> { pub struct MemoHash<T: Hash> {
hash: u64, hash: u64,
value: T, value: Arc<T>,
} }
impl<'de, T: serde::Deserialize<'de> + Hash> serde::Deserialize<'de> for MemoHash<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> { impl<T: Hash> MemoHash<T> {
pub fn new(value: T) -> Self { pub fn new(value: T) -> Self {
let hash = Self::calc_hash(&value); let hash = Self::calc_hash(&value);
Self { hash, value } Self { hash, value: value.into() }
} }
pub fn new_with_hash(value: T, hash: u64) -> Self { pub fn new_with_hash(value: T, hash: u64) -> Self {
Self { hash, value } Self { hash, value: value.into() }
} }
fn calc_hash(data: &T) -> u64 { fn calc_hash(data: &T) -> u64 {
@ -198,7 +198,7 @@ impl<T: Hash> MemoHash<T> {
pub fn inner_mut(&mut self) -> MemoHashGuard<'_, T> { pub fn inner_mut(&mut self) -> MemoHashGuard<'_, T> {
MemoHashGuard { inner: self } MemoHashGuard { inner: self }
} }
pub fn into_inner(self) -> T { pub fn into_inner(self) -> Arc<T> {
self.value self.value
} }
pub fn hash_code(&self) -> u64 { 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 { 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>; type Output = FutureAny<'input>;
fn eval(&'input self, _: DAny<'input>) -> Self::Output { 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 { impl UpcastNode {