INode.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:11k
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.hadoop.hdfs.server.namenode;
- import java.io.UnsupportedEncodingException;
- import java.util.Arrays;
- import java.util.List;
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.fs.ContentSummary;
- import org.apache.hadoop.fs.permission.*;
- import org.apache.hadoop.hdfs.protocol.Block;
- import org.apache.hadoop.hdfs.protocol.LocatedBlock;
- import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
- /**
- * We keep an in-memory representation of the file/block hierarchy.
- * This is a base INode class containing common fields for file and
- * directory inodes.
- */
- abstract class INode implements Comparable<byte[]> {
- protected byte[] name;
- protected INodeDirectory parent;
- protected long modificationTime;
- protected long accessTime;
- /** Simple wrapper for two counters :
- * nsCount (namespace consumed) and dsCount (diskspace consumed).
- */
- static class DirCounts {
- long nsCount = 0;
- long dsCount = 0;
-
- /** returns namespace count */
- long getNsCount() {
- return nsCount;
- }
- /** returns diskspace count */
- long getDsCount() {
- return dsCount;
- }
- }
-
- //Only updated by updatePermissionStatus(...).
- //Other codes should not modify it.
- private long permission;
- private static enum PermissionStatusFormat {
- MODE(0, 16),
- GROUP(MODE.OFFSET + MODE.LENGTH, 25),
- USER(GROUP.OFFSET + GROUP.LENGTH, 23);
- final int OFFSET;
- final int LENGTH; //bit length
- final long MASK;
- PermissionStatusFormat(int offset, int length) {
- OFFSET = offset;
- LENGTH = length;
- MASK = ((-1L) >>> (64 - LENGTH)) << OFFSET;
- }
- long retrieve(long record) {
- return (record & MASK) >>> OFFSET;
- }
- long combine(long bits, long record) {
- return (record & ~MASK) | (bits << OFFSET);
- }
- }
- protected INode() {
- name = null;
- parent = null;
- modificationTime = 0;
- accessTime = 0;
- }
- INode(PermissionStatus permissions, long mTime, long atime) {
- this.name = null;
- this.parent = null;
- this.modificationTime = mTime;
- setAccessTime(atime);
- setPermissionStatus(permissions);
- }
- protected INode(String name, PermissionStatus permissions) {
- this(permissions, 0L, 0L);
- setLocalName(name);
- }
-
- /** copy constructor
- *
- * @param other Other node to be copied
- */
- INode(INode other) {
- setLocalName(other.getLocalName());
- this.parent = other.getParent();
- setPermissionStatus(other.getPermissionStatus());
- setModificationTime(other.getModificationTime());
- setAccessTime(other.getAccessTime());
- }
- /**
- * Check whether this is the root inode.
- */
- boolean isRoot() {
- return name.length == 0;
- }
- /** Set the {@link PermissionStatus} */
- protected void setPermissionStatus(PermissionStatus ps) {
- setUser(ps.getUserName());
- setGroup(ps.getGroupName());
- setPermission(ps.getPermission());
- }
- /** Get the {@link PermissionStatus} */
- protected PermissionStatus getPermissionStatus() {
- return new PermissionStatus(getUserName(),getGroupName(),getFsPermission());
- }
- private synchronized void updatePermissionStatus(
- PermissionStatusFormat f, long n) {
- permission = f.combine(n, permission);
- }
- /** Get user name */
- public String getUserName() {
- int n = (int)PermissionStatusFormat.USER.retrieve(permission);
- return SerialNumberManager.INSTANCE.getUser(n);
- }
- /** Set user */
- protected void setUser(String user) {
- int n = SerialNumberManager.INSTANCE.getUserSerialNumber(user);
- updatePermissionStatus(PermissionStatusFormat.USER, n);
- }
- /** Get group name */
- public String getGroupName() {
- int n = (int)PermissionStatusFormat.GROUP.retrieve(permission);
- return SerialNumberManager.INSTANCE.getGroup(n);
- }
- /** Set group */
- protected void setGroup(String group) {
- int n = SerialNumberManager.INSTANCE.getGroupSerialNumber(group);
- updatePermissionStatus(PermissionStatusFormat.GROUP, n);
- }
- /** Get the {@link FsPermission} */
- public FsPermission getFsPermission() {
- return new FsPermission(
- (short)PermissionStatusFormat.MODE.retrieve(permission));
- }
- protected short getFsPermissionShort() {
- return (short)PermissionStatusFormat.MODE.retrieve(permission);
- }
- /** Set the {@link FsPermission} of this {@link INode} */
- protected void setPermission(FsPermission permission) {
- updatePermissionStatus(PermissionStatusFormat.MODE, permission.toShort());
- }
- /**
- * Check whether it's a directory
- */
- public abstract boolean isDirectory();
- /**
- * Collect all the blocks in all children of this INode.
- * Count and return the number of files in the sub tree.
- * Also clears references since this INode is deleted.
- */
- abstract int collectSubtreeBlocksAndClear(List<Block> v);
- /** Compute {@link ContentSummary}. */
- public final ContentSummary computeContentSummary() {
- long[] a = computeContentSummary(new long[]{0,0,0,0});
- return new ContentSummary(a[0], a[1], a[2], getNsQuota(),
- a[3], getDsQuota());
- }
- /**
- * @return an array of three longs.
- * 0: length, 1: file count, 2: directory count 3: disk space
- */
- abstract long[] computeContentSummary(long[] summary);
-
- /**
- * Get the quota set for this inode
- * @return the quota if it is set; -1 otherwise
- */
- long getNsQuota() {
- return -1;
- }
- long getDsQuota() {
- return -1;
- }
-
- boolean isQuotaSet() {
- return getNsQuota() >= 0 || getDsQuota() >= 0;
- }
-
- /**
- * Adds total nubmer of names and total disk space taken under
- * this tree to counts.
- * Returns updated counts object.
- */
- abstract DirCounts spaceConsumedInTree(DirCounts counts);
-
- /**
- * Get local file name
- * @return local file name
- */
- String getLocalName() {
- return bytes2String(name);
- }
- /**
- * Get local file name
- * @return local file name
- */
- byte[] getLocalNameBytes() {
- return name;
- }
- /**
- * Set local file name
- */
- void setLocalName(String name) {
- this.name = string2Bytes(name);
- }
- /**
- * Set local file name
- */
- void setLocalName(byte[] name) {
- this.name = name;
- }
- /** {@inheritDoc} */
- public String toString() {
- return """ + getLocalName() + "":" + getPermissionStatus();
- }
- /**
- * Get parent directory
- * @return parent INode
- */
- INodeDirectory getParent() {
- return this.parent;
- }
- /**
- * Get last modification time of inode.
- * @return access time
- */
- public long getModificationTime() {
- return this.modificationTime;
- }
- /**
- * Set last modification time of inode.
- */
- void setModificationTime(long modtime) {
- assert isDirectory();
- if (this.modificationTime <= modtime) {
- this.modificationTime = modtime;
- }
- }
- /**
- * Always set the last modification time of inode.
- */
- void setModificationTimeForce(long modtime) {
- assert !isDirectory();
- this.modificationTime = modtime;
- }
- /**
- * Get access time of inode.
- * @return access time
- */
- public long getAccessTime() {
- return accessTime;
- }
- /**
- * Set last access time of inode.
- */
- void setAccessTime(long atime) {
- accessTime = atime;
- }
- /**
- * Is this inode being constructed?
- */
- boolean isUnderConstruction() {
- return false;
- }
- /**
- * Breaks file path into components.
- * @param path
- * @return array of byte arrays each of which represents
- * a single path component.
- */
- static byte[][] getPathComponents(String path) {
- return getPathComponents(getPathNames(path));
- }
- /** Convert strings to byte arrays for path components. */
- static byte[][] getPathComponents(String[] strings) {
- if (strings.length == 0) {
- return new byte[][]{null};
- }
- byte[][] bytes = new byte[strings.length][];
- for (int i = 0; i < strings.length; i++)
- bytes[i] = string2Bytes(strings[i]);
- return bytes;
- }
- /**
- * Breaks file path into names.
- * @param path
- * @return array of names
- */
- static String[] getPathNames(String path) {
- if (path == null || !path.startsWith(Path.SEPARATOR)) {
- return null;
- }
- return path.split(Path.SEPARATOR);
- }
- boolean removeNode() {
- if (parent == null) {
- return false;
- } else {
-
- parent.removeChild(this);
- parent = null;
- return true;
- }
- }
- //
- // Comparable interface
- //
- public int compareTo(byte[] o) {
- return compareBytes(name, o);
- }
- public boolean equals(Object o) {
- if (!(o instanceof INode)) {
- return false;
- }
- return Arrays.equals(this.name, ((INode)o).name);
- }
- public int hashCode() {
- return Arrays.hashCode(this.name);
- }
- //
- // static methods
- //
- /**
- * Compare two byte arrays.
- *
- * @return a negative integer, zero, or a positive integer
- * as defined by {@link #compareTo(byte[])}.
- */
- static int compareBytes(byte[] a1, byte[] a2) {
- if (a1==a2)
- return 0;
- int len1 = (a1==null ? 0 : a1.length);
- int len2 = (a2==null ? 0 : a2.length);
- int n = Math.min(len1, len2);
- byte b1, b2;
- for (int i=0; i<n; i++) {
- b1 = a1[i];
- b2 = a2[i];
- if (b1 != b2)
- return b1 - b2;
- }
- return len1 - len2;
- }
- /**
- * Converts a byte array to a string using UTF8 encoding.
- */
- static String bytes2String(byte[] bytes) {
- try {
- return new String(bytes, "UTF8");
- } catch(UnsupportedEncodingException e) {
- assert false : "UTF8 encoding is not supported ";
- }
- return null;
- }
- /**
- * Converts a string to a byte array using UTF8 encoding.
- */
- static byte[] string2Bytes(String str) {
- try {
- return str.getBytes("UTF8");
- } catch(UnsupportedEncodingException e) {
- assert false : "UTF8 encoding is not supported ";
- }
- return null;
- }
-
-
- LocatedBlocks createLocatedBlocks(List<LocatedBlock> blocks) {
- return new LocatedBlocks(computeContentSummary().getLength(), blocks,
- isUnderConstruction());
- }
- }