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