org.apache.hadoop.yarn.api.records.ContainerId.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.yarn.api.records.ContainerId.java

Source

/**
 * 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();
}