javascriptperformancetreetreemodel

merging two trees using treemodel.js


example: http://jsfiddle.net/yeehawjared/bawv0790/

I'm building an app where a webpage opens, loading JSON of a large data tree structure. TreeModel.js parses this great and all is well.

As time continues, the browser receives updates in the form of smaller data trees. I'm trying to wrap my head around combining the additionalData to the masterTree. I can't think of a way to simultaneously walk both and do a node-by-node comparison. If I could, it would be easy to aggregate node.model.x properties and add children if they don't exist.

In the code below, I walk through the additional data - but I don't know how to efficiently combine new nodes to the masterTree. Can someone help my methodology with psuedo-code or point me in the right direction? What's the best way to continually update my masterTree?

Many thanks.

var tree = new TreeModel();
var masterTree = tree.parse(data1);

var additionalData = tree.parse(data2);
additionalData.walk(function (node) {

    // compare additionalData to the masterTree
    if (node.model.id == masterTree.model.id) {
        console.debug('match, combine the attributes')
    } else {
        // add the additional node to the materTree
    }
});

Solution

  • Take a look at this fiddle for the example in action: http://jsfiddle.net/bawv0790/1/

    The important function is mergeNodes. It is a recursive function that receives 2 nodes, n1 and n2. First it updates n1 size according to n2 and them adds n2 children to n1 if they are missing or merges them if they are present.

    function mergeNodes(n1, n2) {
        var n1HasN2Child, i, n2Child;
    
        // Update the sizes
        updateSize(n1, n2);
    
        // Check which n2 children are present in n1
        n1HasN2Child = n2.children.map(hasChild(n1));
    
        // Iterate over n2 children
        for (i = 0; i < n1HasN2Child.length; i++) {
            n2Child = n2.children[i];
            if (n1HasN2Child[i]) {
                // n1 already has this n2 child, so lets merge them
                n1Child = n1.first({strategy: 'breadth'}, idEq(n2Child));
                mergeNodes(n1Child, n2Child);
            } else {
                // n1 does not have this n2 child, so add it
                n1.addChild(n2Child);
            }
        }
    }
    

    Checking which n2 children are in n1 could be vastly improved if the children were sorted.