Skip to content

Commit

Permalink
Transfer - Remove recursive locks in snapshot node (#1004)
Browse files Browse the repository at this point in the history
  • Loading branch information
yahavi authored Oct 22, 2023
1 parent a85aaa5 commit 45dca6a
Showing 1 changed file with 49 additions and 32 deletions.
81 changes: 49 additions & 32 deletions utils/reposnapshot/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,26 @@ func (node *Node) action(action ActionOnNodeFunc) error {

// Convert node to wrapper in order to save it to file.
func (node *Node) convertToWrapper() (wrapper *NodeExportWrapper, err error) {
var children []*Node
err = node.action(func(node *Node) error {
wrapper = &NodeExportWrapper{
Name: node.name,
Completed: node.NodeStatus == Completed,
}
for i := range node.children {
converted, err := node.children[i].convertToWrapper()
if err != nil {
return err
}
wrapper.Children = append(wrapper.Children, converted)
}
children = node.children
return nil
})
if err != nil {
return
}

for i := range children {
converted, err := children[i].convertToWrapper()
if err != nil {
return nil, err
}
wrapper.Children = append(wrapper.Children, converted)
}
return
}

Expand Down Expand Up @@ -107,17 +113,19 @@ func (node *Node) getActualPath() (actualPath string, err error) {
}

// Sets node as completed, clear its contents, notifies parent to check completion.
func (node *Node) setCompleted() error {
return node.action(func(node *Node) error {
func (node *Node) setCompleted() (err error) {
var parent *Node
err = node.action(func(node *Node) error {
node.NodeStatus = Completed
node.children = nil
parent := node.parent
parent = node.parent
node.parent = nil
if parent != nil {
return parent.CheckCompleted()
}
return nil
})
if err == nil && parent != nil {
return parent.CheckCompleted()
}
return
}

// Check if node completed - if done exploring, done handling files, children are completed.
Expand Down Expand Up @@ -233,30 +241,39 @@ func (node *Node) RestartExploring() error {
// For a structure such as repo->dir1->dir2->dir3
// The initial call will be to the root, and for an input of ({"dir1","dir2"}), and the final output will be a pointer to dir2.
func (node *Node) findMatchingNode(childrenDirs []string) (matchingNode *Node, err error) {
err = node.action(func(node *Node) error {
// The node was found in the cache. Let's return it.
if len(childrenDirs) == 0 {
matchingNode = node
return nil
}
// The node was found in the cache. Let's return it.
if len(childrenDirs) == 0 {
matchingNode = node
return
}

// Check if any of the current node's children are parents of the current node.
for i := range node.children {
if node.children[i].name == childrenDirs[0] {
matchingNode, err = node.children[i].findMatchingNode(childrenDirs[1:])
return err
}
// Check if any of the current node's children are parents of the current node.
var children []*Node
err = node.action(func(node *Node) error {
children = node.children
return nil
})
if err != nil {
return
}
for i := range children {
if children[i].name == childrenDirs[0] {
matchingNode, err = children[i].findMatchingNode(childrenDirs[1:])
return
}
}

// None of the current node's children are parents of the current node.
// This means we need to start creating the searched node parents.
newNode := CreateNewNode(childrenDirs[0], node)
newNode.parent = node
// None of the current node's children are parents of the current node.
// This means we need to start creating the searched node parents.
newNode := CreateNewNode(childrenDirs[0], node)
err = node.action(func(node *Node) error {
node.children = append(node.children, newNode)
matchingNode, err = newNode.findMatchingNode(childrenDirs[1:])
return err
return nil
})
return
if err != nil {
return
}
return newNode.findMatchingNode(childrenDirs[1:])
}

func CreateNewNode(dirName string, parent *Node) *Node {
Expand Down

0 comments on commit 45dca6a

Please sign in to comment.