HDFS-2477. Optimize computing the diff between a block report and the namenode state. Contributed by Tomasz Nykiel.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1196676 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
bd21ddcb78
commit
a4baabe4a4
@ -52,6 +52,9 @@ Trunk (unreleased changes)
|
||||
|
||||
HDFS-2334. Add Closeable to JournalManager. (Ivan Kelly via jitendra)
|
||||
|
||||
HDFS-2477. Optimize computing the diff between a block report and the
|
||||
namenode state. (Tomasz Nykiel via hairong)
|
||||
|
||||
BUG FIXES
|
||||
HDFS-2287. TestParallelRead has a small off-by-one bug. (todd)
|
||||
|
||||
|
@ -122,6 +122,38 @@ void setNext(int index, BlockInfo to) {
|
||||
triplets[index*3+2] = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the previous block on the block list for the datanode at
|
||||
* position index. Set the previous block on the list to "to".
|
||||
*
|
||||
* @param index - the datanode index
|
||||
* @param to - block to be set to previous on the list of blocks
|
||||
* @return current previous block on the list of blocks
|
||||
*/
|
||||
BlockInfo getSetPrevious(int index, BlockInfo to) {
|
||||
assert this.triplets != null : "BlockInfo is not initialized";
|
||||
assert index >= 0 && index*3+1 < triplets.length : "Index is out of bound";
|
||||
BlockInfo info = (BlockInfo)triplets[index*3+1];
|
||||
triplets[index*3+1] = to;
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next block on the block list for the datanode at
|
||||
* position index. Set the next block on the list to "to".
|
||||
*
|
||||
* @param index - the datanode index
|
||||
* @param to - block to be set to next on the list of blocks
|
||||
* * @return current next block on the list of blocks
|
||||
*/
|
||||
BlockInfo getSetNext(int index, BlockInfo to) {
|
||||
assert this.triplets != null : "BlockInfo is not initialized";
|
||||
assert index >= 0 && index*3+2 < triplets.length : "Index is out of bound";
|
||||
BlockInfo info = (BlockInfo)triplets[index*3+2];
|
||||
triplets[index*3+2] = to;
|
||||
return info;
|
||||
}
|
||||
|
||||
int getCapacity() {
|
||||
assert this.triplets != null : "BlockInfo is not initialized";
|
||||
assert triplets.length % 3 == 0 : "Malformed BlockInfo";
|
||||
@ -259,6 +291,27 @@ public BlockInfo listRemove(BlockInfo head, DatanodeDescriptor dn) {
|
||||
return head;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this block from the list of blocks related to the specified
|
||||
* DatanodeDescriptor. Insert it into the head of the list of blocks.
|
||||
*
|
||||
* @return the new head of the list.
|
||||
*/
|
||||
public BlockInfo moveBlockToHead(BlockInfo head, DatanodeDescriptor dn,
|
||||
int curIndex, int headIndex) {
|
||||
if (head == this) {
|
||||
return this;
|
||||
}
|
||||
BlockInfo next = this.getSetNext(curIndex, head);
|
||||
BlockInfo prev = this.getSetPrevious(curIndex, null);
|
||||
|
||||
head.setPrevious(headIndex, this);
|
||||
prev.setNext(prev.findDatanode(dn), next);
|
||||
if (next != null)
|
||||
next.setPrevious(next.findDatanode(dn), prev);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* BlockInfo represents a block that is not being constructed.
|
||||
* In order to start modifying the block, the BlockInfo should be converted
|
||||
@ -317,4 +370,4 @@ public LightWeightGSet.LinkedElement getNext() {
|
||||
public void setNext(LightWeightGSet.LinkedElement next) {
|
||||
this.nextLinkedElement = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,7 @@
|
||||
*/
|
||||
@InterfaceAudience.Private
|
||||
public class BlockManager {
|
||||
|
||||
static final Log LOG = LogFactory.getLog(BlockManager.class);
|
||||
|
||||
/** Default load factor of map */
|
||||
@ -1443,7 +1444,10 @@ private void reportDiff(DatanodeDescriptor dn,
|
||||
BlockInfo delimiter = new BlockInfo(new Block(), 1);
|
||||
boolean added = dn.addBlock(delimiter);
|
||||
assert added : "Delimiting block cannot be present in the node";
|
||||
if(newReport == null)
|
||||
int headIndex = 0; //currently the delimiter is in the head of the list
|
||||
int curIndex;
|
||||
|
||||
if (newReport == null)
|
||||
newReport = new BlockListAsLongs();
|
||||
// scan the report and process newly reported blocks
|
||||
BlockReportIterator itBR = newReport.getBlockReportIterator();
|
||||
@ -1453,8 +1457,9 @@ private void reportDiff(DatanodeDescriptor dn,
|
||||
BlockInfo storedBlock = processReportedBlock(dn, iblk, iState,
|
||||
toAdd, toInvalidate, toCorrupt, toUC);
|
||||
// move block to the head of the list
|
||||
if(storedBlock != null && storedBlock.findDatanode(dn) >= 0)
|
||||
dn.moveBlockToHead(storedBlock);
|
||||
if (storedBlock != null && (curIndex = storedBlock.findDatanode(dn)) >= 0) {
|
||||
headIndex = dn.moveBlockToHead(storedBlock, curIndex, headIndex);
|
||||
}
|
||||
}
|
||||
// collect blocks that have not been reported
|
||||
// all of them are next to the delimiter
|
||||
|
@ -244,15 +244,24 @@ public boolean removeBlock(BlockInfo b) {
|
||||
|
||||
/**
|
||||
* Move block to the head of the list of blocks belonging to the data-node.
|
||||
* @return the index of the head of the blockList
|
||||
*/
|
||||
void moveBlockToHead(BlockInfo b) {
|
||||
blockList = b.listRemove(blockList, this);
|
||||
blockList = b.listInsert(blockList, this);
|
||||
int moveBlockToHead(BlockInfo b, int curIndex, int headIndex) {
|
||||
blockList = b.moveBlockToHead(blockList, this, curIndex, headIndex);
|
||||
return curIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for testing only
|
||||
* @return the head of the blockList
|
||||
*/
|
||||
protected BlockInfo getHead(){
|
||||
return blockList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace specified old block with a new one in the DataNodeDescriptor.
|
||||
*
|
||||
*
|
||||
* @param oldBlock - block to be replaced
|
||||
* @param newBlock - a replacement block
|
||||
* @return the new block
|
||||
|
Loading…
Reference in New Issue
Block a user