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; 023import java.util.List; 024 025import org.apache.hadoop.classification.InterfaceAudience; 026import org.apache.hadoop.classification.InterfaceStability; 027import org.apache.hadoop.io.Writable; 028import org.apache.hadoop.util.StringUtils; 029 030/** Store the summary of a content (a directory or a file). */ 031@InterfaceAudience.Public 032@InterfaceStability.Evolving 033public class ContentSummary extends QuotaUsage implements Writable{ 034 private long length; 035 private long fileCount; 036 private long directoryCount; 037 // These fields are to track the snapshot-related portion of the values. 038 private long snapshotLength; 039 private long snapshotFileCount; 040 private long snapshotDirectoryCount; 041 private long snapshotSpaceConsumed; 042 043 /** We don't use generics. Instead override spaceConsumed and other methods 044 in order to keep backward compatibility. */ 045 public static class Builder extends QuotaUsage.Builder { 046 public Builder() { 047 } 048 049 public Builder length(long length) { 050 this.length = length; 051 return this; 052 } 053 054 public Builder fileCount(long fileCount) { 055 this.fileCount = fileCount; 056 return this; 057 } 058 059 public Builder directoryCount(long directoryCount) { 060 this.directoryCount = directoryCount; 061 return this; 062 } 063 064 public Builder snapshotLength(long snapshotLength) { 065 this.snapshotLength = snapshotLength; 066 return this; 067 } 068 069 public Builder snapshotFileCount(long snapshotFileCount) { 070 this.snapshotFileCount = snapshotFileCount; 071 return this; 072 } 073 074 public Builder snapshotDirectoryCount(long snapshotDirectoryCount) { 075 this.snapshotDirectoryCount = snapshotDirectoryCount; 076 return this; 077 } 078 079 public Builder snapshotSpaceConsumed(long snapshotSpaceConsumed) { 080 this.snapshotSpaceConsumed = snapshotSpaceConsumed; 081 return this; 082 } 083 084 @Override 085 public Builder quota(long quota){ 086 super.quota(quota); 087 return this; 088 } 089 090 @Override 091 public Builder spaceConsumed(long spaceConsumed) { 092 super.spaceConsumed(spaceConsumed); 093 return this; 094 } 095 096 @Override 097 public Builder spaceQuota(long spaceQuota) { 098 super.spaceQuota(spaceQuota); 099 return this; 100 } 101 102 @Override 103 public Builder typeConsumed(long typeConsumed[]) { 104 super.typeConsumed(typeConsumed); 105 return this; 106 } 107 108 @Override 109 public Builder typeQuota(StorageType type, long quota) { 110 super.typeQuota(type, quota); 111 return this; 112 } 113 114 @Override 115 public Builder typeConsumed(StorageType type, long consumed) { 116 super.typeConsumed(type, consumed); 117 return this; 118 } 119 120 @Override 121 public Builder typeQuota(long typeQuota[]) { 122 super.typeQuota(typeQuota); 123 return this; 124 } 125 126 public ContentSummary build() { 127 // Set it in case applications call QuotaUsage#getFileAndDirectoryCount. 128 super.fileAndDirectoryCount(this.fileCount + this.directoryCount); 129 return new ContentSummary(this); 130 } 131 132 private long length; 133 private long fileCount; 134 private long directoryCount; 135 private long snapshotLength; 136 private long snapshotFileCount; 137 private long snapshotDirectoryCount; 138 private long snapshotSpaceConsumed; 139 } 140 141 /** Constructor deprecated by ContentSummary.Builder*/ 142 @Deprecated 143 public ContentSummary() {} 144 145 /** Constructor, deprecated by ContentSummary.Builder 146 * This constructor implicitly set spaceConsumed the same as length. 147 * spaceConsumed and length must be set explicitly with 148 * ContentSummary.Builder 149 * */ 150 @Deprecated 151 public ContentSummary(long length, long fileCount, long directoryCount) { 152 this(length, fileCount, directoryCount, -1L, length, -1L); 153 } 154 155 /** Constructor, deprecated by ContentSummary.Builder */ 156 @Deprecated 157 public ContentSummary( 158 long length, long fileCount, long directoryCount, long quota, 159 long spaceConsumed, long spaceQuota) { 160 this.length = length; 161 this.fileCount = fileCount; 162 this.directoryCount = directoryCount; 163 setQuota(quota); 164 setSpaceConsumed(spaceConsumed); 165 setSpaceQuota(spaceQuota); 166 } 167 168 /** Constructor for ContentSummary.Builder*/ 169 private ContentSummary(Builder builder) { 170 super(builder); 171 this.length = builder.length; 172 this.fileCount = builder.fileCount; 173 this.directoryCount = builder.directoryCount; 174 this.snapshotLength = builder.snapshotLength; 175 this.snapshotFileCount = builder.snapshotFileCount; 176 this.snapshotDirectoryCount = builder.snapshotDirectoryCount; 177 this.snapshotSpaceConsumed = builder.snapshotSpaceConsumed; 178 } 179 180 /** @return the length */ 181 public long getLength() {return length;} 182 183 public long getSnapshotLength() { 184 return snapshotLength; 185 } 186 187 /** @return the directory count */ 188 public long getDirectoryCount() {return directoryCount;} 189 190 public long getSnapshotDirectoryCount() { 191 return snapshotDirectoryCount; 192 } 193 194 /** @return the file count */ 195 public long getFileCount() {return fileCount;} 196 197 public long getSnapshotFileCount() { 198 return snapshotFileCount; 199 } 200 201 public long getSnapshotSpaceConsumed() { 202 return snapshotSpaceConsumed; 203 } 204 205 @Override 206 @InterfaceAudience.Private 207 public void write(DataOutput out) throws IOException { 208 out.writeLong(length); 209 out.writeLong(fileCount); 210 out.writeLong(directoryCount); 211 out.writeLong(getQuota()); 212 out.writeLong(getSpaceConsumed()); 213 out.writeLong(getSpaceQuota()); 214 } 215 216 @Override 217 @InterfaceAudience.Private 218 public void readFields(DataInput in) throws IOException { 219 this.length = in.readLong(); 220 this.fileCount = in.readLong(); 221 this.directoryCount = in.readLong(); 222 setQuota(in.readLong()); 223 setSpaceConsumed(in.readLong()); 224 setSpaceQuota(in.readLong()); 225 } 226 227 @Override 228 public boolean equals(Object to) { 229 if (this == to) { 230 return true; 231 } else if (to instanceof ContentSummary) { 232 ContentSummary right = (ContentSummary) to; 233 return getLength() == right.getLength() && 234 getFileCount() == right.getFileCount() && 235 getDirectoryCount() == right.getDirectoryCount() && 236 getSnapshotLength() == right.getSnapshotLength() && 237 getSnapshotFileCount() == right.getSnapshotFileCount() && 238 getSnapshotDirectoryCount() == right.getSnapshotDirectoryCount() && 239 getSnapshotSpaceConsumed() == right.getSnapshotSpaceConsumed() && 240 super.equals(to); 241 } else { 242 return super.equals(to); 243 } 244 } 245 246 @Override 247 public int hashCode() { 248 long result = getLength() ^ getFileCount() ^ getDirectoryCount() 249 ^ getSnapshotLength() ^ getSnapshotFileCount() 250 ^ getSnapshotDirectoryCount() ^ getSnapshotSpaceConsumed(); 251 return ((int) result) ^ super.hashCode(); 252 } 253 254 /** 255 * Output format: 256 * <----12----> <----12----> <-------18-------> 257 * DIR_COUNT FILE_COUNT CONTENT_SIZE 258 */ 259 private static final String SUMMARY_FORMAT = "%12s %12s %18s "; 260 261 private static final String[] SUMMARY_HEADER_FIELDS = 262 new String[] {"DIR_COUNT", "FILE_COUNT", "CONTENT_SIZE"}; 263 264 /** The header string */ 265 private static final String SUMMARY_HEADER = String.format( 266 SUMMARY_FORMAT, (Object[]) SUMMARY_HEADER_FIELDS); 267 268 private static final String ALL_HEADER = QUOTA_HEADER + SUMMARY_HEADER; 269 270 271 /** Return the header of the output. 272 * if qOption is false, output directory count, file count, and content size; 273 * if qOption is true, output quota and remaining quota as well. 274 * 275 * @param qOption a flag indicating if quota needs to be printed or not 276 * @return the header of the output 277 */ 278 public static String getHeader(boolean qOption) { 279 return qOption ? ALL_HEADER : SUMMARY_HEADER; 280 } 281 282 283 284 /** 285 * Returns the names of the fields from the summary header. 286 * 287 * @return names of fields as displayed in the header 288 */ 289 public static String[] getHeaderFields() { 290 return SUMMARY_HEADER_FIELDS; 291 } 292 293 /** 294 * Returns the names of the fields used in the quota summary. 295 * 296 * @return names of quota fields as displayed in the header 297 */ 298 public static String[] getQuotaHeaderFields() { 299 return QUOTA_HEADER_FIELDS; 300 } 301 302 @Override 303 public String toString() { 304 return toString(true); 305 } 306 307 /** Return the string representation of the object in the output format. 308 * if qOption is false, output directory count, file count, and content size; 309 * if qOption is true, output quota and remaining quota as well. 310 * 311 * @param qOption a flag indicating if quota needs to be printed or not 312 * @return the string representation of the object 313 */ 314 @Override 315 public String toString(boolean qOption) { 316 return toString(qOption, false); 317 } 318 319 /** Return the string representation of the object in the output format. 320 * For description of the options, 321 * @see #toString(boolean, boolean, boolean, boolean, List) 322 * 323 * @param qOption a flag indicating if quota needs to be printed or not 324 * @param hOption a flag indicating if human readable output if to be used 325 * @return the string representation of the object 326 */ 327 public String toString(boolean qOption, boolean hOption) { 328 return toString(qOption, hOption, false, null); 329 } 330 331 /** Return the string representation of the object in the output format. 332 * For description of the options, 333 * @see #toString(boolean, boolean, boolean, boolean, List) 334 * 335 * @param qOption a flag indicating if quota needs to be printed or not 336 * @param hOption a flag indicating if human readable output is to be used 337 * @param xOption a flag indicating if calculation from snapshots is to be 338 * included in the output 339 * @return the string representation of the object 340 */ 341 public String toString(boolean qOption, boolean hOption, boolean xOption) { 342 return toString(qOption, hOption, false, xOption, null); 343 } 344 345 /** 346 * Return the string representation of the object in the output format. 347 * For description of the options, 348 * @see #toString(boolean, boolean, boolean, boolean, List) 349 * 350 * @param qOption a flag indicating if quota needs to be printed or not 351 * @param hOption a flag indicating if human readable output if to be used 352 * @param tOption a flag indicating if display quota by storage types 353 * @param types Storage types to display 354 * @return the string representation of the object 355 */ 356 public String toString(boolean qOption, boolean hOption, 357 boolean tOption, List<StorageType> types) { 358 return toString(qOption, hOption, tOption, false, types); 359 } 360 361 /** Return the string representation of the object in the output format. 362 * if qOption is false, output directory count, file count, and content size; 363 * if qOption is true, output quota and remaining quota as well. 364 * if hOption is false, file sizes are returned in bytes 365 * if hOption is true, file sizes are returned in human readable 366 * if tOption is true, display the quota by storage types 367 * if tOption is false, same logic with #toString(boolean,boolean) 368 * if xOption is false, output includes the calculation from snapshots 369 * if xOption is true, output excludes the calculation from snapshots 370 * 371 * @param qOption a flag indicating if quota needs to be printed or not 372 * @param hOption a flag indicating if human readable output is to be used 373 * @param tOption a flag indicating if display quota by storage types 374 * @param xOption a flag indicating if calculation from snapshots is to be 375 * included in the output 376 * @param types Storage types to display 377 * @return the string representation of the object 378 */ 379 public String toString(boolean qOption, boolean hOption, boolean tOption, 380 boolean xOption, List<StorageType> types) { 381 String prefix = ""; 382 383 if (tOption) { 384 return getTypesQuotaUsage(hOption, types); 385 } 386 387 if (qOption) { 388 prefix = getQuotaUsage(hOption); 389 } 390 391 if (xOption) { 392 return prefix + String.format(SUMMARY_FORMAT, 393 formatSize(directoryCount - snapshotDirectoryCount, hOption), 394 formatSize(fileCount - snapshotFileCount, hOption), 395 formatSize(length - snapshotLength, hOption)); 396 } else { 397 return prefix + String.format(SUMMARY_FORMAT, 398 formatSize(directoryCount, hOption), 399 formatSize(fileCount, hOption), 400 formatSize(length, hOption)); 401 } 402 } 403 404 /** 405 * Formats a size to be human readable or in bytes 406 * @param size value to be formatted 407 * @param humanReadable flag indicating human readable or not 408 * @return String representation of the size 409 */ 410 private String formatSize(long size, boolean humanReadable) { 411 return humanReadable 412 ? StringUtils.TraditionalBinaryPrefix.long2String(size, "", 1) 413 : String.valueOf(size); 414 } 415}