|
@@ -19,6 +19,8 @@ package org.apache.hadoop.ozone.common;
|
|
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.common.primitives.Longs;
|
|
import com.google.common.primitives.Longs;
|
|
|
|
+
|
|
|
|
+import java.nio.ByteBuffer;
|
|
import java.security.MessageDigest;
|
|
import java.security.MessageDigest;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
@@ -76,12 +78,13 @@ public class Checksum {
|
|
|
|
|
|
/**
|
|
/**
|
|
* Computes checksum for give data.
|
|
* Computes checksum for give data.
|
|
- * @param byteString input data in the form of ByteString.
|
|
|
|
|
|
+ * @param byteBuffer input data in the form of ByteString.
|
|
* @return ChecksumData computed for input data.
|
|
* @return ChecksumData computed for input data.
|
|
*/
|
|
*/
|
|
- public ChecksumData computeChecksum(ByteString byteString)
|
|
|
|
|
|
+ public ChecksumData computeChecksum(ByteBuffer byteBuffer)
|
|
throws OzoneChecksumException {
|
|
throws OzoneChecksumException {
|
|
- return computeChecksum(byteString.toByteArray());
|
|
|
|
|
|
+ return computeChecksum(byteBuffer.array(), byteBuffer.position(),
|
|
|
|
+ byteBuffer.limit());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -91,6 +94,16 @@ public class Checksum {
|
|
*/
|
|
*/
|
|
public ChecksumData computeChecksum(byte[] data)
|
|
public ChecksumData computeChecksum(byte[] data)
|
|
throws OzoneChecksumException {
|
|
throws OzoneChecksumException {
|
|
|
|
+ return computeChecksum(data, 0, data.length);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Computes checksum for give data.
|
|
|
|
+ * @param data input data in the form of byte array.
|
|
|
|
+ * @return ChecksumData computed for input data.
|
|
|
|
+ */
|
|
|
|
+ public ChecksumData computeChecksum(byte[] data, int offset, int len)
|
|
|
|
+ throws OzoneChecksumException {
|
|
ChecksumData checksumData = new ChecksumData(this.checksumType, this
|
|
ChecksumData checksumData = new ChecksumData(this.checksumType, this
|
|
.bytesPerChecksum);
|
|
.bytesPerChecksum);
|
|
if (checksumType == ChecksumType.NONE) {
|
|
if (checksumType == ChecksumType.NONE) {
|
|
@@ -120,7 +133,7 @@ public class Checksum {
|
|
|
|
|
|
// Compute number of checksums needs for given data length based on bytes
|
|
// Compute number of checksums needs for given data length based on bytes
|
|
// per checksum.
|
|
// per checksum.
|
|
- int dataSize = data.length;
|
|
|
|
|
|
+ int dataSize = len - offset;
|
|
int numChecksums = (dataSize + bytesPerChecksum - 1) / bytesPerChecksum;
|
|
int numChecksums = (dataSize + bytesPerChecksum - 1) / bytesPerChecksum;
|
|
|
|
|
|
// Checksum is computed for each bytesPerChecksum number of bytes of data
|
|
// Checksum is computed for each bytesPerChecksum number of bytes of data
|
|
@@ -128,7 +141,7 @@ public class Checksum {
|
|
// remaining data with length less than bytesPerChecksum.
|
|
// remaining data with length less than bytesPerChecksum.
|
|
List<ByteString> checksumList = new ArrayList<>(numChecksums);
|
|
List<ByteString> checksumList = new ArrayList<>(numChecksums);
|
|
for (int index = 0; index < numChecksums; index++) {
|
|
for (int index = 0; index < numChecksums; index++) {
|
|
- checksumList.add(computeChecksumAtIndex(data, index));
|
|
|
|
|
|
+ checksumList.add(computeChecksumAtIndex(data, index, offset, len));
|
|
}
|
|
}
|
|
checksumData.setChecksums(checksumList);
|
|
checksumData.setChecksums(checksumList);
|
|
|
|
|
|
@@ -140,15 +153,19 @@ public class Checksum {
|
|
* and a max length of bytesPerChecksum.
|
|
* and a max length of bytesPerChecksum.
|
|
* @param data input data
|
|
* @param data input data
|
|
* @param index index to compute the offset from where data must be read
|
|
* @param index index to compute the offset from where data must be read
|
|
|
|
+ * @param start start pos of the array where the computation has to start
|
|
|
|
+ * @length length of array till which checksum needs to be computed
|
|
* @return computed checksum ByteString
|
|
* @return computed checksum ByteString
|
|
* @throws OzoneChecksumException thrown when ChecksumType is not recognized
|
|
* @throws OzoneChecksumException thrown when ChecksumType is not recognized
|
|
*/
|
|
*/
|
|
- private ByteString computeChecksumAtIndex(byte[] data, int index)
|
|
|
|
|
|
+ private ByteString computeChecksumAtIndex(byte[] data, int index, int start,
|
|
|
|
+ int length)
|
|
throws OzoneChecksumException {
|
|
throws OzoneChecksumException {
|
|
- int offset = index * bytesPerChecksum;
|
|
|
|
|
|
+ int offset = start + index * bytesPerChecksum;
|
|
|
|
+ int dataLength = length - start;
|
|
int len = bytesPerChecksum;
|
|
int len = bytesPerChecksum;
|
|
- if ((offset + len) > data.length) {
|
|
|
|
- len = data.length - offset;
|
|
|
|
|
|
+ if ((offset + len) > dataLength) {
|
|
|
|
+ len = dataLength - offset;
|
|
}
|
|
}
|
|
byte[] checksumBytes = null;
|
|
byte[] checksumBytes = null;
|
|
switch (checksumType) {
|
|
switch (checksumType) {
|
|
@@ -236,7 +253,8 @@ public class Checksum {
|
|
|
|
|
|
int bytesPerChecksum = checksumData.getBytesPerChecksum();
|
|
int bytesPerChecksum = checksumData.getBytesPerChecksum();
|
|
Checksum checksum = new Checksum(checksumType, bytesPerChecksum);
|
|
Checksum checksum = new Checksum(checksumType, bytesPerChecksum);
|
|
- ChecksumData computedChecksumData = checksum.computeChecksum(data);
|
|
|
|
|
|
+ ChecksumData computedChecksumData =
|
|
|
|
+ checksum.computeChecksum(data, 0, data.length);
|
|
|
|
|
|
return checksumData.verifyChecksumDataMatches(computedChecksumData);
|
|
return checksumData.verifyChecksumDataMatches(computedChecksumData);
|
|
}
|
|
}
|