001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hdfs.server.namenode; 019 020import java.util.Iterator; 021 022import org.apache.hadoop.fs.permission.FsPermission; 023import org.apache.hadoop.fs.permission.PermissionStatus; 024import org.apache.hadoop.hdfs.protocol.HdfsConstants; 025import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite; 026import org.apache.hadoop.util.GSet; 027import org.apache.hadoop.util.LightWeightGSet; 028 029import com.google.common.base.Preconditions; 030 031/** 032 * Storing all the {@link INode}s and maintaining the mapping between INode ID 033 * and INode. 034 */ 035public class INodeMap { 036 037 static INodeMap newInstance(INodeDirectory rootDir) { 038 // Compute the map capacity by allocating 1% of total memory 039 int capacity = LightWeightGSet.computeCapacity(1, "INodeMap"); 040 GSet<INode, INodeWithAdditionalFields> map = 041 new LightWeightGSet<>(capacity); 042 map.put(rootDir); 043 return new INodeMap(map); 044 } 045 046 /** Synchronized by external lock. */ 047 private final GSet<INode, INodeWithAdditionalFields> map; 048 049 public Iterator<INodeWithAdditionalFields> getMapIterator() { 050 return map.iterator(); 051 } 052 053 private INodeMap(GSet<INode, INodeWithAdditionalFields> map) { 054 Preconditions.checkArgument(map != null); 055 this.map = map; 056 } 057 058 /** 059 * Add an {@link INode} into the {@link INode} map. Replace the old value if 060 * necessary. 061 * @param inode The {@link INode} to be added to the map. 062 */ 063 public final void put(INode inode) { 064 if (inode instanceof INodeWithAdditionalFields) { 065 map.put((INodeWithAdditionalFields)inode); 066 } 067 } 068 069 /** 070 * Remove a {@link INode} from the map. 071 * @param inode The {@link INode} to be removed. 072 */ 073 public final void remove(INode inode) { 074 map.remove(inode); 075 } 076 077 /** 078 * @return The size of the map. 079 */ 080 public int size() { 081 return map.size(); 082 } 083 084 /** 085 * Get the {@link INode} with the given id from the map. 086 * @param id ID of the {@link INode}. 087 * @return The {@link INode} in the map with the given id. Return null if no 088 * such {@link INode} in the map. 089 */ 090 public INode get(long id) { 091 INode inode = new INodeWithAdditionalFields(id, null, new PermissionStatus( 092 "", "", new FsPermission((short) 0)), 0, 0) { 093 094 @Override 095 void recordModification(int latestSnapshotId) { 096 } 097 098 @Override 099 public void destroyAndCollectBlocks(ReclaimContext reclaimContext) { 100 // Nothing to do 101 } 102 103 @Override 104 public QuotaCounts computeQuotaUsage( 105 BlockStoragePolicySuite bsps, byte blockStoragePolicyId, 106 boolean useCache, int lastSnapshotId) { 107 return null; 108 } 109 110 @Override 111 public ContentSummaryComputationContext computeContentSummary( 112 int snapshotId, ContentSummaryComputationContext summary) { 113 return null; 114 } 115 116 @Override 117 public void cleanSubtree( 118 ReclaimContext reclaimContext, int snapshotId, int priorSnapshotId) { 119 } 120 121 @Override 122 public byte getStoragePolicyID(){ 123 return HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED; 124 } 125 126 @Override 127 public byte getLocalStoragePolicyID() { 128 return HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED; 129 } 130 }; 131 132 return map.get(inode); 133 } 134 135 /** 136 * Clear the {@link #map} 137 */ 138 public void clear() { 139 map.clear(); 140 } 141}