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

网格计算

开发平台:

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.fs;
  19. import org.apache.hadoop.conf.Configuration;
  20. import org.apache.hadoop.util.Shell;
  21. import java.io.BufferedReader;
  22. import java.io.File;
  23. import java.io.IOException;
  24. import java.util.concurrent.atomic.AtomicLong;
  25. /** Filesystem disk space usage statistics.  Uses the unix 'du' program*/
  26. public class DU extends Shell {
  27.   private String  dirPath;
  28.   private AtomicLong used = new AtomicLong();
  29.   private volatile boolean shouldRun = true;
  30.   private Thread refreshUsed;
  31.   private IOException duException = null;
  32.   private long refreshInterval;
  33.   
  34.   /**
  35.    * Keeps track of disk usage.
  36.    * @param path the path to check disk usage in
  37.    * @param interval refresh the disk usage at this interval
  38.    * @throws IOException if we fail to refresh the disk usage
  39.    */
  40.   public DU(File path, long interval) throws IOException {
  41.     super(0);
  42.     
  43.     //we set the Shell interval to 0 so it will always run our command
  44.     //and use this one to set the thread sleep interval
  45.     this.refreshInterval = interval;
  46.     this.dirPath = path.getCanonicalPath();
  47.     
  48.     //populate the used variable
  49.     run();
  50.   }
  51.   
  52.   /**
  53.    * Keeps track of disk usage.
  54.    * @param path the path to check disk usage in
  55.    * @param conf configuration object
  56.    * @throws IOException if we fail to refresh the disk usage
  57.    */
  58.   public DU(File path, Configuration conf) throws IOException {
  59.     this(path, 600000L);
  60.     //10 minutes default refresh interval
  61.   }
  62.   /**
  63.    * This thread refreshes the "used" variable.
  64.    * 
  65.    * Future improvements could be to not permanently
  66.    * run this thread, instead run when getUsed is called.
  67.    **/
  68.   class DURefreshThread implements Runnable {
  69.     
  70.     public void run() {
  71.       
  72.       while(shouldRun) {
  73.         try {
  74.           Thread.sleep(refreshInterval);
  75.           
  76.           try {
  77.             //update the used variable
  78.             DU.this.run();
  79.           } catch (IOException e) {
  80.             synchronized (DU.this) {
  81.               //save the latest exception so we can return it in getUsed()
  82.               duException = e;
  83.             }
  84.             
  85.             LOG.warn("Could not get disk usage information", e);
  86.           }
  87.         } catch (InterruptedException e) {
  88.         }
  89.       }
  90.     }
  91.   }
  92.   
  93.   /**
  94.    * Decrease how much disk space we use.
  95.    * @param value decrease by this value
  96.    */
  97.   public void decDfsUsed(long value) {
  98.     used.addAndGet(-value);
  99.   }
  100.   /**
  101.    * Increase how much disk space we use.
  102.    * @param value increase by this value
  103.    */
  104.   public void incDfsUsed(long value) {
  105.     used.addAndGet(value);
  106.   }
  107.   
  108.   /**
  109.    * @return disk space used 
  110.    * @throws IOException if the shell command fails
  111.    */
  112.   public long getUsed() throws IOException {
  113.     //if the updating thread isn't started, update on demand
  114.     if(refreshUsed == null) {
  115.       run();
  116.     } else {
  117.       synchronized (DU.this) {
  118.         //if an exception was thrown in the last run, rethrow
  119.         if(duException != null) {
  120.           IOException tmp = duException;
  121.           duException = null;
  122.           throw tmp;
  123.         }
  124.       }
  125.     }
  126.     
  127.     return used.longValue();
  128.   }
  129.   /**
  130.    * @return the path of which we're keeping track of disk usage
  131.    */
  132.   public String getDirPath() {
  133.     return dirPath;
  134.   }
  135.   
  136.   /**
  137.    * Start the disk usage checking thread.
  138.    */
  139.   public void start() {
  140.     //only start the thread if the interval is sane
  141.     if(refreshInterval > 0) {
  142.       refreshUsed = new Thread(new DURefreshThread(), 
  143.           "refreshUsed-"+dirPath);
  144.       refreshUsed.setDaemon(true);
  145.       refreshUsed.start();
  146.     }
  147.   }
  148.   
  149.   /**
  150.    * Shut down the refreshing thread.
  151.    */
  152.   public void shutdown() {
  153.     this.shouldRun = false;
  154.     
  155.     if(this.refreshUsed != null) {
  156.       this.refreshUsed.interrupt();
  157.     }
  158.   }
  159.   
  160.   public String toString() {
  161.     return
  162.       "du -sk " + dirPath +"n" +
  163.       used + "t" + dirPath;
  164.   }
  165.   protected String[] getExecString() {
  166.     return new String[] {"du", "-sk", dirPath};
  167.   }
  168.   
  169.   protected void parseExecResult(BufferedReader lines) throws IOException {
  170.     String line = lines.readLine();
  171.     if (line == null) {
  172.       throw new IOException("Expecting a line not the end of stream");
  173.     }
  174.     String[] tokens = line.split("t");
  175.     if(tokens.length == 0) {
  176.       throw new IOException("Illegal du output");
  177.     }
  178.     this.used.set(Long.parseLong(tokens[0])*1024);
  179.   }
  180.   public static void main(String[] args) throws Exception {
  181.     String path = ".";
  182.     if (args.length > 0) {
  183.       path = args[0];
  184.     }
  185.     System.out.println(new DU(new File(path), new Configuration()).toString());
  186.   }
  187. }