org.apache.hadoop.hdfs.server.namenode.CachePool.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hdfs.server.namenode.CachePool.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.hdfs.server.namenode;

import java.io.IOException;

import javax.annotation.Nonnull;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.protocol.CacheDirective;
import org.apache.hadoop.hdfs.protocol.CachePoolEntry;
import org.apache.hadoop.hdfs.protocol.CachePoolInfo;
import org.apache.hadoop.hdfs.protocol.CachePoolStats;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.IntrusiveCollection;

import com.google.common.base.Preconditions;

/**
 * A CachePool describes a set of cache resources being managed by the NameNode.
 * User caching requests are billed to the cache pool specified in the request.
 *
 * This is an internal class, only used on the NameNode.  For identifying or
 * describing a cache pool to clients, please use CachePoolInfo.
 * 
 * CachePools must be accessed under the FSNamesystem lock.
 */
@InterfaceAudience.Private
public final class CachePool {
    @Nonnull
    private final String poolName;

    @Nonnull
    private String ownerName;

    @Nonnull
    private String groupName;

    /**
     * Cache pool permissions.
     * 
     * READ permission means that you can list the cache directives in this pool.
     * WRITE permission means that you can add, remove, or modify cache directives
     *       in this pool.
     * EXECUTE permission is unused.
     */
    @Nonnull
    private FsPermission mode;

    /**
     * Maximum number of bytes that can be cached in this pool.
     */
    private long limit;

    /**
     * Default replication num for CacheDirective in this pool.
     */
    private short defaultReplication;

    /**
     * Maximum duration that a CacheDirective in this pool remains valid,
     * in milliseconds.
     */
    private long maxRelativeExpiryMs;

    private long bytesNeeded;
    private long bytesCached;
    private long filesNeeded;
    private long filesCached;

    public final static class DirectiveList extends IntrusiveCollection<CacheDirective> {
        private final CachePool cachePool;

        private DirectiveList(CachePool cachePool) {
            this.cachePool = cachePool;
        }

        public CachePool getCachePool() {
            return cachePool;
        }
    }

    @Nonnull
    private final DirectiveList directiveList = new DirectiveList(this);

    /**
     * Create a new cache pool based on a CachePoolInfo object and the defaults.
     * We will fill in information that was not supplied according to the
     * defaults.
     */
    static CachePool createFromInfoAndDefaults(CachePoolInfo info) throws IOException {
        UserGroupInformation ugi = null;
        String ownerName = info.getOwnerName();
        if (ownerName == null) {
            ugi = NameNode.getRemoteUser();
            ownerName = ugi.getShortUserName();
        }
        String groupName = info.getGroupName();
        if (groupName == null) {
            if (ugi == null) {
                ugi = NameNode.getRemoteUser();
            }
            groupName = ugi.getPrimaryGroupName();
        }
        FsPermission mode = (info.getMode() == null) ? FsPermission.getCachePoolDefault() : info.getMode();
        long limit = info.getLimit() == null ? CachePoolInfo.DEFAULT_LIMIT : info.getLimit();
        short defaultReplication = info.getDefaultReplication() == null ? CachePoolInfo.DEFAULT_REPLICATION_NUM
                : info.getDefaultReplication();
        long maxRelativeExpiry = info.getMaxRelativeExpiryMs() == null ? CachePoolInfo.DEFAULT_MAX_RELATIVE_EXPIRY
                : info.getMaxRelativeExpiryMs();
        return new CachePool(info.getPoolName(), ownerName, groupName, mode, limit, defaultReplication,
                maxRelativeExpiry);
    }

    /**
     * Create a new cache pool based on a CachePoolInfo object.
     * No fields in the CachePoolInfo can be blank.
     */
    static CachePool createFromInfo(CachePoolInfo info) {
        return new CachePool(info.getPoolName(), info.getOwnerName(), info.getGroupName(), info.getMode(),
                info.getLimit(), info.getDefaultReplication(), info.getMaxRelativeExpiryMs());
    }

    CachePool(String poolName, String ownerName, String groupName, FsPermission mode, long limit,
            short defaultReplication, long maxRelativeExpiry) {
        Preconditions.checkNotNull(poolName);
        Preconditions.checkNotNull(ownerName);
        Preconditions.checkNotNull(groupName);
        Preconditions.checkNotNull(mode);
        this.poolName = poolName;
        this.ownerName = ownerName;
        this.groupName = groupName;
        this.mode = new FsPermission(mode);
        this.limit = limit;
        this.defaultReplication = defaultReplication;
        this.maxRelativeExpiryMs = maxRelativeExpiry;
    }

