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     */
018    package org.apache.hadoop.hdfs.server.blockmanagement;
019    
020    import com.google.common.annotations.VisibleForTesting;
021    import com.google.common.base.Preconditions;
022    import com.google.common.collect.Lists;
023    
024    import org.apache.hadoop.fs.XAttr;
025    import org.apache.hadoop.hdfs.StorageType;
026    import org.apache.hadoop.hdfs.XAttrHelper;
027    import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy;
028    import org.apache.hadoop.hdfs.protocol.HdfsConstants;
029    import org.slf4j.Logger;
030    import org.slf4j.LoggerFactory;
031    
032    import java.util.List;
033    
034    /** A collection of block storage policies. */
035    public class BlockStoragePolicySuite {
036      static final Logger LOG = LoggerFactory.getLogger(BlockStoragePolicySuite
037          .class);
038    
039      public static final String STORAGE_POLICY_XATTR_NAME
040          = "hsm.block.storage.policy.id";
041      public static final XAttr.NameSpace XAttrNS = XAttr.NameSpace.SYSTEM;
042    
043      public static final int ID_BIT_LENGTH = 4;
044      public static final byte ID_UNSPECIFIED = 0;
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 XAttrNS.toString().toLowerCase() + "." + STORAGE_POLICY_XATTR_NAME;
135      }
136    
137      public static XAttr buildXAttr(byte policyId) {
138        final String name = buildXAttrName();
139        return XAttrHelper.buildXAttr(name, new byte[]{policyId});
140      }
141    
142      public static boolean isStoragePolicyXAttr(XAttr xattr) {
143        return xattr != null && xattr.getNameSpace() == XAttrNS
144            && xattr.getName().equals(STORAGE_POLICY_XATTR_NAME);
145      }
146    }