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; 021import java.util.List; 022 023import org.apache.hadoop.fs.permission.FsPermission; 024import org.apache.hadoop.fs.permission.PermissionStatus; 025import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy; 026import org.apache.hadoop.hdfs.protocol.QuotaExceededException; 027import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite; 028import org.apache.hadoop.hdfs.server.namenode.Quota.Counts; 029import org.apache.hadoop.util.GSet; 030import org.apache.hadoop.util.LightWeightGSet; 031 032import com.google.common.base.Preconditions; 033 034/** 035 * Storing all the {@link INode}s and maintaining the mapping between INode ID 036 * and INode. 037 */ 038public class INodeMap { 039 040 static INodeMap newInstance(INodeDirectory rootDir) { 041 // Compute the map capacity by allocating 1% of total memory 042 int capacity = LightWeightGSet.computeCapacity(1, "INodeMap"); 043 GSet<INode, INodeWithAdditionalFields> map 044 = new LightWeightGSet<INode, INodeWithAdditionalFields>(capacity); 045 map.put(rootDir); 046 return new INodeMap(map); 047 } 048 049 /** Synchronized by external lock. */ 050 private final GSet<INode, INodeWithAdditionalFields> map; 051 052 public Iterator<INodeWithAdditionalFields> getMapIterator() { 053 return map.iterator(); 054 } 055 056 private INodeMap(GSet<INode, INodeWithAdditionalFields> map) { 057 Preconditions.checkArgument(map != null); 058 this.map = map; 059 } 060 061 /** 062 * Add an {@link INode} into the {@link INode} map. Replace the old value if 063 * necessary. 064 * @param inode The {@link INode} to be added to the map. 065 */ 066 public final void put(INode inode) { 067 if (inode instanceof INodeWithAdditionalFields) { 068 map.put((INodeWithAdditionalFields)inode); 069 } 070 } 071 072 /** 073 * Remove a {@link INode} from the map. 074 * @param inode The {@link INode} to be removed. 075 */ 076 public final void remove(INode inode) { 077 map.remove(inode); 078 } 079 080 /** 081 * @return The size of the map. 082 */ 083 public int size() { 084 return map.size(); 085 } 086 087 /** 088 * Get the {@link INode} with the given id from the map. 089 * @param id ID of the {@link INode}. 090 * @return The {@link INode} in the map with the given id. Return null if no 091 * such {@link INode} in the map. 092 */ 093 public INode get(long id) { 094 INode inode = new INodeWithAdditionalFields(id, null, new PermissionStatus( 095 "", "", new FsPermission((short) 0)), 0, 0) { 096 097 @Override 098 void recordModification(int latestSnapshotId) 099 throws QuotaExceededException { 100 } 101 102 @Override 103 public void destroyAndCollectBlocks(BlocksMapUpdateInfo collectedBlocks, 104 List<INode> removedINodes) { 105 // Nothing to do 106 } 107 108 @Override 109 public Counts computeQuotaUsage(Counts counts, boolean useCache, 110 int lastSnapshotId) { 111 return null; 112 } 113 114 @Override 115 public ContentSummaryComputationContext computeContentSummary( 116 ContentSummaryComputationContext summary) { 117 return null; 118 } 119 120 @Override 121 public Counts cleanSubtree(int snapshotId, int priorSnapshotId, 122 BlocksMapUpdateInfo collectedBlocks, List<INode> removedINodes, 123 boolean countDiffChange) throws QuotaExceededException { 124 return null; 125 } 126 127 @Override 128 public byte getStoragePolicyID(){ 129 return BlockStoragePolicySuite.ID_UNSPECIFIED; 130 } 131 132 @Override 133 public byte getLocalStoragePolicyID() { 134 return BlockStoragePolicySuite.ID_UNSPECIFIED; 135 } 136 }; 137 138 return map.get(inode); 139 } 140 141 /** 142 * Clear the {@link #map} 143 */ 144 public void clear() { 145 map.clear(); 146 } 147}