|
@@ -32,6 +32,7 @@ import java.nio.ByteBuffer;
|
|
|
public abstract class AbstractRawErasureCoder
|
|
|
extends Configured implements RawErasureCoder {
|
|
|
|
|
|
+ private static byte[] emptyChunk = new byte[4096];
|
|
|
private final int numDataUnits;
|
|
|
private final int numParityUnits;
|
|
|
private final int numAllUnits;
|
|
@@ -42,6 +43,23 @@ public abstract class AbstractRawErasureCoder
|
|
|
this.numAllUnits = numDataUnits + numParityUnits;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Make sure to return an empty chunk buffer for the desired length.
|
|
|
+ * @param leastLength
|
|
|
+ * @return empty chunk of zero bytes
|
|
|
+ */
|
|
|
+ protected static byte[] getEmptyChunk(int leastLength) {
|
|
|
+ if (emptyChunk.length >= leastLength) {
|
|
|
+ return emptyChunk; // In most time
|
|
|
+ }
|
|
|
+
|
|
|
+ synchronized (AbstractRawErasureCoder.class) {
|
|
|
+ emptyChunk = new byte[leastLength];
|
|
|
+ }
|
|
|
+
|
|
|
+ return emptyChunk;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public int getNumDataUnits() {
|
|
|
return numDataUnits;
|
|
@@ -73,11 +91,9 @@ public abstract class AbstractRawErasureCoder
|
|
|
* @return the buffer itself, with ZERO bytes written, the position and limit
|
|
|
* are not changed after the call
|
|
|
*/
|
|
|
- protected ByteBuffer resetBuffer(ByteBuffer buffer) {
|
|
|
+ protected ByteBuffer resetBuffer(ByteBuffer buffer, int len) {
|
|
|
int pos = buffer.position();
|
|
|
- for (int i = pos; i < buffer.limit(); ++i) {
|
|
|
- buffer.put((byte) 0);
|
|
|
- }
|
|
|
+ buffer.put(getEmptyChunk(len), 0, len);
|
|
|
buffer.position(pos);
|
|
|
|
|
|
return buffer;
|
|
@@ -90,9 +106,8 @@ public abstract class AbstractRawErasureCoder
|
|
|
* @return the buffer itself
|
|
|
*/
|
|
|
protected byte[] resetBuffer(byte[] buffer, int offset, int len) {
|
|
|
- for (int i = offset; i < len; ++i) {
|
|
|
- buffer[i] = (byte) 0;
|
|
|
- }
|
|
|
+ byte[] empty = getEmptyChunk(len);
|
|
|
+ System.arraycopy(empty, 0, buffer, offset, len);
|
|
|
|
|
|
return buffer;
|
|
|
}
|
|
@@ -104,9 +119,10 @@ public abstract class AbstractRawErasureCoder
|
|
|
* @param allowNull whether to allow any element to be null or not
|
|
|
* @param dataLen the length of data available in the buffer to ensure with
|
|
|
* @param isDirectBuffer is direct buffer or not to ensure with
|
|
|
+ * @param isOutputs is output buffer or not
|
|
|
*/
|
|
|
- protected void ensureLengthAndType(ByteBuffer[] buffers, boolean allowNull,
|
|
|
- int dataLen, boolean isDirectBuffer) {
|
|
|
+ protected void checkParameterBuffers(ByteBuffer[] buffers, boolean
|
|
|
+ allowNull, int dataLen, boolean isDirectBuffer, boolean isOutputs) {
|
|
|
for (ByteBuffer buffer : buffers) {
|
|
|
if (buffer == null && !allowNull) {
|
|
|
throw new HadoopIllegalArgumentException(
|
|
@@ -120,18 +136,23 @@ public abstract class AbstractRawErasureCoder
|
|
|
throw new HadoopIllegalArgumentException(
|
|
|
"Invalid buffer, isDirect should be " + isDirectBuffer);
|
|
|
}
|
|
|
+ if (isOutputs) {
|
|
|
+ resetBuffer(buffer, dataLen);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Check and ensure the buffers are of the length specified by dataLen.
|
|
|
+ * Check and ensure the buffers are of the length specified by dataLen. If is
|
|
|
+ * output buffers, ensure they will be ZEROed.
|
|
|
* @param buffers the buffers to check
|
|
|
* @param allowNull whether to allow any element to be null or not
|
|
|
* @param dataLen the length of data available in the buffer to ensure with
|
|
|
+ * @param isOutputs is output buffer or not
|
|
|
*/
|
|
|
- protected void ensureLength(byte[][] buffers,
|
|
|
- boolean allowNull, int dataLen) {
|
|
|
+ protected void checkParameterBuffers(byte[][] buffers, boolean allowNull,
|
|
|
+ int dataLen, boolean isOutputs) {
|
|
|
for (byte[] buffer : buffers) {
|
|
|
if (buffer == null && !allowNull) {
|
|
|
throw new HadoopIllegalArgumentException(
|
|
@@ -139,6 +160,8 @@ public abstract class AbstractRawErasureCoder
|
|
|
} else if (buffer != null && buffer.length != dataLen) {
|
|
|
throw new HadoopIllegalArgumentException(
|
|
|
"Invalid buffer not of length " + dataLen);
|
|
|
+ } else if (isOutputs) {
|
|
|
+ resetBuffer(buffer, 0, dataLen);
|
|
|
}
|
|
|
}
|
|
|
}
|