فهرست منبع

fix Dirty Nodes for large NodeIds

Evan Almloff 2 سال پیش
والد
کامیت
e4cb8c3aa0
2فایلهای تغییر یافته به همراه9 افزوده شده و 26 حذف شده
  1. 7 24
      packages/native-core/src/passes.rs
  2. 2 2
      packages/native-core/src/tree.rs

+ 7 - 24
packages/native-core/src/passes.rs

@@ -16,34 +16,20 @@ use crate::{NodeId, NodeMask};
 
 #[derive(Default)]
 struct DirtyNodes {
-    passes_dirty: Vec<u64>,
+    nodes_dirty: Vec<NodeId>,
 }
 
 impl DirtyNodes {
     pub fn add_node(&mut self, node_id: NodeId) {
-        let node_id = node_id.uindex();
-        let index = node_id / 64;
-        let bit = node_id % 64;
-        let encoded = 1 << bit;
-        if let Some(passes) = self.passes_dirty.get_mut(index) {
-            *passes |= encoded;
-        } else {
-            self.passes_dirty.resize(index + 1, 0);
-            self.passes_dirty[index] |= encoded;
-        }
+        self.nodes_dirty.push(node_id);
     }
 
     pub fn is_empty(&self) -> bool {
-        self.passes_dirty.iter().all(|dirty| *dirty == 0)
+        self.nodes_dirty.is_empty()
     }
 
-    pub fn pop(&mut self) -> Option<usize> {
-        let index = self.passes_dirty.iter().position(|dirty| *dirty != 0)?;
-        let passes = self.passes_dirty[index];
-        let node_id = passes.trailing_zeros();
-        let encoded = 1 << node_id;
-        self.passes_dirty[index] &= !encoded;
-        Some((index * 64) + node_id as usize)
+    pub fn pop(&mut self) -> Option<NodeId> {
+        self.nodes_dirty.pop()
     }
 }
 
@@ -76,7 +62,7 @@ impl DirtyNodeStates {
         }
     }
 
-    fn pop_front(&self, pass_id: TypeId) -> Option<(u16, usize)> {
+    fn pop_front(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
         let mut values = self.dirty.get(&pass_id)?.write();
         let mut value = values.first_entry()?;
         let height = *value.key();
@@ -89,7 +75,7 @@ impl DirtyNodeStates {
         Some((height, id))
     }
 
-    fn pop_back(&self, pass_id: TypeId) -> Option<(u16, usize)> {
+    fn pop_back(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
         let mut values = self.dirty.get(&pass_id)?.write();
         let mut value = values.last_entry()?;
         let height = *value.key();
@@ -214,7 +200,6 @@ pub fn run_pass<V: FromAnyValue + Send + Sync>(
     match pass_direction {
         PassDirection::ParentToChild => {
             while let Some((height, id)) = dirty.pop_front(type_id) {
-                let id = tree.id_at(id).unwrap();
                 if (update_node)(id, ctx) {
                     nodes_updated.insert(id);
                     for id in tree.children_ids(id) {
@@ -227,7 +212,6 @@ pub fn run_pass<V: FromAnyValue + Send + Sync>(
         }
         PassDirection::ChildToParent => {
             while let Some((height, id)) = dirty.pop_back(type_id) {
-                let id = tree.id_at(id).unwrap();
                 if (update_node)(id, ctx) {
                     nodes_updated.insert(id);
                     if let Some(id) = tree.parent_id(id) {
@@ -240,7 +224,6 @@ pub fn run_pass<V: FromAnyValue + Send + Sync>(
         }
         PassDirection::AnyOrder => {
             while let Some((height, id)) = dirty.pop_back(type_id) {
-                let id = tree.id_at(id).unwrap();
                 if (update_node)(id, ctx) {
                     nodes_updated.insert(id);
                     for dependant in &dependants {

+ 2 - 2
packages/native-core/src/tree.rs

@@ -49,7 +49,7 @@ pub trait TreeMut: TreeRef {
 
 impl<'a> TreeRef for TreeRefView<'a> {
     fn parent_id(&self, id: NodeId) -> Option<NodeId> {
-        self.get(id).unwrap().parent
+        self.get(id).ok()?.parent
     }
 
     fn children_ids(&self, id: NodeId) -> Vec<NodeId> {
@@ -59,7 +59,7 @@ impl<'a> TreeRef for TreeRefView<'a> {
     }
 
     fn height(&self, id: NodeId) -> Option<u16> {
-        Some(self.get(id).unwrap().height)
+        Some(self.get(id).ok()?.height)
     }
 
     fn contains(&self, id: NodeId) -> bool {