View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.util;
20  
21  import java.io.IOException;
22  import java.lang.reflect.Constructor;
23  import java.util.zip.Checksum;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  
29  /**
30   * Checksum types. The Checksum type is a one byte number
31   * that stores a representation of the checksum algorithm
32   * used to encode a hfile. The ordinal of these cannot
33   * change or else you risk breaking all existing HFiles out there.
34   */
35  @InterfaceAudience.Private
36  public enum ChecksumType {
37  
38    NULL((byte)0) {
39      @Override
40      public String getName() {
41        return "NULL";
42      }
43      @Override
44      public void initialize() {
45        // do nothing
46      }
47      @Override
48      public Checksum getChecksumObject() throws IOException {
49        return null; // checksums not used
50      }
51    },
52  
53    CRC32((byte)1) {
54      private transient Constructor<?> ctor;
55  
56      @Override
57      public String getName() {
58        return "CRC32";
59      }
60  
61      @Override
62      public void initialize() {
63        final String PURECRC32 = "org.apache.hadoop.util.PureJavaCrc32";
64        final String JDKCRC = "java.util.zip.CRC32";
65        LOG = LogFactory.getLog(ChecksumType.class);
66  
67        // check if hadoop library is available
68        try {
69          ctor = ChecksumFactory.newConstructor(PURECRC32);
70          LOG.debug(PURECRC32 + " available");
71        } catch (Exception e) {
72          LOG.trace(PURECRC32 + " not available.");
73        }
74        try {
75          // The default checksum class name is java.util.zip.CRC32.
76          // This is available on all JVMs.
77          if (ctor == null) {
78            ctor = ChecksumFactory.newConstructor(JDKCRC);
79            LOG.debug(JDKCRC + " available");
80          }
81        } catch (Exception e) {
82          LOG.trace(JDKCRC + " not available.");
83        }
84      }
85  
86      @Override
87      public Checksum getChecksumObject() throws IOException {
88        if (ctor == null) {
89          throw new IOException("Bad constructor for " + getName());
90        }
91        try {
92          return (Checksum)ctor.newInstance();
93        } catch (Exception e) {
94          throw new IOException(e);
95        }
96      }
97    },
98  
99    CRC32C((byte)2) {
100     private transient Constructor<?> ctor;
101 
102     @Override
103     public String getName() {
104       return "CRC32C";
105     }
106 
107     @Override
108     public void initialize() {
109       final String PURECRC32C = "org.apache.hadoop.util.PureJavaCrc32C";
110       LOG = LogFactory.getLog(ChecksumType.class);
111       try {
112         ctor = ChecksumFactory.newConstructor(PURECRC32C);
113         LOG.debug(PURECRC32C + " available");
114       } catch (Exception e) {
115         LOG.trace(PURECRC32C + " not available.");
116       }
117     }
118 
119     @Override
120     public Checksum getChecksumObject() throws IOException {
121       if (ctor == null) {
122         throw new IOException("Bad constructor for " + getName());
123       }
124       try {
125         return (Checksum)ctor.newInstance();
126       } catch (Exception e) {
127         throw new IOException(e);
128       }
129     }
130   };
131 
132   private final byte code;
133   protected Log LOG;
134 
135   /** initializes the relevant checksum class object */
136   abstract void initialize();
137 
138   /** returns the name of this checksum type */
139   public abstract String getName();
140 
141   private ChecksumType(final byte c) {
142     this.code = c;
143     initialize();
144   }
145 
146   /** returns a object that can be used to generate/validate checksums */
147   public abstract Checksum getChecksumObject() throws IOException;
148 
149   public byte getCode() {
150     return this.code;
151   }
152 
153   /**
154    * Cannot rely on enum ordinals . They change if item is removed or moved.
155    * Do our own codes.
156    * @param b
157    * @return Type associated with passed code.
158    */
159   public static ChecksumType codeToType(final byte b) {
160     for (ChecksumType t : ChecksumType.values()) {
161       if (t.getCode() == b) {
162         return t;
163       }
164     }
165     throw new RuntimeException("Unknown checksum type code " + b);
166   }
167 
168   /**
169    * Map a checksum name to a specific type.
170    * Do our own names.
171    * @param name
172    * @return Type associated with passed code.
173    */
174   public static ChecksumType nameToType(final String name) {
175     for (ChecksumType t : ChecksumType.values()) {
176       if (t.getName().equals(name)) {
177         return t;
178       }
179     }
180     throw new RuntimeException("Unknown checksum type name " + name);
181   }
182 }