|
@@ -20,19 +20,107 @@ package org.apache.hadoop.io.erasurecode;
|
|
|
import com.google.common.base.Preconditions;
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
-import org.apache.hadoop.fs.CommonConfigurationKeys;
|
|
|
+import org.apache.hadoop.io.erasurecode.codec.ErasureCodec;
|
|
|
+import org.apache.hadoop.io.erasurecode.codec.HHXORErasureCodec;
|
|
|
+import org.apache.hadoop.io.erasurecode.codec.RSErasureCodec;
|
|
|
+import org.apache.hadoop.io.erasurecode.codec.XORErasureCodec;
|
|
|
+import org.apache.hadoop.io.erasurecode.coder.ErasureDecoder;
|
|
|
+import org.apache.hadoop.io.erasurecode.coder.ErasureEncoder;
|
|
|
+import org.apache.hadoop.io.erasurecode.rawcoder.RSRawErasureCoderFactory;
|
|
|
+import org.apache.hadoop.io.erasurecode.rawcoder.RSRawErasureCoderFactoryLegacy;
|
|
|
import org.apache.hadoop.io.erasurecode.rawcoder.RawErasureCoderFactory;
|
|
|
import org.apache.hadoop.io.erasurecode.rawcoder.RawErasureDecoder;
|
|
|
import org.apache.hadoop.io.erasurecode.rawcoder.RawErasureEncoder;
|
|
|
+import org.apache.hadoop.io.erasurecode.rawcoder.XORRawErasureCoderFactory;
|
|
|
+
|
|
|
+import java.lang.reflect.Constructor;
|
|
|
+import java.lang.reflect.InvocationTargetException;
|
|
|
|
|
|
/**
|
|
|
- * A codec & coder utility to help create raw coders conveniently.
|
|
|
+ * A codec & coder utility to help create coders conveniently.
|
|
|
+ *
|
|
|
+ * {@link CodecUtil} includes erasure coder configurations key and default
|
|
|
+ * values such as coder class name and erasure codec option values included
|
|
|
+ * by {@link ErasureCodecOptions}. {@link ErasureEncoder} and
|
|
|
+ * {@link ErasureDecoder} are created by createEncoder and createDecoder
|
|
|
+ * respectively.{@link RawErasureEncoder} and {@link RawErasureDecoder} are
|
|
|
+ * are created by createRawEncoder and createRawDecoder.
|
|
|
*/
|
|
|
@InterfaceAudience.Private
|
|
|
public final class CodecUtil {
|
|
|
|
|
|
+ /** Erasure coder XOR codec. */
|
|
|
+ public static final String IO_ERASURECODE_CODEC_XOR_KEY =
|
|
|
+ "io.erasurecode.codec.xor";
|
|
|
+ public static final String IO_ERASURECODE_CODEC_XOR =
|
|
|
+ XORErasureCodec.class.getCanonicalName();
|
|
|
+ /** Erasure coder Reed-Solomon codec. */
|
|
|
+ public static final String IO_ERASURECODE_CODEC_RS_DEFAULT_KEY =
|
|
|
+ "io.erasurecode.codec.rs";
|
|
|
+ public static final String IO_ERASURECODE_CODEC_RS_DEFAULT =
|
|
|
+ RSErasureCodec.class.getCanonicalName();
|
|
|
+ /** Erasure coder hitch hiker XOR codec. */
|
|
|
+ public static final String IO_ERASURECODE_CODEC_HHXOR_KEY =
|
|
|
+ "io.erasurecode.codec.hhxor";
|
|
|
+ public static final String IO_ERASURECODE_CODEC_HHXOR =
|
|
|
+ HHXORErasureCodec.class.getCanonicalName();
|
|
|
+
|
|
|
+ /** Supported erasure codec classes. */
|
|
|
+
|
|
|
+ /** Raw coder factory for the RS default codec. */
|
|
|
+ public static final String IO_ERASURECODE_CODEC_RS_DEFAULT_RAWCODER_KEY =
|
|
|
+ "io.erasurecode.codec.rs-default.rawcoder";
|
|
|
+ public static final String IO_ERASURECODE_CODEC_RS_DEFAULT_RAWCODER_DEFAULT =
|
|
|
+ RSRawErasureCoderFactory.class.getCanonicalName();
|
|
|
+
|
|
|
+ /** Raw coder factory for the RS legacy codec. */
|
|
|
+ public static final String IO_ERASURECODE_CODEC_RS_LEGACY_RAWCODER_KEY =
|
|
|
+ "io.erasurecode.codec.rs-legacy.rawcoder";
|
|
|
+ public static final String IO_ERASURECODE_CODEC_RS_LEGACY_RAWCODER_DEFAULT =
|
|
|
+ RSRawErasureCoderFactoryLegacy.class.getCanonicalName();
|
|
|
+
|
|
|
+ /** Raw coder factory for the XOR codec. */
|
|
|
+ public static final String IO_ERASURECODE_CODEC_XOR_RAWCODER_KEY =
|
|
|
+ "io.erasurecode.codec.xor.rawcoder";
|
|
|
+ public static final String IO_ERASURECODE_CODEC_XOR_RAWCODER_DEFAULT =
|
|
|
+ XORRawErasureCoderFactory.class.getCanonicalName();
|
|
|
+
|
|
|
private CodecUtil() { }
|
|
|
|
|
|
+ /**
|
|
|
+ * Create encoder corresponding to given codec.
|
|
|
+ * @param options Erasure codec options
|
|
|
+ * @return erasure encoder
|
|
|
+ */
|
|
|
+ public static ErasureEncoder createEncoder(Configuration conf,
|
|
|
+ ErasureCodecOptions options) {
|
|
|
+ Preconditions.checkNotNull(conf);
|
|
|
+ Preconditions.checkNotNull(options);
|
|
|
+
|
|
|
+ String codecKey = getCodecClassName(conf,
|
|
|
+ options.getSchema().getCodecName());
|
|
|
+
|
|
|
+ ErasureCodec codec = createCodec(conf, codecKey, options);
|
|
|
+ return codec.createEncoder();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create decoder corresponding to given codec.
|
|
|
+ * @param options Erasure codec options
|
|
|
+ * @return erasure decoder
|
|
|
+ */
|
|
|
+ public static ErasureDecoder createDecoder(Configuration conf,
|
|
|
+ ErasureCodecOptions options) {
|
|
|
+ Preconditions.checkNotNull(conf);
|
|
|
+ Preconditions.checkNotNull(options);
|
|
|
+
|
|
|
+ String codecKey = getCodecClassName(conf,
|
|
|
+ options.getSchema().getCodecName());
|
|
|
+
|
|
|
+ ErasureCodec codec = createCodec(conf, codecKey, options);
|
|
|
+ return codec.createDecoder();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Create RS raw encoder according to configuration.
|
|
|
* @param conf configuration
|
|
@@ -45,7 +133,7 @@ public final class CodecUtil {
|
|
|
Preconditions.checkNotNull(conf);
|
|
|
Preconditions.checkNotNull(codec);
|
|
|
|
|
|
- String rawCoderFactoryKey = getFactNameFromCodec(conf, codec);
|
|
|
+ String rawCoderFactoryKey = getRawCoderFactNameFromCodec(conf, codec);
|
|
|
|
|
|
RawErasureCoderFactory fact = createRawCoderFactory(conf,
|
|
|
rawCoderFactoryKey);
|
|
@@ -65,7 +153,7 @@ public final class CodecUtil {
|
|
|
Preconditions.checkNotNull(conf);
|
|
|
Preconditions.checkNotNull(codec);
|
|
|
|
|
|
- String rawCoderFactoryKey = getFactNameFromCodec(conf, codec);
|
|
|
+ String rawCoderFactoryKey = getRawCoderFactNameFromCodec(conf, codec);
|
|
|
|
|
|
RawErasureCoderFactory fact = createRawCoderFactory(conf,
|
|
|
rawCoderFactoryKey);
|
|
@@ -92,22 +180,21 @@ public final class CodecUtil {
|
|
|
return fact;
|
|
|
}
|
|
|
|
|
|
- private static String getFactNameFromCodec(Configuration conf, String codec) {
|
|
|
+ private static String getRawCoderFactNameFromCodec(Configuration conf,
|
|
|
+ String codec) {
|
|
|
switch (codec) {
|
|
|
case ErasureCodeConstants.RS_DEFAULT_CODEC_NAME:
|
|
|
return conf.get(
|
|
|
- CommonConfigurationKeys.IO_ERASURECODE_CODEC_RS_DEFAULT_RAWCODER_KEY,
|
|
|
- CommonConfigurationKeys.
|
|
|
- IO_ERASURECODE_CODEC_RS_DEFAULT_RAWCODER_DEFAULT);
|
|
|
+ IO_ERASURECODE_CODEC_RS_DEFAULT_RAWCODER_KEY,
|
|
|
+ IO_ERASURECODE_CODEC_RS_DEFAULT_RAWCODER_DEFAULT);
|
|
|
case ErasureCodeConstants.RS_LEGACY_CODEC_NAME:
|
|
|
return conf.get(
|
|
|
- CommonConfigurationKeys.IO_ERASURECODE_CODEC_RS_LEGACY_RAWCODER_KEY,
|
|
|
- CommonConfigurationKeys.
|
|
|
- IO_ERASURECODE_CODEC_RS_LEGACY_RAWCODER_DEFAULT);
|
|
|
+ IO_ERASURECODE_CODEC_RS_LEGACY_RAWCODER_KEY,
|
|
|
+ IO_ERASURECODE_CODEC_RS_LEGACY_RAWCODER_DEFAULT);
|
|
|
case ErasureCodeConstants.XOR_CODEC_NAME:
|
|
|
return conf.get(
|
|
|
- CommonConfigurationKeys.IO_ERASURECODE_CODEC_XOR_RAWCODER_KEY,
|
|
|
- CommonConfigurationKeys.IO_ERASURECODE_CODEC_XOR_RAWCODER_DEFAULT);
|
|
|
+ IO_ERASURECODE_CODEC_XOR_RAWCODER_KEY,
|
|
|
+ IO_ERASURECODE_CODEC_XOR_RAWCODER_DEFAULT);
|
|
|
default:
|
|
|
// For custom codec, we throw exception if the factory is not configured
|
|
|
String rawCoderKey = "io.erasurecode.codec." + codec + ".rawcoder";
|
|
@@ -119,4 +206,59 @@ public final class CodecUtil {
|
|
|
return factName;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private static ErasureCodec createCodec(Configuration conf,
|
|
|
+ String codecClassName, ErasureCodecOptions options) {
|
|
|
+ ErasureCodec codec = null;
|
|
|
+ try {
|
|
|
+ Class<? extends ErasureCodec> codecClass =
|
|
|
+ conf.getClassByName(codecClassName)
|
|
|
+ .asSubclass(ErasureCodec.class);
|
|
|
+ Constructor<? extends ErasureCodec> constructor
|
|
|
+ = codecClass.getConstructor(Configuration.class,
|
|
|
+ ErasureCodecOptions.class);
|
|
|
+ codec = constructor.newInstance(conf, options);
|
|
|
+ } catch (ClassNotFoundException | InstantiationException |
|
|
|
+ IllegalAccessException | NoSuchMethodException |
|
|
|
+ InvocationTargetException e) {
|
|
|
+ throw new RuntimeException("Failed to create erasure codec", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (codec == null) {
|
|
|
+ throw new RuntimeException("Failed to create erasure codec");
|
|
|
+ }
|
|
|
+
|
|
|
+ return codec;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String getCodecClassName(Configuration conf, String codec) {
|
|
|
+ switch (codec) {
|
|
|
+ case ErasureCodeConstants.RS_DEFAULT_CODEC_NAME:
|
|
|
+ return conf.get(
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_RS_DEFAULT_KEY,
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_RS_DEFAULT);
|
|
|
+ case ErasureCodeConstants.RS_LEGACY_CODEC_NAME:
|
|
|
+ //TODO:rs-legacy should be handled differently.
|
|
|
+ return conf.get(
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_RS_DEFAULT_KEY,
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_RS_DEFAULT);
|
|
|
+ case ErasureCodeConstants.XOR_CODEC_NAME:
|
|
|
+ return conf.get(
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_XOR_KEY,
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_XOR);
|
|
|
+ case ErasureCodeConstants.HHXOR_CODEC_NAME:
|
|
|
+ return conf.get(
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_HHXOR_KEY,
|
|
|
+ CodecUtil.IO_ERASURECODE_CODEC_HHXOR);
|
|
|
+ default:
|
|
|
+ // For custom codec, we throw exception if the factory is not configured
|
|
|
+ String codecKey = "io.erasurecode.codec." + codec + ".coder";
|
|
|
+ String codecClass = conf.get(codecKey);
|
|
|
+ if (codecClass == null) {
|
|
|
+ throw new IllegalArgumentException("Codec not configured " +
|
|
|
+ "for custom codec " + codec);
|
|
|
+ }
|
|
|
+ return codecClass;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|