Package ca.carleton.gcrc.couch.date.cluster

Source Code of ca.carleton.gcrc.couch.date.cluster.TreeRebalanceProcess$Result

package ca.carleton.gcrc.couch.date.cluster;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import ca.carleton.gcrc.couch.date.impl.Interval;

public class TreeRebalanceProcess {
 
  static final int NODE_ELEMENT_THRESHOLD = 32;

  static public class Result {
    public List<TreeNode> legacyNodes = new Vector<TreeNode>();
    public TreeNode rootNode = null;
    public int nextClusterId;
  }
 
  static private class TreeNodeWithElements {
    private TreeNode node;
    private List<TreeElement> elements = new Vector<TreeElement>();
    private TreeNodeWithElements lowNode = null;
    private TreeNodeWithElements highNode = null;
   
    public TreeNodeWithElements(int clusterId, Interval interval) throws Exception {
      node = new TreeNode(clusterId, interval);
    }
   
    public TreeNode getNode(){
      return node;
    }
   
    public void addElement(TreeElement element, Result results) throws Exception {
     
      if( null != lowNode && lowNode.includes(element) ){
        // It fits in low node
        lowNode.addElement(element, results);
       
      } else if( null != highNode && highNode.includes(element) ){
        // It fits in high node
        highNode.addElement(element, results);
       
      } else {
        elements.add(element);
       
        if( elements.size() > NODE_ELEMENT_THRESHOLD
         && null == lowNode ){
          // Time to create children nodes
          {
            Interval lowInterval = new Interval(node.getInterval().getMin(), node.getMidPoint());
            int lowClusterId = results.nextClusterId;
            results.nextClusterId++;
            lowNode = new TreeNodeWithElements(lowClusterId, lowInterval);
            node.setLowChildNode( lowNode.node );
           
            List<TreeElement> childElements = new ArrayList<TreeElement>(elements.size());
            for(TreeElement elem : elements){
              if( lowNode.includes(elem) ){
                childElements.add(elem);
                lowNode.addElement(elem, results);
              }
            }
            elements.removeAll(childElements);
          }

          {
            Interval highInterval = new Interval(node.getMidPoint(), node.getInterval().getMax());
            int highClusterId = results.nextClusterId;
            results.nextClusterId++;
            highNode = new TreeNodeWithElements(highClusterId, highInterval);
            node.setHighChildNode( highNode.node );
           
            List<TreeElement> childElements = new ArrayList<TreeElement>(elements.size());
            for(TreeElement elem : elements){
              if( highNode.includes(elem) ){
                childElements.add(elem);
                highNode.addElement(elem, results);
              }
            }
            elements.removeAll(childElements);
          }
        }
      }
    }

    private boolean includes(TreeElement element) {
      return element.getInterval().isIncludedIn( node.getInterval() );
    }
  }
 
  static TreeRebalanceProcess.Result createTree(List<? extends TreeElement> elements) throws Exception {
    Result results = new Result();

    // Compute full interval, next cluster id and legacy nodes
    Interval fullInterval = null;
    results.nextClusterId = 1;
    Map<Integer,TreeNode> legacyNodes = new HashMap<Integer,TreeNode>();
    for(TreeElement element : elements){
      Integer clusterId = element.getClusterId();
     
      // Accumulate full interval
      if( null == fullInterval ){
        fullInterval = element.getInterval();
      } else {
        fullInterval = fullInterval.extendTo(element.getInterval());
      }
     
      // Figure out next cluster id
      if( null != clusterId ){
        if( clusterId >= results.nextClusterId ){
          results.nextClusterId = clusterId + 1;
        }
      }
     
      // Accumulate legacy nodes
      if( null != clusterId ){
        TreeNode legacyNode = legacyNodes.get(clusterId);
        if( null == legacyNode ){
          legacyNode = new TreeNode(clusterId, element.getInterval());
          legacyNodes.put(clusterId, legacyNode);
        } else {
          legacyNode.extendTo(element.getInterval());
        }
      }
    }
   
    // Need a full interval
    if( null == fullInterval ){
      // Create a default one
      fullInterval = new Interval(0, 1500000000000L);
    }
   
    // Create root node for tree
    TreeNodeWithElements rootNodeWithElements = new TreeNodeWithElements(results.nextClusterId, fullInterval);
    results.nextClusterId++;
    for(TreeElement element : elements){
      rootNodeWithElements.addElement(element, results);
    }
   
    // Install root node in results
    results.rootNode = rootNodeWithElements.getNode();
   
    // Install legacy nodes in results
    results.legacyNodes.addAll( legacyNodes.values() );
   
    return results;
  }
}
TOP

Related Classes of ca.carleton.gcrc.couch.date.cluster.TreeRebalanceProcess$Result

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.