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.fs;
019    
020    import java.io.DataInput;
021    import java.io.DataOutput;
022    import java.io.IOException;
023    
024    import org.apache.hadoop.classification.InterfaceAudience;
025    import org.apache.hadoop.classification.InterfaceStability;
026    import org.apache.hadoop.io.Writable;
027    import org.apache.hadoop.util.StringUtils;
028    
029    /** Store the summary of a content (a directory or a file). */
030    @InterfaceAudience.Public
031    @InterfaceStability.Evolving
032    public class ContentSummary implements Writable{
033      private long length;
034      private long fileCount;
035      private long directoryCount;
036      private long quota;
037      private long spaceConsumed;
038      private long spaceQuota;
039      
040    
041      /** Constructor */
042      public ContentSummary() {}
043      
044      /** Constructor */
045      public ContentSummary(long length, long fileCount, long directoryCount) {
046        this(length, fileCount, directoryCount, -1L, length, -1L);
047      }
048    
049      /** Constructor */
050      public ContentSummary(
051          long length, long fileCount, long directoryCount, long quota,
052          long spaceConsumed, long spaceQuota) {
053        this.length = length;
054        this.fileCount = fileCount;
055        this.directoryCount = directoryCount;
056        this.quota = quota;
057        this.spaceConsumed = spaceConsumed;
058        this.spaceQuota = spaceQuota;
059      }
060    
061      /** @return the length */
062      public long getLength() {return length;}
063    
064      /** @return the directory count */
065      public long getDirectoryCount() {return directoryCount;}
066    
067      /** @return the file count */
068      public long getFileCount() {return fileCount;}
069      
070      /** Return the directory quota */
071      public long getQuota() {return quota;}
072      
073      /** Retuns (disk) space consumed */ 
074      public long getSpaceConsumed() {return spaceConsumed;}
075    
076      /** Returns (disk) space quota */
077      public long getSpaceQuota() {return spaceQuota;}
078      
079      @Override
080      @InterfaceAudience.Private
081      public void write(DataOutput out) throws IOException {
082        out.writeLong(length);
083        out.writeLong(fileCount);
084        out.writeLong(directoryCount);
085        out.writeLong(quota);
086        out.writeLong(spaceConsumed);
087        out.writeLong(spaceQuota);
088      }
089    
090      @Override
091      @InterfaceAudience.Private
092      public void readFields(DataInput in) throws IOException {
093        this.length = in.readLong();
094        this.fileCount = in.readLong();
095        this.directoryCount = in.readLong();
096        this.quota = in.readLong();
097        this.spaceConsumed = in.readLong();
098        this.spaceQuota = in.readLong();
099      }
100      
101      /** 
102       * Output format:
103       * <----12----> <----12----> <-------18------->
104       *    DIR_COUNT   FILE_COUNT       CONTENT_SIZE FILE_NAME    
105       */
106      private static final String STRING_FORMAT = "%12s %12s %18s ";
107      /** 
108       * Output format:
109       * <----12----> <----15----> <----15----> <----15----> <----12----> <----12----> <-------18------->
110       *    QUOTA   REMAINING_QUATA SPACE_QUOTA SPACE_QUOTA_REM DIR_COUNT   FILE_COUNT   CONTENT_SIZE     FILE_NAME    
111       */
112      private static final String QUOTA_STRING_FORMAT = "%12s %15s ";
113      private static final String SPACE_QUOTA_STRING_FORMAT = "%15s %15s ";
114      
115      /** The header string */
116      private static final String HEADER = String.format(
117          STRING_FORMAT.replace('d', 's'), "directories", "files", "bytes");
118    
119      private static final String QUOTA_HEADER = String.format(
120          QUOTA_STRING_FORMAT + SPACE_QUOTA_STRING_FORMAT, 
121          "name quota", "rem name quota", "space quota", "rem space quota") +
122          HEADER;
123      
124      /** Return the header of the output.
125       * if qOption is false, output directory count, file count, and content size;
126       * if qOption is true, output quota and remaining quota as well.
127       * 
128       * @param qOption a flag indicating if quota needs to be printed or not
129       * @return the header of the output
130       */
131      public static String getHeader(boolean qOption) {
132        return qOption ? QUOTA_HEADER : HEADER;
133      }
134      
135      @Override
136      public String toString() {
137        return toString(true);
138      }
139    
140      /** Return the string representation of the object in the output format.
141       * if qOption is false, output directory count, file count, and content size;
142       * if qOption is true, output quota and remaining quota as well.
143       *
144       * @param qOption a flag indicating if quota needs to be printed or not
145       * @return the string representation of the object
146      */
147      public String toString(boolean qOption) {
148        return toString(qOption, false);
149      }
150    
151      /** Return the string representation of the object in the output format.
152       * if qOption is false, output directory count, file count, and content size;
153       * if qOption is true, output quota and remaining quota as well.
154       * if hOption is false file sizes are returned in bytes
155       * if hOption is true file sizes are returned in human readable 
156       * 
157       * @param qOption a flag indicating if quota needs to be printed or not
158       * @param hOption a flag indicating if human readable output if to be used
159       * @return the string representation of the object
160       */
161      public String toString(boolean qOption, boolean hOption) {
162        String prefix = "";
163        if (qOption) {
164          String quotaStr = "none";
165          String quotaRem = "inf";
166          String spaceQuotaStr = "none";
167          String spaceQuotaRem = "inf";
168          
169          if (quota>0) {
170            quotaStr = formatSize(quota, hOption);
171            quotaRem = formatSize(quota-(directoryCount+fileCount), hOption);
172          }
173          if (spaceQuota>0) {
174            spaceQuotaStr = formatSize(spaceQuota, hOption);
175            spaceQuotaRem = formatSize(spaceQuota - spaceConsumed, hOption);
176          }
177          
178          prefix = String.format(QUOTA_STRING_FORMAT + SPACE_QUOTA_STRING_FORMAT, 
179                                 quotaStr, quotaRem, spaceQuotaStr, spaceQuotaRem);
180        }
181        
182        return prefix + String.format(STRING_FORMAT,
183         formatSize(directoryCount, hOption),
184         formatSize(fileCount, hOption),
185         formatSize(length, hOption));
186      }
187      /**
188       * Formats a size to be human readable or in bytes
189       * @param size value to be formatted
190       * @param humanReadable flag indicating human readable or not
191       * @return String representation of the size
192      */
193      private String formatSize(long size, boolean humanReadable) {
194        return humanReadable
195          ? StringUtils.TraditionalBinaryPrefix.long2String(size, "", 1)
196          : String.valueOf(size);
197      }
198    }