001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hdfs.server.blockmanagement;
019
020import com.google.common.annotations.VisibleForTesting;
021import com.google.common.base.Preconditions;
022import com.google.common.collect.Lists;
023
024import org.apache.hadoop.fs.StorageType;
025import org.apache.hadoop.fs.XAttr;
026import org.apache.hadoop.hdfs.XAttrHelper;
027import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy;
028import org.apache.hadoop.hdfs.protocol.HdfsConstants;
029import org.apache.hadoop.util.StringUtils;
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033import java.util.List;
034
035/** A collection of block storage policies. */
036public class BlockStoragePolicySuite {
037  static final Logger LOG = LoggerFactory.getLogger(BlockStoragePolicySuite
038      .class);
039
040  public static final String STORAGE_POLICY_XATTR_NAME
041      = "hsm.block.storage.policy.id";
042  public static final XAttr.NameSpace XAttrNS = XAttr.NameSpace.SYSTEM;
043
044  public static final int ID_BIT_LENGTH = 4;
045
046  @VisibleForTesting
047  public static BlockStoragePolicySuite createDefaultSuite() {
048    final BlockStoragePolicy[] policies =
049        new BlockStoragePolicy[1 << ID_BIT_LENGTH];
050    final byte lazyPersistId = HdfsConstants.MEMORY_STORAGE_POLICY_ID;
051    policies[lazyPersistId] = new BlockStoragePolicy(lazyPersistId,
052        HdfsConstants.MEMORY_STORAGE_POLICY_NAME,
053        new StorageType[]{StorageType.RAM_DISK, StorageType.DISK},
054        new StorageType[]{StorageType.DISK},
055        new StorageType[]{StorageType.DISK},
056        true);    // Cannot be changed on regular files, but inherited.
057    final byte allssdId = HdfsConstants.ALLSSD_STORAGE_POLICY_ID;
058    policies[allssdId] = new BlockStoragePolicy(allssdId,
059        HdfsConstants.ALLSSD_STORAGE_POLICY_NAME,
060        new StorageType[]{StorageType.SSD},
061        new StorageType[]{StorageType.DISK},
062        new StorageType[]{StorageType.DISK});
063    final byte onessdId = HdfsConstants.ONESSD_STORAGE_POLICY_ID;
064    policies[onessdId] = new BlockStoragePolicy(onessdId,
065        HdfsConstants.ONESSD_STORAGE_POLICY_NAME,
066        new StorageType[]{StorageType.SSD, StorageType.DISK},
067        new StorageType[]{StorageType.SSD, StorageType.DISK},
068        new StorageType[]{StorageType.SSD, StorageType.DISK});
069    final byte hotId = HdfsConstants.HOT_STORAGE_POLICY_ID;
070    policies[hotId] = new BlockStoragePolicy(hotId,
071        HdfsConstants.HOT_STORAGE_POLICY_NAME,
072        new StorageType[]{StorageType.DISK}, StorageType.EMPTY_ARRAY,
073        new StorageType[]{StorageType.ARCHIVE});
074    final byte warmId = HdfsConstants.WARM_STORAGE_POLICY_ID;
075    policies[warmId] = new BlockStoragePolicy(warmId,
076        HdfsConstants.WARM_STORAGE_POLICY_NAME,
077        new StorageType[]{StorageType.DISK, StorageType.ARCHIVE},
078        new StorageType[]{StorageType.DISK, StorageType.ARCHIVE},
079        new StorageType[]{StorageType.DISK, StorageType.ARCHIVE});
080    final byte coldId = HdfsConstants.COLD_STORAGE_POLICY_ID;
081    policies[coldId] = new BlockStoragePolicy(coldId,
082        HdfsConstants.COLD_STORAGE_POLICY_NAME,
083        new StorageType[]{StorageType.ARCHIVE}, StorageType.EMPTY_ARRAY,
084        StorageType.EMPTY_ARRAY);
085    return new BlockStoragePolicySuite(hotId, policies);
086  }
087
088  private final byte defaultPolicyID;
089  private final BlockStoragePolicy[] policies;
090
091  public BlockStoragePolicySuite(byte defaultPolicyID,
092      BlockStoragePolicy[] policies) {
093    this.defaultPolicyID = defaultPolicyID;
094    this.policies = policies;
095  }
096
097  /** @return the corresponding policy. */
098  public BlockStoragePolicy getPolicy(byte id) {
099    // id == 0 means policy not specified.
100    return id == 0? getDefaultPolicy(): policies[id];
101  }
102
103  /** @return the default policy. */
104  public BlockStoragePolicy getDefaultPolicy() {
105    return getPolicy(defaultPolicyID);
106  }
107
108  public BlockStoragePolicy getPolicy(String policyName) {
109    Preconditions.checkNotNull(policyName);
110
111    if (policies != null) {
112      for (BlockStoragePolicy policy : policies) {
113        if (policy != null && policy.getName().equalsIgnoreCase(policyName)) {
114          return policy;
115        }
116      }
117    }
118    return null;
119  }
120
121  public BlockStoragePolicy[] getAllPolicies() {
122    List<BlockStoragePolicy> list = Lists.newArrayList();
123    if (policies != null) {
124      for (BlockStoragePolicy policy : policies) {
125        if (policy != null) {
126          list.add(policy);
127        }
128      }
129    }
130    return list.toArray(new BlockStoragePolicy[list.size()]);
131  }
132
133  public static String buildXAttrName() {
134    return StringUtils.toLowerCase(XAttrNS.toString())
135        + "." + STORAGE_POLICY_XATTR_NAME;
136  }
137
138  public static XAttr buildXAttr(byte policyId) {
139    final String name = buildXAttrName();
140    return XAttrHelper.buildXAttr(name, new byte[]{policyId});
141  }
142
143  public static String getStoragePolicyXAttrPrefixedName() {
144    return XAttrHelper.getPrefixedName(XAttrNS, STORAGE_POLICY_XATTR_NAME);
145  }
146}