package org.apache.hadoop.corona;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.net.Node;
public class ClusterNode {
public static final Log LOG =
LogFactory.getLog(ClusterNode.class);
public static class GrantId {
public String sessionId;
public int requestId;
private final String unique;
public GrantId (String sessionId, int requestId) {
this.sessionId = sessionId;
this.requestId = requestId;
this.unique = sessionId + requestId;
}
@Override
public int hashCode() {
return unique.hashCode();
}
@Override
public boolean equals(Object that) {
if (that == null)
return false;
if (that instanceof GrantId)
return this.equals((GrantId)that);
return false;
}
public boolean equals(GrantId that) {
if (that == null)
return false;
return (this.unique.equals(that.unique));
}
}
public ClusterNodeInfo clusterNodeInfo;
public long lastHeartbeatTime;
public boolean deleted = false;
public final Node hostNode;
public Map<String, Integer> resourceTypeToMaxCpu;
public Map<String, IntWritable> resourceTypeToAllocatedCpu;
protected Map<GrantId, ResourceRequest> grants =
new HashMap<GrantId, ResourceRequest> ();
protected ComputeSpecs granted =
new ComputeSpecs(); // All integral fields get initialized to 0.
private void initResourceTypeToCpu(Map<Integer, Map<String, Integer>> cpuToResourcePartitioning) {
Map<String, Integer> ret = cpuToResourcePartitioning.get((int)clusterNodeInfo.total.numCpus);
if (ret == null) {
Map<String, Integer> oneCpuMap = cpuToResourcePartitioning.get(1);
if (oneCpuMap == null) {
throw new RuntimeException ("No matching entry for cpu count: " + clusterNodeInfo.total.numCpus
+ " in node " + clusterNodeInfo.toString() + " and no 1 cpu map");
}
ret = new HashMap<String, Integer> ();
for (String key: oneCpuMap.keySet()) {
ret.put(key, oneCpuMap.get(key).intValue() * clusterNodeInfo.total.numCpus);
}
}
resourceTypeToMaxCpu = ret;
resourceTypeToAllocatedCpu = new HashMap<String, IntWritable> ();
for (String key: ret.keySet()) {
resourceTypeToAllocatedCpu.put(key, new IntWritable(0));
}
}
public ClusterNode(ClusterNodeInfo clusterNodeInfo, Node node,
Map<Integer, Map<String, Integer>> cpuToResourcePartitioning) {
clusterNodeInfo.address.host = clusterNodeInfo.address.host.intern();
this.clusterNodeInfo = clusterNodeInfo;
lastHeartbeatTime = ClusterManager.clock.getTime();
this.hostNode = node;
initResourceTypeToCpu(cpuToResourcePartitioning);
}
public void addGrant(String sessionId, ResourceRequest req) {
if (deleted)
throw new RuntimeException ("Node " + getName() + " has been deleted");
grants.put(new GrantId(sessionId, req.id), req);
// update allocated counts
Utilities.incrComputeSpecs(granted, req.specs);
IntWritable cpu = resourceTypeToAllocatedCpu.get(req.type);
cpu.set(cpu.get() + req.specs.numCpus);
//LOG.info("Node " + getName() + " has granted " + granted.numCpus + " cpus");
}
public ResourceRequest getRequestForGrant(String sessionId, int requestId) {
return grants.get(new GrantId(sessionId, requestId));
}
public void cancelGrant(String sessionId, int requestId) {
if (deleted)
throw new RuntimeException ("Node " + getName() + " has been deleted");
ResourceRequest req = grants.remove(new GrantId(sessionId, requestId));
if (req != null) {
Utilities.decrComputeSpecs(granted, req.specs);
IntWritable cpu = resourceTypeToAllocatedCpu.get(req.type);
cpu.set(cpu.get() - req.specs.numCpus);
}
//LOG.info("Node " + getName() + " has granted " + granted.numCpus + " cpus");
}
public boolean checkForGrant(ResourceRequest req) {
if (deleted)
throw new RuntimeException ("Node " + getName() + " has been deleted");
// only check for cpu availability for specific type right now
IntWritable cpuAlloced = resourceTypeToAllocatedCpu.get(req.type);
Integer cpuMax = resourceTypeToMaxCpu.get(req.type);
return (cpuMax.intValue() >= req.specs.numCpus + cpuAlloced.get());
}
public void heartbeat() {
lastHeartbeatTime = ClusterManager.clock.getTime();
}
public String getName() {
return clusterNodeInfo.name;
}
public String getHost() {
return clusterNodeInfo.address.host;
}
public InetAddress getAddress() {
return clusterNodeInfo.address;
}
public String getAppInfo() {
return clusterNodeInfo.appInfo;
}
public Set<GrantId> getGrants() {
HashSet<GrantId> ret = new HashSet<GrantId> ();
ret.addAll(grants.keySet());
return (ret);
}
public int getMaxCpuForType(String type) {
Integer i = resourceTypeToMaxCpu.get(type);
if (i == null)
return 0;
else
return i.intValue();
}
public int getAllocatedCpuForType(String type) {
IntWritable i = resourceTypeToAllocatedCpu.get(type);
if (i == null)
return 0;
else
return i.get();
}
}