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.namenode;
019    
020    import java.util.HashMap;
021    import java.util.Map;
022    import java.util.SortedSet;
023    
024    import org.apache.hadoop.classification.InterfaceAudience;
025    import org.apache.hadoop.hdfs.protocol.LayoutVersion;
026    import org.apache.hadoop.hdfs.protocol.LayoutVersion.FeatureInfo;
027    import org.apache.hadoop.hdfs.protocol.LayoutVersion.LayoutFeature;
028    
029    
030    @InterfaceAudience.Private
031    public class NameNodeLayoutVersion { 
032      /** Build layout version and corresponding feature matrix */
033      public final static Map<Integer, SortedSet<LayoutFeature>> FEATURES
034          = new HashMap<Integer, SortedSet<LayoutFeature>>();
035    
036      public static final int CURRENT_LAYOUT_VERSION
037          = LayoutVersion.getCurrentLayoutVersion(Feature.values());
038    
039      static {
040        LayoutVersion.updateMap(FEATURES, LayoutVersion.Feature.values());
041        LayoutVersion.updateMap(FEATURES, NameNodeLayoutVersion.Feature.values());
042      }
043      
044      public static SortedSet<LayoutFeature> getFeatures(int lv) {
045        return FEATURES.get(lv);
046      }
047    
048      public static boolean supports(final LayoutFeature f, final int lv) {
049        return LayoutVersion.supports(FEATURES, f, lv);
050      }
051    
052      /**
053       * Enums for features that change the layout version.
054       * <br><br>
055       * To add a new layout version:
056       * <ul>
057       * <li>Define a new enum constant with a short enum name, the new layout version 
058       * and description of the added feature.</li>
059       * <li>When adding a layout version with an ancestor that is not same as
060       * its immediate predecessor, use the constructor where a specific ancestor
061       * can be passed.
062       * </li>
063       * </ul>
064       */
065      public static enum Feature implements LayoutFeature {
066        ROLLING_UPGRADE(-55, -53, "Support rolling upgrade", false),
067        EDITLOG_LENGTH(-56, "Add length field to every edit log op");
068        
069        private final FeatureInfo info;
070    
071        /**
072         * Feature that is added at layout version {@code lv} - 1. 
073         * @param lv new layout version with the addition of this feature
074         * @param description description of the feature
075         */
076        Feature(final int lv, final String description) {
077          this(lv, lv + 1, description, false);
078        }
079    
080        /**
081         * NameNode feature that is added at layout version {@code ancestoryLV}.
082         * @param lv new layout version with the addition of this feature
083         * @param ancestorLV layout version from which the new lv is derived from.
084         * @param description description of the feature
085         * @param reserved true when this is a layout version reserved for previous
086         *        versions
087         * @param features set of features that are to be enabled for this version
088         */
089        Feature(final int lv, final int ancestorLV, final String description,
090            boolean reserved, Feature... features) {
091          info = new FeatureInfo(lv, ancestorLV, description, reserved, features);
092        }
093        
094        @Override
095        public FeatureInfo getInfo() {
096          return info;
097        }
098      }
099    }