gpa
gpa

Reputation: 2451

Java multi-way tree searching using fork-join

I have multi-way tree structure, which i have to traverse to determine status. I am looking into 'Post-Order' type traversal where leaf nodes are processed first. And search end condition depends on any of child node having status inactive. Also, from performance perspective, i would to use JDK7's fork-join mechanism.

enter image description here

Upvotes: 0

Views: 1862

Answers (1)

Alex DiCarlo
Alex DiCarlo

Reputation: 4891

Here is a (very) rough sketch of how you could do it.

final class TreeNode {
    private final Iterable<TreeNode> children;

    TreeNode(Iterable<TreeNode> aChildren) {
        children = aChildren;
    }

    Iterable<TreeNode> getChildren() {
        return children;
    }

    void postorder(TreeNodeIterator iterator) {
        postorderTraverse(this, iterator);
    }

    private void postorderTraverse(TreeNode node, TreeNodeIterator iterator) {
        for (TreeNode child : children) {
            postorderTraverse(child, iterator);
        }
        iterator.visit(node);
    }

    void postorderParallel(TreeNodeIterator iterator) {
        new ForkJoinPool().invoke(new VisitNodeAction(iterator, this));
    }

    interface TreeNodeIterator {
        void visit(TreeNode child);
    }

    private class VisitNodeAction extends RecursiveAction {
        private final TreeNodeIterator iterator;
        private final TreeNode node;

        private VisitNodeAction(TreeNodeIterator iterator, TreeNode node) {
            this.iterator = iterator;
            this.node = node;
        }

        @Override
        protected void compute() {
            List<RecursiveAction> tasks = new LinkedList<RecursiveAction>();
            for (TreeNode child : children) {
                tasks.add(new VisitNodeAction(iterator, child));
            }
            invokeAll(tasks);
            iterator.visit(node);
        }
    }
}

Some things that would need to be modified:

  • Adding your check for the status being inactive. Easiest way would be to keep a atomic boolean in each RecursiveAction that is checked before processing the node and updated when a node is inactive, although this is not a very clean or functional route.
  • Adding a way to decide when new threads should be used, the above uses a thread for every node. Also, you could possibly optimize it a bit by not creating a ForkJoinPool on every invocation of postorderParallel.

Upvotes: 2

Related Questions