Skip to content

Commit

Permalink
HDFS-8190. StripedBlockUtil.getInternalBlockLength may have overflow …
Browse files Browse the repository at this point in the history
…error.
  • Loading branch information
Tsz-Wo Nicholas Sze authored and Zhe Zhang committed May 26, 2015
1 parent 922631f commit e107886
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 142 deletions.
3 changes: 3 additions & 0 deletions hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-EC-7285.txt
Expand Up @@ -104,3 +104,6 @@


HDFS-8181. createErasureCodingZone sets retryCache state as false always HDFS-8181. createErasureCodingZone sets retryCache state as false always
(Uma Maheswara Rao G via vinayakumarb) (Uma Maheswara Rao G via vinayakumarb)

HDFS-8190. StripedBlockUtil.getInternalBlockLength may have overflow error.
(szetszwo)
Expand Up @@ -25,6 +25,8 @@
import org.apache.hadoop.hdfs.protocol.LocatedBlock; import org.apache.hadoop.hdfs.protocol.LocatedBlock;
import org.apache.hadoop.hdfs.protocol.LocatedStripedBlock; import org.apache.hadoop.hdfs.protocol.LocatedStripedBlock;


import com.google.common.base.Preconditions;

/** /**
* Utility class for analyzing striped block groups * Utility class for analyzing striped block groups
*/ */
Expand Down Expand Up @@ -81,46 +83,43 @@ public static LocatedBlock constructInternalBlock(LocatedStripedBlock bg,
/** /**
* Get the size of an internal block at the given index of a block group * Get the size of an internal block at the given index of a block group
* *
* @param numBytesInGroup Size of the block group only counting data blocks * @param dataSize Size of the block group only counting data blocks
* @param cellSize The size of a striping cell * @param cellSize The size of a striping cell
* @param dataBlkNum The number of data blocks * @param numDataBlocks The number of data blocks
* @param idxInGroup The logical index in the striped block group * @param i The logical index in the striped block group
* @return The size of the internal block at the specified index * @return The size of the internal block at the specified index
*/ */
public static long getInternalBlockLength(long numBytesInGroup, public static long getInternalBlockLength(long dataSize,
int cellSize, int dataBlkNum, int idxInGroup) { int cellSize, int numDataBlocks, int i) {
Preconditions.checkArgument(dataSize >= 0);
Preconditions.checkArgument(cellSize > 0);
Preconditions.checkArgument(numDataBlocks > 0);
Preconditions.checkArgument(i >= 0);
// Size of each stripe (only counting data blocks) // Size of each stripe (only counting data blocks)
final long numBytesPerStripe = cellSize * dataBlkNum; final int stripeSize = cellSize * numDataBlocks;
assert numBytesPerStripe > 0:
"getInternalBlockLength should only be called on valid striped blocks";
// If block group ends at stripe boundary, each internal block has an equal // If block group ends at stripe boundary, each internal block has an equal
// share of the group // share of the group
if (numBytesInGroup % numBytesPerStripe == 0) { final int lastStripeDataLen = (int)(dataSize % stripeSize);
return numBytesInGroup / dataBlkNum; if (lastStripeDataLen == 0) {
return dataSize / numDataBlocks;
} }


int numStripes = (int) ((numBytesInGroup - 1) / numBytesPerStripe + 1); final int numStripes = (int) ((dataSize - 1) / stripeSize + 1);
assert numStripes >= 1 : "There should be at least 1 stripe"; return (numStripes - 1L)*cellSize

+ lastCellSize(lastStripeDataLen, cellSize, numDataBlocks, i);
// All stripes but the last one are full stripes. The block should at least }
// contain (numStripes - 1) full cells.
long blkSize = (numStripes - 1) * cellSize; private static int lastCellSize(int size, int cellSize, int numDataBlocks,

int i) {
long lastStripeLen = numBytesInGroup % numBytesPerStripe; if (i < numDataBlocks) {
// Size of parity cells should equal the size of the first cell, if it // parity block size (i.e. i >= numDataBlocks) is the same as
// is not full. // the first data block size (i.e. i = 0).
long lastParityCellLen = Math.min(cellSize, lastStripeLen); size -= i*cellSize;

if (size < 0) {
if (idxInGroup >= dataBlkNum) { size = 0;
// for parity blocks }
blkSize += lastParityCellLen;
} else {
// for data blocks
blkSize += Math.min(cellSize,
Math.max(0, lastStripeLen - cellSize * idxInGroup));
} }

return size > cellSize? cellSize: size;
return blkSize;
} }


/** /**
Expand Down

0 comments on commit e107886

Please sign in to comment.