| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.tools.rumen; |
| |
| import java.util.Collections; |
| import java.util.Set; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| |
| /** |
| * {@link Node} represents a node in the cluster topology. A node can be a |
| * {@link MachineNode}, or a {@link RackNode}, etc. |
| */ |
| public class Node implements Comparable<Node> { |
| private static final SortedSet<Node> EMPTY_SET = |
| Collections.unmodifiableSortedSet(new TreeSet<Node>()); |
| private Node parent; |
| private final String name; |
| private final int level; |
| private SortedSet<Node> children; |
| |
| /** |
| * @param name |
| * A unique name to identify a node in the cluster. |
| * @param level |
| * The level of the node in the cluster |
| */ |
| public Node(String name, int level) { |
| if (name == null) { |
| throw new IllegalArgumentException("Node name cannot be null"); |
| } |
| |
| if (level < 0) { |
| throw new IllegalArgumentException("Level cannot be negative"); |
| } |
| |
| this.name = name; |
| this.level = level; |
| } |
| |
| /** |
| * Get the name of the node. |
| * |
| * @return The name of the node. |
| */ |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * Get the level of the node. |
| * @return The level of the node. |
| */ |
| public int getLevel() { |
| return level; |
| } |
| |
| private void checkChildren() { |
| if (children == null) { |
| children = new TreeSet<Node>(); |
| } |
| } |
| |
| /** |
| * Add a child node to this node. |
| * @param child The child node to be added. The child node should currently not be belong to another cluster topology. |
| * @return Boolean indicating whether the node is successfully added. |
| */ |
| public synchronized boolean addChild(Node child) { |
| if (child.parent != null) { |
| throw new IllegalArgumentException( |
| "The child is already under another node:" + child.parent); |
| } |
| checkChildren(); |
| boolean retval = children.add(child); |
| if (retval) child.parent = this; |
| return retval; |
| } |
| |
| /** |
| * Does this node have any children? |
| * @return Boolean indicate whether this node has any children. |
| */ |
| public synchronized boolean hasChildren() { |
| return children != null && !children.isEmpty(); |
| } |
| |
| /** |
| * Get the children of this node. |
| * |
| * @return The children of this node. If no child, an empty set will be |
| * returned. The returned set is read-only. |
| */ |
| public synchronized Set<Node> getChildren() { |
| return (children == null) ? EMPTY_SET : |
| Collections.unmodifiableSortedSet(children); |
| } |
| |
| /** |
| * Get the parent node. |
| * @return the parent node. If root node, return null. |
| */ |
| public Node getParent() { |
| return parent; |
| } |
| |
| @Override |
| public int hashCode() { |
| return name.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) |
| return true; |
| if (obj == null) |
| return false; |
| if (obj.getClass() != this.getClass()) |
| return false; |
| Node other = (Node) obj; |
| return name.equals(other.name); |
| } |
| |
| @Override |
| public String toString() { |
| return "(" + name +", " + level +")"; |
| } |
| |
| @Override |
| public int compareTo(Node o) { |
| return name.compareTo(o.name); |
| } |
| } |