From 1b9ab43b6d8a08f0db89768f9a947187e0988200 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Mon, 17 Dec 2018 17:06:14 -0800 Subject: [PATCH] Path and change tracking working --- server/src/rbx_session.rs | 56 ++++++++++++++++++++------------------ server/src/rbx_snapshot.rs | 45 ++++++++++++++++++++++++------ server/src/web.rs | 4 +-- 3 files changed, 66 insertions(+), 39 deletions(-) diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs index 3c306064..e1a0df67 100644 --- a/server/src/rbx_session.rs +++ b/server/src/rbx_session.rs @@ -18,8 +18,7 @@ use crate::{ pub struct RbxSession { tree: RbxTree, - paths_to_node_ids: PathMap, - ids_to_project_paths: HashMap, + path_map: PathMap, message_queue: Arc>, imfs: Arc>, project: Arc, @@ -31,19 +30,16 @@ impl RbxSession { imfs: Arc>, message_queue: Arc>, ) -> RbxSession { + let mut path_map = PathMap::new(); + let tree = { let temp_imfs = imfs.lock().unwrap(); - construct_initial_tree(&project, &temp_imfs) + construct_initial_tree(&project, &temp_imfs, &mut path_map) }; - // TODO: Restore these? - let paths_to_node_ids = PathMap::new(); - let ids_to_project_paths = HashMap::new(); - RbxSession { tree, - paths_to_node_ids, - ids_to_project_paths, + path_map, message_queue, imfs, project, @@ -51,18 +47,25 @@ impl RbxSession { } fn path_created_or_updated(&mut self, path: &Path) { - let imfs = self.imfs.lock().unwrap(); - let root_path = imfs.get_root_for_path(path) - .expect("Path was outside in-memory filesystem roots"); - - let closest_path = self.paths_to_node_ids.descend(root_path, path); - let &instance_id = self.paths_to_node_ids.get(&closest_path).unwrap(); - - let snapshot = snapshot_instances_from_imfs(&imfs, &closest_path) - .expect("Could not generate instance snapshot"); - let mut changes = InstanceChanges::default(); - reconcile_subtree(&mut self.tree, instance_id, &snapshot, &mut changes); + + { + let imfs = self.imfs.lock().unwrap(); + let root_path = imfs.get_root_for_path(path) + .expect("Path was outside in-memory filesystem roots"); + + let closest_path = self.path_map.descend(root_path, path); + let &instance_id = self.path_map.get(&closest_path).unwrap(); + + let snapshot = snapshot_instances_from_imfs(&imfs, &closest_path) + .expect("Could not generate instance snapshot"); + + reconcile_subtree(&mut self.tree, instance_id, &snapshot, &mut self.path_map, &mut changes); + } + + if !changes.is_empty() { + self.message_queue.push_messages(&[changes]); + } } pub fn path_created(&mut self, path: &Path) { @@ -90,7 +93,7 @@ impl RbxSession { pub fn path_removed(&mut self, path: &Path) { info!("Path removed: {}", path.display()); - let instance_id = match self.paths_to_node_ids.remove(path) { + let instance_id = match self.path_map.remove(path) { Some(id) => id, None => return, }; @@ -121,19 +124,17 @@ impl RbxSession { pub fn get_tree(&self) -> &RbxTree { &self.tree } - - pub fn get_project_path_map(&self) -> &HashMap { - &self.ids_to_project_paths - } } pub fn construct_oneoff_tree(project: &Project, imfs: &Imfs) -> RbxTree { - construct_initial_tree(project, imfs) + let mut path_map = PathMap::new(); + construct_initial_tree(project, imfs, &mut path_map) } fn construct_initial_tree( project: &Project, imfs: &Imfs, + path_map: &mut PathMap, ) -> RbxTree { let snapshot = construct_project_node( imfs, @@ -142,8 +143,9 @@ fn construct_initial_tree( ); let mut changes = InstanceChanges::default(); + let tree = reify_root(&snapshot, path_map, &mut changes); - reify_root(&snapshot, &mut changes) + tree } fn construct_project_node<'a>( diff --git a/server/src/rbx_snapshot.rs b/server/src/rbx_snapshot.rs index 45320990..f81161d7 100644 --- a/server/src/rbx_snapshot.rs +++ b/server/src/rbx_snapshot.rs @@ -7,6 +7,8 @@ use std::{ use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue}; +use crate::path_map::PathMap; + #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct InstanceChanges { pub added: HashSet, @@ -28,37 +30,61 @@ pub struct RbxSnapshotInstance<'a> { pub source_path: Option, } -pub fn reify_root(snapshot: &RbxSnapshotInstance, changes: &mut InstanceChanges) -> RbxTree { +pub fn reify_root( + snapshot: &RbxSnapshotInstance, + path_map: &mut PathMap, + changes: &mut InstanceChanges, +) -> RbxTree { let instance = reify_core(snapshot); let mut tree = RbxTree::new(instance); let root_id = tree.get_root_id(); + if let Some(source_path) = &snapshot.source_path { + path_map.insert(source_path.clone(), root_id); + } + changes.added.insert(root_id); for child in &snapshot.children { - reify_subtree(child, &mut tree, root_id, changes); + reify_subtree(child, &mut tree, root_id, path_map, changes); } tree } -pub fn reify_subtree(snapshot: &RbxSnapshotInstance, tree: &mut RbxTree, parent_id: RbxId, changes: &mut InstanceChanges) { +pub fn reify_subtree( + snapshot: &RbxSnapshotInstance, + tree: &mut RbxTree, + parent_id: RbxId, + path_map: &mut PathMap, + changes: &mut InstanceChanges, +) { let instance = reify_core(snapshot); let id = tree.insert_instance(instance, parent_id); + if let Some(source_path) = &snapshot.source_path { + path_map.insert(source_path.clone(), id); + } + changes.added.insert(id); for child in &snapshot.children { - reify_subtree(child, tree, id, changes); + reify_subtree(child, tree, id, path_map, changes); } } -pub fn reconcile_subtree(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance, changes: &mut InstanceChanges) { +pub fn reconcile_subtree( + tree: &mut RbxTree, + id: RbxId, + snapshot: &RbxSnapshotInstance, + path_map: &mut PathMap, + changes: &mut InstanceChanges, +) { if reconcile_instance_properties(tree.get_instance_mut(id).unwrap(), snapshot) { changes.updated.insert(id); } - reconcile_instance_children(tree, id, snapshot, changes); + reconcile_instance_children(tree, id, snapshot, path_map, changes); } fn reify_core(snapshot: &RbxSnapshotInstance) -> RbxInstance { @@ -138,7 +164,8 @@ fn reconcile_instance_children( tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance, - changes: &mut InstanceChanges + path_map: &mut PathMap, + changes: &mut InstanceChanges, ) { let children_ids = tree.get_instance(id).unwrap().get_children_ids().to_vec(); let child_count = children_ids.len().max(snapshot.children.len()); @@ -168,7 +195,7 @@ fn reconcile_instance_children( } for child_snapshot in &children_to_add { - reify_subtree(child_snapshot, tree, id, changes); + reify_subtree(child_snapshot, tree, id, path_map, changes); } for child_id in &children_to_remove { @@ -180,6 +207,6 @@ fn reconcile_instance_children( } for (child_id, child_snapshot) in &children_to_update { - reconcile_subtree(tree, *child_id, child_snapshot, changes); + reconcile_subtree(tree, *child_id, child_snapshot, path_map, changes); } } \ No newline at end of file diff --git a/server/src/web.rs b/server/src/web.rs index 6a7e02d6..d1974bed 100644 --- a/server/src/web.rs +++ b/server/src/web.rs @@ -27,7 +27,6 @@ pub struct ServerInfoResponse<'a> { pub protocol_version: u64, pub root_instance_id: RbxId, pub project: Cow<'a, Project>, - pub ids_to_project_paths: Cow<'a, HashMap>, } #[derive(Debug, Serialize, Deserialize)] @@ -80,7 +79,6 @@ impl Server { session_id: self.session.session_id, root_instance_id: tree.get_root_id(), project: Cow::Borrowed(&self.session.project), - ids_to_project_paths: Cow::Borrowed(rbx_session.get_project_path_map()), }) }, @@ -97,7 +95,7 @@ impl Server { if !new_messages.is_empty() { return Response::json(&SubscribeResponse { session_id: self.session.session_id, - messages: Cow::Borrowed(&[]), + messages: Cow::Borrowed(&new_messages), message_cursor: new_cursor, }) }