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 */
018package org.apache.hadoop.fs;
019
020import java.io.DataInput;
021import java.io.DataOutput;
022import java.io.IOException;
023
024import org.apache.hadoop.classification.InterfaceAudience;
025import org.apache.hadoop.classification.InterfaceStability;
026import org.apache.hadoop.io.Writable;
027import org.apache.hadoop.util.StringUtils;
028
029/** Store the summary of a content (a directory or a file). */
030@InterfaceAudience.Public
031@InterfaceStability.Evolving
032public 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
105   */
106  private static final String SUMMARY_FORMAT = "%12s %12s %18s ";
107  /**
108   * Output format:
109   * <----12----> <------15-----> <------15-----> <------15----->
110   *        QUOTA       REM_QUOTA     SPACE_QUOTA REM_SPACE_QUOTA
111   * <----12----> <----12----> <-------18------->
112   *    DIR_COUNT   FILE_COUNT       CONTENT_SIZE
113   */
114  private static final String QUOTA_SUMMARY_FORMAT = "%12s %15s ";
115  private static final String SPACE_QUOTA_SUMMARY_FORMAT = "%15s %15s ";
116
117  private static final String[] HEADER_FIELDS = new String[] { "DIR_COUNT",
118      "FILE_COUNT", "CONTENT_SIZE"};
119  private static final String[] QUOTA_HEADER_FIELDS = new String[] { "QUOTA",
120      "REM_QUOTA", "SPACE_QUOTA", "REM_SPACE_QUOTA" };
121
122  /** The header string */
123  private static final String HEADER = String.format(
124      SUMMARY_FORMAT, (Object[]) HEADER_FIELDS);
125
126  private static final String QUOTA_HEADER = String.format(
127      QUOTA_SUMMARY_FORMAT + SPACE_QUOTA_SUMMARY_FORMAT,
128      (Object[]) QUOTA_HEADER_FIELDS) +
129      HEADER;
130  
131  /** Return the header of the output.
132   * if qOption is false, output directory count, file count, and content size;
133   * if qOption is true, output quota and remaining quota as well.
134   * 
135   * @param qOption a flag indicating if quota needs to be printed or not
136   * @return the header of the output
137   */
138  public static String getHeader(boolean qOption) {
139    return qOption ? QUOTA_HEADER : HEADER;
140  }
141
142  /**
143   * Returns the names of the fields from the summary header.
144   * 
145   * @return names of fields as displayed in the header
146   */
147  public static String[] getHeaderFields() {
148    return HEADER_FIELDS;
149  }
150
151  /**
152   * Returns the names of the fields used in the quota summary.
153   * 
154   * @return names of quota fields as displayed in the header
155   */
156  public static String[] getQuotaHeaderFields() {
157    return QUOTA_HEADER_FIELDS;
158  }
159
160  @Override
161  public String toString() {
162    return toString(true);
163  }
164
165  /** Return the string representation of the object in the output format.
166   * if qOption is false, output directory count, file count, and content size;
167   * if qOption is true, output quota and remaining quota as well.
168   *
169   * @param qOption a flag indicating if quota needs to be printed or not
170   * @return the string representation of the object
171  */
172  public String toString(boolean qOption) {
173    return toString(qOption, false);
174  }
175
176  /** Return the string representation of the object in the output format.
177   * if qOption is false, output directory count, file count, and content size;
178   * if qOption is true, output quota and remaining quota as well.
179   * if hOption is false file sizes are returned in bytes
180   * if hOption is true file sizes are returned in human readable 
181   * 
182   * @param qOption a flag indicating if quota needs to be printed or not
183   * @param hOption a flag indicating if human readable output if to be used
184   * @return the string representation of the object
185   */
186  public String toString(boolean qOption, boolean hOption) {
187    String prefix = "";
188    if (qOption) {
189      String quotaStr = "none";
190      String quotaRem = "inf";
191      String spaceQuotaStr = "none";
192      String spaceQuotaRem = "inf";
193      
194      if (quota>0) {
195        quotaStr = formatSize(quota, hOption);
196        quotaRem = formatSize(quota-(directoryCount+fileCount), hOption);
197      }
198      if (spaceQuota>0) {
199        spaceQuotaStr = formatSize(spaceQuota, hOption);
200        spaceQuotaRem = formatSize(spaceQuota - spaceConsumed, hOption);
201      }
202      
203      prefix = String.format(QUOTA_SUMMARY_FORMAT + SPACE_QUOTA_SUMMARY_FORMAT,
204                             quotaStr, quotaRem, spaceQuotaStr, spaceQuotaRem);
205    }
206    
207    return prefix + String.format(SUMMARY_FORMAT,
208     formatSize(directoryCount, hOption),
209     formatSize(fileCount, hOption),
210     formatSize(length, hOption));
211  }
212  /**
213   * Formats a size to be human readable or in bytes
214   * @param size value to be formatted
215   * @param humanReadable flag indicating human readable or not
216   * @return String representation of the size
217  */
218  private String formatSize(long size, boolean humanReadable) {
219    return humanReadable
220      ? StringUtils.TraditionalBinaryPrefix.long2String(size, "", 1)
221      : String.valueOf(size);
222  }
223}