mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-25 15:16:07 +00:00
Fix PatchTree performance issues (#755)
When building the tree, I've implemented a few improvements: - We no longer traverse the full ancestry for every leaf node- we exit early when we find a node that already exists - We no longer search the entire tree to see if a node id exists before creating one with that id, we just check if is in the map
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
* Added better support for `Font` properties ([#731])
|
* Added better support for `Font` properties ([#731])
|
||||||
* Add new plugin template to the `init` command ([#738])
|
* Add new plugin template to the `init` command ([#738])
|
||||||
* Added rich Source diffs in patch visualizer ([#748])
|
* Added rich Source diffs in patch visualizer ([#748])
|
||||||
|
* Fix PatchTree performance issues ([#755])
|
||||||
|
|
||||||
[#745]: https://github.com/rojo-rbx/rojo/pull/745
|
[#745]: https://github.com/rojo-rbx/rojo/pull/745
|
||||||
[#668]: https://github.com/rojo-rbx/rojo/pull/668
|
[#668]: https://github.com/rojo-rbx/rojo/pull/668
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
[#731]: https://github.com/rojo-rbx/rojo/pull/731
|
[#731]: https://github.com/rojo-rbx/rojo/pull/731
|
||||||
[#738]: https://github.com/rojo-rbx/rojo/pull/738
|
[#738]: https://github.com/rojo-rbx/rojo/pull/738
|
||||||
[#748]: https://github.com/rojo-rbx/rojo/pull/748
|
[#748]: https://github.com/rojo-rbx/rojo/pull/748
|
||||||
|
[#755]: https://github.com/rojo-rbx/rojo/pull/755
|
||||||
|
|
||||||
## [7.3.0] - April 22, 2023
|
## [7.3.0] - April 22, 2023
|
||||||
* Added `$attributes` to project format. ([#574])
|
* Added `$attributes` to project format. ([#574])
|
||||||
|
|||||||
@@ -113,6 +113,10 @@ function Tree:getNode(id, searchNode)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Tree:doesNodeExist(id)
|
||||||
|
return self.idToNode[id] ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Adds a node to the tree as a child of the node with id == parent
|
-- Adds a node to the tree as a child of the node with id == parent
|
||||||
-- If parent is nil, it defaults to root
|
-- If parent is nil, it defaults to root
|
||||||
-- props must contain id, and cannot contain children or parentId
|
-- props must contain id, and cannot contain children or parentId
|
||||||
@@ -122,16 +126,16 @@ function Tree:addNode(parent, props)
|
|||||||
|
|
||||||
parent = parent or "ROOT"
|
parent = parent or "ROOT"
|
||||||
|
|
||||||
local node = self:getNode(props.id)
|
if self:doesNodeExist(props.id) then
|
||||||
if node then
|
|
||||||
-- Update existing node
|
-- Update existing node
|
||||||
|
local node = self:getNode(props.id)
|
||||||
for k, v in props do
|
for k, v in props do
|
||||||
node[k] = v
|
node[k] = v
|
||||||
end
|
end
|
||||||
return node
|
return node
|
||||||
end
|
end
|
||||||
|
|
||||||
node = table.clone(props)
|
local node = table.clone(props)
|
||||||
node.children = {}
|
node.children = {}
|
||||||
node.parentId = parent
|
node.parentId = parent
|
||||||
|
|
||||||
@@ -149,9 +153,10 @@ end
|
|||||||
|
|
||||||
-- Given a list of ancestor ids in descending order, builds the nodes for them
|
-- Given a list of ancestor ids in descending order, builds the nodes for them
|
||||||
-- using the patch and instanceMap info
|
-- using the patch and instanceMap info
|
||||||
function Tree:buildAncestryNodes(ancestryIds: { string }, patch, instanceMap)
|
function Tree:buildAncestryNodes(previousId: string?, ancestryIds: { string }, patch, instanceMap)
|
||||||
-- Build nodes for ancestry by going up the tree
|
-- Build nodes for ancestry by going up the tree
|
||||||
local previousId = "ROOT"
|
previousId = previousId or "ROOT"
|
||||||
|
|
||||||
for _, ancestorId in ancestryIds do
|
for _, ancestorId in ancestryIds do
|
||||||
local value = instanceMap.fromIds[ancestorId] or patch.added[ancestorId]
|
local value = instanceMap.fromIds[ancestorId] or patch.added[ancestorId]
|
||||||
if not value then
|
if not value then
|
||||||
@@ -175,6 +180,8 @@ local PatchTree = {}
|
|||||||
function PatchTree.build(patch, instanceMap, changeListHeaders)
|
function PatchTree.build(patch, instanceMap, changeListHeaders)
|
||||||
local tree = Tree.new()
|
local tree = Tree.new()
|
||||||
|
|
||||||
|
local knownAncestors = {}
|
||||||
|
|
||||||
for _, change in patch.updated do
|
for _, change in patch.updated do
|
||||||
local instance = instanceMap.fromIds[change.id]
|
local instance = instanceMap.fromIds[change.id]
|
||||||
if not instance then
|
if not instance then
|
||||||
@@ -185,13 +192,21 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
|||||||
local ancestryIds = {}
|
local ancestryIds = {}
|
||||||
local parentObject = instance.Parent
|
local parentObject = instance.Parent
|
||||||
local parentId = instanceMap.fromInstances[parentObject]
|
local parentId = instanceMap.fromInstances[parentObject]
|
||||||
|
local previousId = nil
|
||||||
while parentObject do
|
while parentObject do
|
||||||
|
if knownAncestors[parentId] then
|
||||||
|
-- We've already added this ancestor
|
||||||
|
previousId = parentId
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
table.insert(ancestryIds, 1, parentId)
|
table.insert(ancestryIds, 1, parentId)
|
||||||
|
knownAncestors[parentId] = true
|
||||||
parentObject = parentObject.Parent
|
parentObject = parentObject.Parent
|
||||||
parentId = instanceMap.fromInstances[parentObject]
|
parentId = instanceMap.fromInstances[parentObject]
|
||||||
end
|
end
|
||||||
|
|
||||||
tree:buildAncestryNodes(ancestryIds, patch, instanceMap)
|
tree:buildAncestryNodes(previousId, ancestryIds, patch, instanceMap)
|
||||||
|
|
||||||
-- Gather detail text
|
-- Gather detail text
|
||||||
local changeList, hint = nil, nil
|
local changeList, hint = nil, nil
|
||||||
@@ -268,14 +283,22 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
|||||||
local ancestryIds = {}
|
local ancestryIds = {}
|
||||||
local parentObject = instance.Parent
|
local parentObject = instance.Parent
|
||||||
local parentId = instanceMap.fromInstances[parentObject] or HttpService:GenerateGUID(false)
|
local parentId = instanceMap.fromInstances[parentObject] or HttpService:GenerateGUID(false)
|
||||||
|
local previousId = nil
|
||||||
while parentObject do
|
while parentObject do
|
||||||
|
if knownAncestors[parentId] then
|
||||||
|
-- We've already added this ancestor
|
||||||
|
previousId = parentId
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
instanceMap:insert(parentId, parentObject) -- This ensures we can find the parent later
|
instanceMap:insert(parentId, parentObject) -- This ensures we can find the parent later
|
||||||
table.insert(ancestryIds, 1, parentId)
|
table.insert(ancestryIds, 1, parentId)
|
||||||
|
knownAncestors[parentId] = true
|
||||||
parentObject = parentObject.Parent
|
parentObject = parentObject.Parent
|
||||||
parentId = instanceMap.fromInstances[parentObject] or HttpService:GenerateGUID(false)
|
parentId = instanceMap.fromInstances[parentObject] or HttpService:GenerateGUID(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
tree:buildAncestryNodes(ancestryIds, patch, instanceMap)
|
tree:buildAncestryNodes(previousId, ancestryIds, patch, instanceMap)
|
||||||
|
|
||||||
-- Add this node to tree
|
-- Add this node to tree
|
||||||
local nodeId = instanceMap.fromInstances[instance] or HttpService:GenerateGUID(false)
|
local nodeId = instanceMap.fromInstances[instance] or HttpService:GenerateGUID(false)
|
||||||
@@ -295,8 +318,16 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
|||||||
local parentId = change.Parent
|
local parentId = change.Parent
|
||||||
local parentData = patch.added[parentId]
|
local parentData = patch.added[parentId]
|
||||||
local parentObject = instanceMap.fromIds[parentId]
|
local parentObject = instanceMap.fromIds[parentId]
|
||||||
|
local previousId = nil
|
||||||
while parentId do
|
while parentId do
|
||||||
|
if knownAncestors[parentId] then
|
||||||
|
-- We've already added this ancestor
|
||||||
|
previousId = parentId
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
table.insert(ancestryIds, 1, parentId)
|
table.insert(ancestryIds, 1, parentId)
|
||||||
|
knownAncestors[parentId] = true
|
||||||
parentId = nil
|
parentId = nil
|
||||||
|
|
||||||
if parentData then
|
if parentData then
|
||||||
@@ -312,7 +343,7 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
tree:buildAncestryNodes(ancestryIds, patch, instanceMap)
|
tree:buildAncestryNodes(previousId, ancestryIds, patch, instanceMap)
|
||||||
|
|
||||||
-- Gather detail text
|
-- Gather detail text
|
||||||
local changeList, hint = nil, nil
|
local changeList, hint = nil, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user