HADOOP-12013 Generate fixed data to perform erasure coder test. Contributed by Kai Zheng
This commit is contained in:
parent
3d734df24c
commit
4ae32abdf4
|
@ -54,3 +54,5 @@
|
||||||
|
|
||||||
HADOOP-11938. Enhance ByteBuffer version encode/decode API of raw erasure
|
HADOOP-11938. Enhance ByteBuffer version encode/decode API of raw erasure
|
||||||
coder. (Kai Zheng via Zhe Zhang)
|
coder. (Kai Zheng via Zhe Zhang)
|
||||||
|
|
||||||
|
HADOOP-12013. Generate fixed data to perform erasure coder test. (Kai Zheng)
|
|
@ -52,6 +52,12 @@ public abstract class TestCoderBase {
|
||||||
// may go to different coding implementations.
|
// may go to different coding implementations.
|
||||||
protected boolean usingDirectBuffer = true;
|
protected boolean usingDirectBuffer = true;
|
||||||
|
|
||||||
|
protected boolean usingFixedData = true;
|
||||||
|
// Using this the generated data can be repeatable across multiple calls to
|
||||||
|
// encode(), in order for troubleshooting.
|
||||||
|
private static int FIXED_DATA_GENERATOR = 0;
|
||||||
|
protected byte[][] fixedData;
|
||||||
|
|
||||||
protected int getChunkSize() {
|
protected int getChunkSize() {
|
||||||
return chunkSize;
|
return chunkSize;
|
||||||
}
|
}
|
||||||
|
@ -63,13 +69,17 @@ public abstract class TestCoderBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare before running the case.
|
* Prepare before running the case.
|
||||||
|
* @param conf
|
||||||
* @param numDataUnits
|
* @param numDataUnits
|
||||||
* @param numParityUnits
|
* @param numParityUnits
|
||||||
* @param erasedDataIndexes
|
* @param erasedDataIndexes
|
||||||
|
* @param erasedParityIndexes
|
||||||
|
* @param usingFixedData Using fixed or pre-generated data to test instead of
|
||||||
|
* generating data
|
||||||
*/
|
*/
|
||||||
protected void prepare(Configuration conf, int numDataUnits,
|
protected void prepare(Configuration conf, int numDataUnits,
|
||||||
int numParityUnits, int[] erasedDataIndexes,
|
int numParityUnits, int[] erasedDataIndexes,
|
||||||
int[] erasedParityIndexes) {
|
int[] erasedParityIndexes, boolean usingFixedData) {
|
||||||
this.conf = conf;
|
this.conf = conf;
|
||||||
this.numDataUnits = numDataUnits;
|
this.numDataUnits = numDataUnits;
|
||||||
this.numParityUnits = numParityUnits;
|
this.numParityUnits = numParityUnits;
|
||||||
|
@ -77,6 +87,38 @@ public abstract class TestCoderBase {
|
||||||
erasedDataIndexes : new int[] {0};
|
erasedDataIndexes : new int[] {0};
|
||||||
this.erasedParityIndexes = erasedParityIndexes != null ?
|
this.erasedParityIndexes = erasedParityIndexes != null ?
|
||||||
erasedParityIndexes : new int[] {0};
|
erasedParityIndexes : new int[] {0};
|
||||||
|
this.usingFixedData = usingFixedData;
|
||||||
|
if (usingFixedData) {
|
||||||
|
prepareFixedData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare before running the case.
|
||||||
|
* @param conf
|
||||||
|
* @param numDataUnits
|
||||||
|
* @param numParityUnits
|
||||||
|
* @param erasedDataIndexes
|
||||||
|
* @param erasedParityIndexes
|
||||||
|
*/
|
||||||
|
protected void prepare(Configuration conf, int numDataUnits,
|
||||||
|
int numParityUnits, int[] erasedDataIndexes,
|
||||||
|
int[] erasedParityIndexes) {
|
||||||
|
prepare(conf, numDataUnits, numParityUnits, erasedDataIndexes,
|
||||||
|
erasedParityIndexes, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare before running the case.
|
||||||
|
* @param numDataUnits
|
||||||
|
* @param numParityUnits
|
||||||
|
* @param erasedDataIndexes
|
||||||
|
* @param erasedParityIndexes
|
||||||
|
*/
|
||||||
|
protected void prepare(int numDataUnits, int numParityUnits,
|
||||||
|
int[] erasedDataIndexes, int[] erasedParityIndexes) {
|
||||||
|
prepare(null, numDataUnits, numParityUnits, erasedDataIndexes,
|
||||||
|
erasedParityIndexes, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,6 +320,29 @@ public abstract class TestCoderBase {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected ECChunk[] prepareDataChunksForEncoding() {
|
protected ECChunk[] prepareDataChunksForEncoding() {
|
||||||
|
if (usingFixedData) {
|
||||||
|
ECChunk[] chunks = new ECChunk[numDataUnits];
|
||||||
|
for (int i = 0; i < chunks.length; i++) {
|
||||||
|
chunks[i] = makeChunkUsingData(fixedData[i]);
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
return generateDataChunks();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ECChunk makeChunkUsingData(byte[] data) {
|
||||||
|
ECChunk chunk = allocateOutputChunk();
|
||||||
|
ByteBuffer buffer = chunk.getBuffer();
|
||||||
|
int pos = buffer.position();
|
||||||
|
buffer.put(data, 0, chunkSize);
|
||||||
|
buffer.flip();
|
||||||
|
buffer.position(pos);
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ECChunk[] generateDataChunks() {
|
||||||
ECChunk[] chunks = new ECChunk[numDataUnits];
|
ECChunk[] chunks = new ECChunk[numDataUnits];
|
||||||
for (int i = 0; i < chunks.length; i++) {
|
for (int i = 0; i < chunks.length; i++) {
|
||||||
chunks[i] = generateDataChunk();
|
chunks[i] = generateDataChunk();
|
||||||
|
@ -286,6 +351,15 @@ public abstract class TestCoderBase {
|
||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prepareFixedData() {
|
||||||
|
// We may load test data from a resource, or just generate randomly.
|
||||||
|
// The generated data will be used across subsequent encode/decode calls.
|
||||||
|
this.fixedData = new byte[numDataUnits][];
|
||||||
|
for (int i = 0; i < numDataUnits; i++) {
|
||||||
|
fixedData[i] = generateFixedData(baseChunkSize * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate data chunk by making random data.
|
* Generate data chunk by making random data.
|
||||||
* @return
|
* @return
|
||||||
|
@ -319,6 +393,17 @@ public abstract class TestCoderBase {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected byte[] generateFixedData(int len) {
|
||||||
|
byte[] buffer = new byte[len];
|
||||||
|
for (int i = 0; i < buffer.length; i++) {
|
||||||
|
buffer[i] = (byte) FIXED_DATA_GENERATOR++;
|
||||||
|
if (FIXED_DATA_GENERATOR == 256) {
|
||||||
|
FIXED_DATA_GENERATOR = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare parity chunks for encoding, each chunk for each parity unit.
|
* Prepare parity chunks for encoding, each chunk for each parity unit.
|
||||||
* @return
|
* @return
|
||||||
|
|
|
@ -80,7 +80,13 @@ public class TestRSRawCoder extends TestRSRawCoderBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCodingDirectBuffer_10x4_erasure_of_d2_d4_p0() {
|
public void testCodingDirectBuffer_10x4_erasure_of_d2_d4_p0() {
|
||||||
prepare(null, 10, 4, new int[] {2, 4}, new int[] {0});
|
prepare(null, 10, 4, new int[]{2, 4}, new int[]{0});
|
||||||
|
testCoding(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCodingDirectBuffer_usingFixedData_10x4_erasure_of_d2_d4_p0() {
|
||||||
|
prepare(null, 10, 4, new int[] {2, 4}, new int[] {0}, true);
|
||||||
testCoding(true);
|
testCoding(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.io.erasurecode.rawcoder;
|
package org.apache.hadoop.io.erasurecode.rawcoder;
|
||||||
|
|
||||||
import org.apache.hadoop.io.erasurecode.ECChunk;
|
|
||||||
import org.apache.hadoop.io.erasurecode.rawcoder.util.RSUtil;
|
import org.apache.hadoop.io.erasurecode.rawcoder.util.RSUtil;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test base for raw Reed-solomon coders.
|
* Test base for raw Reed-solomon coders.
|
||||||
|
@ -32,6 +27,8 @@ public abstract class TestRSRawCoderBase extends TestRawCoderBase {
|
||||||
private static int symbolSize = 0;
|
private static int symbolSize = 0;
|
||||||
private static int symbolMax = 0;
|
private static int symbolMax = 0;
|
||||||
|
|
||||||
|
private static int RS_FIXED_DATA_GENERATOR = 0;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
symbolSize = (int) Math.round(Math.log(
|
symbolSize = (int) Math.round(Math.log(
|
||||||
RSUtil.GF.getFieldSize()) / Math.log(2));
|
RSUtil.GF.getFieldSize()) / Math.log(2));
|
||||||
|
@ -41,9 +38,21 @@ public abstract class TestRSRawCoderBase extends TestRawCoderBase {
|
||||||
@Override
|
@Override
|
||||||
protected byte[] generateData(int len) {
|
protected byte[] generateData(int len) {
|
||||||
byte[] buffer = new byte[len];
|
byte[] buffer = new byte[len];
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < buffer.length; i++) {
|
||||||
buffer[i] = (byte) RAND.nextInt(symbolMax);
|
buffer[i] = (byte) RAND.nextInt(symbolMax);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected byte[] generateFixedData(int len) {
|
||||||
|
byte[] buffer = new byte[len];
|
||||||
|
for (int i = 0; i < buffer.length; i++) {
|
||||||
|
buffer[i] = (byte) RS_FIXED_DATA_GENERATOR++;
|
||||||
|
if (RS_FIXED_DATA_GENERATOR == symbolMax) {
|
||||||
|
RS_FIXED_DATA_GENERATOR = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue