|
@@ -17,12 +17,11 @@
|
|
|
*/
|
|
|
package org.apache.hadoop.hdfs.server.namenode;
|
|
|
|
|
|
-import java.util.Collection;
|
|
|
-import java.util.HashMap;
|
|
|
import java.util.Iterator;
|
|
|
-import java.util.Map;
|
|
|
|
|
|
import org.apache.hadoop.hdfs.protocol.Block;
|
|
|
+import org.apache.hadoop.hdfs.util.GSet;
|
|
|
+import org.apache.hadoop.hdfs.util.GSetByHashMap;
|
|
|
|
|
|
/**
|
|
|
* This class maintains the map from a block to its metadata.
|
|
@@ -56,7 +55,7 @@ class BlocksMap {
|
|
|
private int capacity;
|
|
|
private final float loadFactor;
|
|
|
|
|
|
- private Map<BlockInfo, BlockInfo> map;
|
|
|
+ private GSet<Block, BlockInfo> blocks;
|
|
|
|
|
|
BlocksMap(int initialCapacity, float loadFactor) {
|
|
|
this.capacity = 1;
|
|
@@ -64,11 +63,12 @@ class BlocksMap {
|
|
|
while (this.capacity < initialCapacity)
|
|
|
this.capacity <<= 1;
|
|
|
this.loadFactor = loadFactor;
|
|
|
- this.map = new HashMap<BlockInfo, BlockInfo>(initialCapacity, loadFactor);
|
|
|
+ this.blocks = new GSetByHashMap<Block, BlockInfo>(
|
|
|
+ initialCapacity, loadFactor);
|
|
|
}
|
|
|
|
|
|
INodeFile getINode(Block b) {
|
|
|
- BlockInfo info = map.get(b);
|
|
|
+ BlockInfo info = blocks.get(b);
|
|
|
return (info != null) ? info.getINode() : null;
|
|
|
}
|
|
|
|
|
@@ -76,10 +76,10 @@ class BlocksMap {
|
|
|
* Add block b belonging to the specified file inode to the map.
|
|
|
*/
|
|
|
BlockInfo addINode(BlockInfo b, INodeFile iNode) {
|
|
|
- BlockInfo info = map.get(b);
|
|
|
+ BlockInfo info = blocks.get(b);
|
|
|
if (info != b) {
|
|
|
info = b;
|
|
|
- map.put(info, info);
|
|
|
+ blocks.put(info);
|
|
|
}
|
|
|
info.setINode(iNode);
|
|
|
return info;
|
|
@@ -91,7 +91,7 @@ class BlocksMap {
|
|
|
* and remove all data-node locations associated with the block.
|
|
|
*/
|
|
|
void removeBlock(Block block) {
|
|
|
- BlockInfo blockInfo = map.remove(block);
|
|
|
+ BlockInfo blockInfo = blocks.remove(block);
|
|
|
if (blockInfo == null)
|
|
|
return;
|
|
|
|
|
@@ -104,7 +104,7 @@ class BlocksMap {
|
|
|
|
|
|
/** Returns the block object it it exists in the map. */
|
|
|
BlockInfo getStoredBlock(Block b) {
|
|
|
- return map.get(b);
|
|
|
+ return blocks.get(b);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -112,7 +112,7 @@ class BlocksMap {
|
|
|
* returns Iterator that iterates through the nodes the block belongs to.
|
|
|
*/
|
|
|
Iterator<DatanodeDescriptor> nodeIterator(Block b) {
|
|
|
- return nodeIterator(map.get(b));
|
|
|
+ return nodeIterator(blocks.get(b));
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -125,7 +125,7 @@ class BlocksMap {
|
|
|
|
|
|
/** counts number of containing nodes. Better than using iterator. */
|
|
|
int numNodes(Block b) {
|
|
|
- BlockInfo info = map.get(b);
|
|
|
+ BlockInfo info = blocks.get(b);
|
|
|
return info == null ? 0 : info.numNodes();
|
|
|
}
|
|
|
|
|
@@ -135,7 +135,7 @@ class BlocksMap {
|
|
|
* only if it does not belong to any file and data-nodes.
|
|
|
*/
|
|
|
boolean removeNode(Block b, DatanodeDescriptor node) {
|
|
|
- BlockInfo info = map.get(b);
|
|
|
+ BlockInfo info = blocks.get(b);
|
|
|
if (info == null)
|
|
|
return false;
|
|
|
|
|
@@ -144,30 +144,31 @@ class BlocksMap {
|
|
|
|
|
|
if (info.getDatanode(0) == null // no datanodes left
|
|
|
&& info.getINode() == null) { // does not belong to a file
|
|
|
- map.remove(b); // remove block from the map
|
|
|
+ blocks.remove(b); // remove block from the map
|
|
|
}
|
|
|
return removed;
|
|
|
}
|
|
|
|
|
|
int size() {
|
|
|
- return map.size();
|
|
|
+ return blocks.size();
|
|
|
}
|
|
|
|
|
|
- Collection<BlockInfo> getBlocks() {
|
|
|
- return map.values();
|
|
|
+ Iterable<BlockInfo> getBlocks() {
|
|
|
+ return blocks;
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* Check if the block exists in map
|
|
|
*/
|
|
|
boolean contains(Block block) {
|
|
|
- return map.containsKey(block);
|
|
|
+ return blocks.contains(block);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Check if the replica at the given datanode exists in map
|
|
|
*/
|
|
|
boolean contains(Block block, DatanodeDescriptor datanode) {
|
|
|
- BlockInfo info = map.get(block);
|
|
|
+ BlockInfo info = blocks.get(block);
|
|
|
if (info == null)
|
|
|
return false;
|
|
|
|
|
@@ -180,16 +181,11 @@ class BlocksMap {
|
|
|
/** Get the capacity of the HashMap that stores blocks */
|
|
|
int getCapacity() {
|
|
|
// Capacity doubles every time the map size reaches the threshold
|
|
|
- while (map.size() > (int)(capacity * loadFactor)) {
|
|
|
+ while (blocks.size() > (int)(capacity * loadFactor)) {
|
|
|
capacity <<= 1;
|
|
|
}
|
|
|
return capacity;
|
|
|
}
|
|
|
-
|
|
|
- /** Get the load factor of the map */
|
|
|
- float getLoadFactor() {
|
|
|
- return loadFactor;
|
|
|
- }
|
|
|
|
|
|
/**
|
|
|
* Replace a block in the block map by a new block.
|
|
@@ -198,7 +194,7 @@ class BlocksMap {
|
|
|
* @return new block
|
|
|
*/
|
|
|
BlockInfo replaceBlock(BlockInfo newBlock) {
|
|
|
- BlockInfo currentBlock = map.get(newBlock);
|
|
|
+ BlockInfo currentBlock = blocks.get(newBlock);
|
|
|
assert currentBlock != null : "the block if not in blocksMap";
|
|
|
// replace block in data-node lists
|
|
|
for(int idx = currentBlock.numNodes()-1; idx >= 0; idx--) {
|
|
@@ -206,7 +202,7 @@ class BlocksMap {
|
|
|
dn.replaceBlock(currentBlock, newBlock);
|
|
|
}
|
|
|
// replace block in the map itself
|
|
|
- map.put(newBlock, newBlock);
|
|
|
+ blocks.put(newBlock);
|
|
|
return newBlock;
|
|
|
}
|
|
|
}
|