Java tutorial
/** * 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.yarn.api.records; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceStability.Stable; import org.apache.hadoop.classification.InterfaceStability.Unstable; import org.apache.hadoop.util.FastNumberFormat; import org.apache.hadoop.yarn.util.Records; /** * <p><code>ContainerId</code> represents a globally unique identifier * for a {@link Container} in the cluster.</p> */ @Public @Stable public abstract class ContainerId implements Comparable<ContainerId> { public static final long CONTAINER_ID_BITMASK = 0xffffffffffL; private static final String CONTAINER_PREFIX = "container_"; private static final String EPOCH_PREFIX = "e"; @Public @Unstable public static ContainerId newContainerId(ApplicationAttemptId appAttemptId, long containerId) { ContainerId id = Records.newRecord(ContainerId.class); id.setContainerId(containerId); id.setApplicationAttemptId(appAttemptId); id.build(); return id; } @Private @Deprecated @Unstable public static ContainerId newInstance(ApplicationAttemptId appAttemptId, int containerId) { ContainerId id = Records.newRecord(ContainerId.class); id.setContainerId(containerId); id.setApplicationAttemptId(appAttemptId); id.build(); return id; } /** * Get the <code>ApplicationAttemptId</code> of the application to which the * <code>Container</code> was assigned. * <p> * Note: If containers are kept alive across application attempts via * {@link ApplicationSubmissionContext#setKeepContainersAcrossApplicationAttempts(boolean)} * the <code>ContainerId</code> does not necessarily contain the current * running application attempt's <code>ApplicationAttemptId</code> This * container can be allocated by previously exited application attempt and * managed by the current running attempt thus have the previous application * attempt's <code>ApplicationAttemptId</code>. * </p> * * @return <code>ApplicationAttemptId</code> of the application to which the * <code>Container</code> was assigned */ @Public @Stable public abstract ApplicationAttemptId getApplicationAttemptId(); @Private @Unstable protected abstract void setApplicationAttemptId(ApplicationAttemptId atId); /** * Get the lower 32 bits of identifier of the <code>ContainerId</code>, * which doesn't include epoch. Note that this method will be marked as * deprecated, so please use <code>getContainerId</code> instead. * @return lower 32 bits of identifier of the <code>ContainerId</code> */ @Public @Deprecated @Unstable public abstract int getId(); /** * Get the identifier of the <code>ContainerId</code>. Upper 24 bits are * reserved as epoch of cluster, and lower 40 bits are reserved as * sequential number of containers. * @return identifier of the <code>ContainerId</code> */ @Public @Unstable public abstract long getContainerId(); @Private @Unstable protected abstract void setContainerId(long id); private static final int APP_ID_MIN_DIGITS = 4; private static final int ATTEMPT_ID_MIN_DIGITS = 2; private static final int EPOCH_MIN_DIGITS = 2; private static final int CONTAINER_ID_MIN_DIGITS = 6; @Override public int hashCode() { // Generated by IntelliJ IDEA 13.1. int result = (int) (getContainerId() ^ (getContainerId() >>> 32)); result = 31 * result + getApplicationAttemptId().hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ContainerId other = (ContainerId) obj; if (!this.getApplicationAttemptId().equals(other.getApplicationAttemptId())) return false; if (this.getContainerId() != other.getContainerId()) return false; return true; } @Override public int compareTo(ContainerId other) { int result = this.getApplicationAttemptId().compareTo(other.getApplicationAttemptId()); if (result == 0) { return Long.compare(getContainerId(), other.getContainerId()); } else { return result; } } /** * @return A string representation of containerId. The format is * container_e*epoch*_*clusterTimestamp*_*appId*_*attemptId*_*containerId* * when epoch is larger than 0 * (e.g. container_e17_1410901177871_0001_01_000005). * *epoch* is increased when RM restarts or fails over. * When epoch is 0, epoch is omitted * (e.g. container_1410901177871_0001_01_000005). */ @Override public String toString() { StringBuilder sb = new StringBuilder(64); sb.append(CONTAINER_PREFIX); long epoch = getContainerId() >> 40; if (epoch > 0) { sb.append(EPOCH_PREFIX); FastNumberFormat.format(sb, epoch, EPOCH_MIN_DIGITS); sb.append('_'); } ApplicationId appId = getApplicationAttemptId().getApplicationId(); sb.append(appId.getClusterTimestamp()); sb.append('_'); FastNumberFormat.format(sb, appId.getId(), APP_ID_MIN_DIGITS); sb.append('_'); FastNumberFormat.format(sb, getApplicationAttemptId().getAttemptId(), ATTEMPT_ID_MIN_DIGITS); sb.append('_'); FastNumberFormat.format(sb, CONTAINER_ID_BITMASK & getContainerId(), CONTAINER_ID_MIN_DIGITS); return sb.toString(); } @Public @Stable public static ContainerId fromString(String containerIdStr) { if (!containerIdStr.startsWith(CONTAINER_PREFIX)) { throw new IllegalArgumentException("Invalid ContainerId prefix: " + containerIdStr); } try { int pos1 = CONTAINER_PREFIX.length() - 1; long epoch = 0; if (containerIdStr.regionMatches(pos1 + 1, EPOCH_PREFIX, 0, EPOCH_PREFIX.length())) { int pos2 = containerIdStr.indexOf('_', pos1 + 1); if (pos2 < 0) { throw new IllegalArgumentException("Invalid ContainerId: " + containerIdStr); } String epochStr = containerIdStr.substring(pos1 + 1 + EPOCH_PREFIX.length(), pos2); epoch = Integer.parseInt(epochStr); // rewind the current position pos1 = pos2; } int pos2 = containerIdStr.indexOf('_', pos1 + 1); if (pos2 < 0) { throw new IllegalArgumentException("Invalid ContainerId: " + containerIdStr); } long clusterTimestamp = Long.parseLong(containerIdStr.substring(pos1 + 1, pos2)); int pos3 = containerIdStr.indexOf('_', pos2 + 1); if (pos3 < 0) { throw new IllegalArgumentException("Invalid ContainerId: " + containerIdStr); } int appId = Integer.parseInt(containerIdStr.substring(pos2 + 1, pos3)); ApplicationId applicationId = ApplicationId.newInstance(clusterTimestamp, appId); int pos4 = containerIdStr.indexOf('_', pos3 + 1); if (pos4 < 0) { throw new IllegalArgumentException("Invalid ContainerId: " + containerIdStr); } int attemptId = Integer.parseInt(containerIdStr.substring(pos3 + 1, pos4)); ApplicationAttemptId appAttemptId = ApplicationAttemptId.newInstance(applicationId, attemptId); long id = Long.parseLong(containerIdStr.substring(pos4 + 1)); long cid = (epoch << 40) | id; ContainerId containerId = ContainerId.newContainerId(appAttemptId, cid); return containerId; } catch (NumberFormatException n) { throw new IllegalArgumentException("Invalid ContainerId: " + containerIdStr, n); } } protected abstract void build(); }