    public String getPoolName() {
        return poolName;
    }

    public String getOwnerName() {
        return ownerName;
    }

    public CachePool setOwnerName(String ownerName) {
        this.ownerName = ownerName;
        return this;
    }

    public String getGroupName() {
        return groupName;
    }

    public CachePool setGroupName(String groupName) {
        this.groupName = groupName;
        return this;
    }

    public FsPermission getMode() {
        return mode;
    }

    public CachePool setMode(FsPermission mode) {
        this.mode = new FsPermission(mode);
        return this;
    }

    public long getLimit() {
        return limit;
    }

    public CachePool setLimit(long bytes) {
        this.limit = bytes;
        return this;
    }

    public short getDefaultReplication() {
        return defaultReplication;
    }

    public void setDefaultReplication(short replication) {
        this.defaultReplication = replication;
    }

    public long getMaxRelativeExpiryMs() {
        return maxRelativeExpiryMs;
    }

    public CachePool setMaxRelativeExpiryMs(long expiry) {
        this.maxRelativeExpiryMs = expiry;
        return this;
    }

    /**
     * Get either full or partial information about this CachePool.
     *
     * @param fullInfo
     *          If true, only the name will be returned (i.e., what you 
     *          would get if you didn't have read permission for this pool.)
     * @return
     *          Cache pool information.
     */
    CachePoolInfo getInfo(boolean fullInfo) {
        CachePoolInfo info = new CachePoolInfo(poolName);
        if (!fullInfo) {
            return info;
        }
        return info.setOwnerName(ownerName).setGroupName(groupName).setMode(new FsPermission(mode)).setLimit(limit)
                .setDefaultReplication(defaultReplication).setMaxRelativeExpiryMs(maxRelativeExpiryMs);
    }

    /**
     * Resets statistics related to this CachePool
     */
    public void resetStatistics() {
        bytesNeeded = 0;
        bytesCached = 0;
        filesNeeded = 0;
        filesCached = 0;
    }

    public void addBytesNeeded(long bytes) {
        bytesNeeded += bytes;
    }

    public void addBytesCached(long bytes) {
        bytesCached += bytes;
    }

    public void addFilesNeeded(long files) {
        filesNeeded += files;
    }

    public void addFilesCached(long files) {
        filesCached += files;
    }

    public long getBytesNeeded() {
        return bytesNeeded;
    }

    public long getBytesCached() {
        return bytesCached;
    }

    public long getBytesOverlimit() {
        return Math.max(bytesNeeded - limit, 0);
    }

    public long getFilesNeeded() {
        return filesNeeded;
    }

    public long getFilesCached() {
        return filesCached;
    }

    /**
     * Get statistics about this CachePool.
     *
     * @return   Cache pool statistics.
     */
    private CachePoolStats getStats() {
        return new CachePoolStats.Builder().setBytesNeeded(bytesNeeded).setBytesCached(bytesCached)
                .setBytesOverlimit(getBytesOverlimit()).setFilesNeeded(filesNeeded).setFilesCached(filesCached)
                .build();
    }

    /**
     * Returns a CachePoolInfo describing this CachePool based on the permissions
     * of the calling user. Unprivileged users will see only minimal descriptive
     * information about the pool.
     * 
     * @param pc Permission checker to be used to validate the user's permissions,
     *          or null
     * @return CachePoolEntry describing this CachePool
     */
    public CachePoolEntry getEntry(FSPermissionChecker pc) {
        boolean hasPermission = true;
        if (pc != null) {
            try {
                pc.checkPermission(this, FsAction.READ);
            } catch (AccessControlException e) {
                hasPermission = false;
            }
        }
        return new CachePoolEntry(getInfo(hasPermission),
                hasPermission ? getStats() : new CachePoolStats.Builder().build());
    }

    public String toString() {
        return new StringBuilder().append("{ ").append("poolName:").append(poolName).append(", ownerName:")
                .append(ownerName).append(", groupName:").append(groupName).append(", mode:").append(mode)
                .append(", limit:").append(limit).append(", defaultReplication").append(defaultReplication)
                .append(", maxRelativeExpiryMs:").append(maxRelativeExpiryMs).append(" }").toString();
    }

    public DirectiveList getDirectiveList() {
        return directiveList;
    }
}