INode.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:11k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.hdfs.server.namenode;
  19. import java.io.UnsupportedEncodingException;
  20. import java.util.Arrays;
  21. import java.util.List;
  22. import org.apache.hadoop.fs.Path;
  23. import org.apache.hadoop.fs.ContentSummary;
  24. import org.apache.hadoop.fs.permission.*;
  25. import org.apache.hadoop.hdfs.protocol.Block;
  26. import org.apache.hadoop.hdfs.protocol.LocatedBlock;
  27. import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
  28. /**
  29.  * We keep an in-memory representation of the file/block hierarchy.
  30.  * This is a base INode class containing common fields for file and 
  31.  * directory inodes.
  32.  */
  33. abstract class INode implements Comparable<byte[]> {
  34.   protected byte[] name;
  35.   protected INodeDirectory parent;
  36.   protected long modificationTime;
  37.   protected long accessTime;
  38.   /** Simple wrapper for two counters : 
  39.    *  nsCount (namespace consumed) and dsCount (diskspace consumed).
  40.    */
  41.   static class DirCounts {
  42.     long nsCount = 0;
  43.     long dsCount = 0;
  44.     
  45.     /** returns namespace count */
  46.     long getNsCount() {
  47.       return nsCount;
  48.     }
  49.     /** returns diskspace count */
  50.     long getDsCount() {
  51.       return dsCount;
  52.     }
  53.   }
  54.   
  55.   //Only updated by updatePermissionStatus(...).
  56.   //Other codes should not modify it.
  57.   private long permission;
  58.   private static enum PermissionStatusFormat {
  59.     MODE(0, 16),
  60.     GROUP(MODE.OFFSET + MODE.LENGTH, 25),
  61.     USER(GROUP.OFFSET + GROUP.LENGTH, 23);
  62.     final int OFFSET;
  63.     final int LENGTH; //bit length
  64.     final long MASK;
  65.     PermissionStatusFormat(int offset, int length) {
  66.       OFFSET = offset;
  67.       LENGTH = length;
  68.       MASK = ((-1L) >>> (64 - LENGTH)) << OFFSET;
  69.     }
  70.     long retrieve(long record) {
  71.       return (record & MASK) >>> OFFSET;
  72.     }
  73.     long combine(long bits, long record) {
  74.       return (record & ~MASK) | (bits << OFFSET);
  75.     }
  76.   }
  77.   protected INode() {
  78.     name = null;
  79.     parent = null;
  80.     modificationTime = 0;
  81.     accessTime = 0;
  82.   }
  83.   INode(PermissionStatus permissions, long mTime, long atime) {
  84.     this.name = null;
  85.     this.parent = null;
  86.     this.modificationTime = mTime;
  87.     setAccessTime(atime);
  88.     setPermissionStatus(permissions);
  89.   }
  90.   protected INode(String name, PermissionStatus permissions) {
  91.     this(permissions, 0L, 0L);
  92.     setLocalName(name);
  93.   }
  94.   
  95.   /** copy constructor
  96.    * 
  97.    * @param other Other node to be copied
  98.    */
  99.   INode(INode other) {
  100.     setLocalName(other.getLocalName());
  101.     this.parent = other.getParent();
  102.     setPermissionStatus(other.getPermissionStatus());
  103.     setModificationTime(other.getModificationTime());
  104.     setAccessTime(other.getAccessTime());
  105.   }
  106.   /**
  107.    * Check whether this is the root inode.
  108.    */
  109.   boolean isRoot() {
  110.     return name.length == 0;
  111.   }
  112.   /** Set the {@link PermissionStatus} */
  113.   protected void setPermissionStatus(PermissionStatus ps) {
  114.     setUser(ps.getUserName());
  115.     setGroup(ps.getGroupName());
  116.     setPermission(ps.getPermission());
  117.   }
  118.   /** Get the {@link PermissionStatus} */
  119.   protected PermissionStatus getPermissionStatus() {
  120.     return new PermissionStatus(getUserName(),getGroupName(),getFsPermission());
  121.   }
  122.   private synchronized void updatePermissionStatus(
  123.       PermissionStatusFormat f, long n) {
  124.     permission = f.combine(n, permission);
  125.   }
  126.   /** Get user name */
  127.   public String getUserName() {
  128.     int n = (int)PermissionStatusFormat.USER.retrieve(permission);
  129.     return SerialNumberManager.INSTANCE.getUser(n);
  130.   }
  131.   /** Set user */
  132.   protected void setUser(String user) {
  133.     int n = SerialNumberManager.INSTANCE.getUserSerialNumber(user);
  134.     updatePermissionStatus(PermissionStatusFormat.USER, n);
  135.   }
  136.   /** Get group name */
  137.   public String getGroupName() {
  138.     int n = (int)PermissionStatusFormat.GROUP.retrieve(permission);
  139.     return SerialNumberManager.INSTANCE.getGroup(n);
  140.   }
  141.   /** Set group */
  142.   protected void setGroup(String group) {
  143.     int n = SerialNumberManager.INSTANCE.getGroupSerialNumber(group);
  144.     updatePermissionStatus(PermissionStatusFormat.GROUP, n);
  145.   }
  146.   /** Get the {@link FsPermission} */
  147.   public FsPermission getFsPermission() {
  148.     return new FsPermission(
  149.         (short)PermissionStatusFormat.MODE.retrieve(permission));
  150.   }
  151.   protected short getFsPermissionShort() {
  152.     return (short)PermissionStatusFormat.MODE.retrieve(permission);
  153.   }
  154.   /** Set the {@link FsPermission} of this {@link INode} */
  155.   protected void setPermission(FsPermission permission) {
  156.     updatePermissionStatus(PermissionStatusFormat.MODE, permission.toShort());
  157.   }
  158.   /**
  159.    * Check whether it's a directory
  160.    */
  161.   public abstract boolean isDirectory();
  162.   /**
  163.    * Collect all the blocks in all children of this INode.
  164.    * Count and return the number of files in the sub tree.
  165.    * Also clears references since this INode is deleted.
  166.    */
  167.   abstract int collectSubtreeBlocksAndClear(List<Block> v);
  168.   /** Compute {@link ContentSummary}. */
  169.   public final ContentSummary computeContentSummary() {
  170.     long[] a = computeContentSummary(new long[]{0,0,0,0});
  171.     return new ContentSummary(a[0], a[1], a[2], getNsQuota(), 
  172.                               a[3], getDsQuota());
  173.   }
  174.   /**
  175.    * @return an array of three longs. 
  176.    * 0: length, 1: file count, 2: directory count 3: disk space
  177.    */
  178.   abstract long[] computeContentSummary(long[] summary);
  179.   
  180.   /**
  181.    * Get the quota set for this inode
  182.    * @return the quota if it is set; -1 otherwise
  183.    */
  184.   long getNsQuota() {
  185.     return -1;
  186.   }
  187.   long getDsQuota() {
  188.     return -1;
  189.   }
  190.   
  191.   boolean isQuotaSet() {
  192.     return getNsQuota() >= 0 || getDsQuota() >= 0;
  193.   }
  194.   
  195.   /**
  196.    * Adds total nubmer of names and total disk space taken under 
  197.    * this tree to counts.
  198.    * Returns updated counts object.
  199.    */
  200.   abstract DirCounts spaceConsumedInTree(DirCounts counts);
  201.   
  202.   /**
  203.    * Get local file name
  204.    * @return local file name
  205.    */
  206.   String getLocalName() {
  207.     return bytes2String(name);
  208.   }
  209.   /**
  210.    * Get local file name
  211.    * @return local file name
  212.    */
  213.   byte[] getLocalNameBytes() {
  214.     return name;
  215.   }
  216.   /**
  217.    * Set local file name
  218.    */
  219.   void setLocalName(String name) {
  220.     this.name = string2Bytes(name);
  221.   }
  222.   /**
  223.    * Set local file name
  224.    */
  225.   void setLocalName(byte[] name) {
  226.     this.name = name;
  227.   }
  228.   /** {@inheritDoc} */
  229.   public String toString() {
  230.     return """ + getLocalName() + "":" + getPermissionStatus();
  231.   }
  232.   /**
  233.    * Get parent directory 
  234.    * @return parent INode
  235.    */
  236.   INodeDirectory getParent() {
  237.     return this.parent;
  238.   }
  239.   /** 
  240.    * Get last modification time of inode.
  241.    * @return access time
  242.    */
  243.   public long getModificationTime() {
  244.     return this.modificationTime;
  245.   }
  246.   /**
  247.    * Set last modification time of inode.
  248.    */
  249.   void setModificationTime(long modtime) {
  250.     assert isDirectory();
  251.     if (this.modificationTime <= modtime) {
  252.       this.modificationTime = modtime;
  253.     }
  254.   }
  255.   /**
  256.    * Always set the last modification time of inode.
  257.    */
  258.   void setModificationTimeForce(long modtime) {
  259.     assert !isDirectory();
  260.     this.modificationTime = modtime;
  261.   }
  262.   /**
  263.    * Get access time of inode.
  264.    * @return access time
  265.    */
  266.   public long getAccessTime() {
  267.     return accessTime;
  268.   }
  269.   /**
  270.    * Set last access time of inode.
  271.    */
  272.   void setAccessTime(long atime) {
  273.     accessTime = atime;
  274.   }
  275.   /**
  276.    * Is this inode being constructed?
  277.    */
  278.   boolean isUnderConstruction() {
  279.     return false;
  280.   }
  281.   /**
  282.    * Breaks file path into components.
  283.    * @param path
  284.    * @return array of byte arrays each of which represents 
  285.    * a single path component.
  286.    */
  287.   static byte[][] getPathComponents(String path) {
  288.     return getPathComponents(getPathNames(path));
  289.   }
  290.   /** Convert strings to byte arrays for path components. */
  291.   static byte[][] getPathComponents(String[] strings) {
  292.     if (strings.length == 0) {
  293.       return new byte[][]{null};
  294.     }
  295.     byte[][] bytes = new byte[strings.length][];
  296.     for (int i = 0; i < strings.length; i++)
  297.       bytes[i] = string2Bytes(strings[i]);
  298.     return bytes;
  299.   }
  300.   /**
  301.    * Breaks file path into names.
  302.    * @param path
  303.    * @return array of names 
  304.    */
  305.   static String[] getPathNames(String path) {
  306.     if (path == null || !path.startsWith(Path.SEPARATOR)) {
  307.       return null;
  308.     }
  309.     return path.split(Path.SEPARATOR);
  310.   }
  311.   boolean removeNode() {
  312.     if (parent == null) {
  313.       return false;
  314.     } else {
  315.       
  316.       parent.removeChild(this);
  317.       parent = null;
  318.       return true;
  319.     }
  320.   }
  321.   //
  322.   // Comparable interface
  323.   //
  324.   public int compareTo(byte[] o) {
  325.     return compareBytes(name, o);
  326.   }
  327.   public boolean equals(Object o) {
  328.     if (!(o instanceof INode)) {
  329.       return false;
  330.     }
  331.     return Arrays.equals(this.name, ((INode)o).name);
  332.   }
  333.   public int hashCode() {
  334.     return Arrays.hashCode(this.name);
  335.   }
  336.   //
  337.   // static methods
  338.   //
  339.   /**
  340.    * Compare two byte arrays.
  341.    * 
  342.    * @return a negative integer, zero, or a positive integer 
  343.    * as defined by {@link #compareTo(byte[])}.
  344.    */
  345.   static int compareBytes(byte[] a1, byte[] a2) {
  346.     if (a1==a2)
  347.         return 0;
  348.     int len1 = (a1==null ? 0 : a1.length);
  349.     int len2 = (a2==null ? 0 : a2.length);
  350.     int n = Math.min(len1, len2);
  351.     byte b1, b2;
  352.     for (int i=0; i<n; i++) {
  353.       b1 = a1[i];
  354.       b2 = a2[i];
  355.       if (b1 != b2)
  356.         return b1 - b2;
  357.     }
  358.     return len1 - len2;
  359.   }
  360.   /**
  361.    * Converts a byte array to a string using UTF8 encoding.
  362.    */
  363.   static String bytes2String(byte[] bytes) {
  364.     try {
  365.       return new String(bytes, "UTF8");
  366.     } catch(UnsupportedEncodingException e) {
  367.       assert false : "UTF8 encoding is not supported ";
  368.     }
  369.     return null;
  370.   }
  371.   /**
  372.    * Converts a string to a byte array using UTF8 encoding.
  373.    */
  374.   static byte[] string2Bytes(String str) {
  375.     try {
  376.       return str.getBytes("UTF8");
  377.     } catch(UnsupportedEncodingException e) {
  378.       assert false : "UTF8 encoding is not supported ";
  379.     }
  380.     return null;
  381.   }
  382.   
  383.   
  384.   LocatedBlocks createLocatedBlocks(List<LocatedBlock> blocks) {
  385.     return new LocatedBlocks(computeContentSummary().getLength(), blocks,
  386.         isUnderConstruction());
  387.   }
  388. }