| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.fs; |
| |
| import java.io.DataInput; |
| import java.io.DataOutput; |
| import java.io.IOException; |
| import java.util.List; |
| |
| import org.apache.hadoop.classification.InterfaceAudience; |
| import org.apache.hadoop.classification.InterfaceStability; |
| import org.apache.hadoop.io.Writable; |
| import org.apache.hadoop.util.StringUtils; |
| |
| /** Store the summary of a content (a directory or a file). */ |
| @InterfaceAudience.Public |
| @InterfaceStability.Evolving |
| public class ContentSummary extends QuotaUsage implements Writable{ |
| private long length; |
| private long fileCount; |
| private long directoryCount; |
| // These fields are to track the snapshot-related portion of the values. |
| private long snapshotLength; |
| private long snapshotFileCount; |
| private long snapshotDirectoryCount; |
| private long snapshotSpaceConsumed; |
| private String erasureCodingPolicy; |
| |
| /** We don't use generics. Instead override spaceConsumed and other methods |
| in order to keep backward compatibility. */ |
| public static class Builder extends QuotaUsage.Builder { |
| public Builder() { |
| } |
| |
| public Builder length(long length) { |
| this.length = length; |
| return this; |
| } |
| |
| public Builder fileCount(long fileCount) { |
| this.fileCount = fileCount; |
| return this; |
| } |
| |
| public Builder directoryCount(long directoryCount) { |
| this.directoryCount = directoryCount; |
| return this; |
| } |
| |
| public Builder snapshotLength(long snapshotLength) { |
| this.snapshotLength = snapshotLength; |
| return this; |
| } |
| |
| public Builder snapshotFileCount(long snapshotFileCount) { |
| this.snapshotFileCount = snapshotFileCount; |
| return this; |
| } |
| |
| public Builder snapshotDirectoryCount(long snapshotDirectoryCount) { |
| this.snapshotDirectoryCount = snapshotDirectoryCount; |
| return this; |
| } |
| |
| public Builder snapshotSpaceConsumed(long snapshotSpaceConsumed) { |
| this.snapshotSpaceConsumed = snapshotSpaceConsumed; |
| return this; |
| } |
| |
| public Builder erasureCodingPolicy(String ecPolicy) { |
| this.erasureCodingPolicy = ecPolicy; |
| return this; |
| } |
| |
| @Override |
| public Builder quota(long quota){ |
| super.quota(quota); |
| return this; |
| } |
| |
| @Override |
| public Builder spaceConsumed(long spaceConsumed) { |
| super.spaceConsumed(spaceConsumed); |
| return this; |
| } |
| |
| @Override |
| public Builder spaceQuota(long spaceQuota) { |
| super.spaceQuota(spaceQuota); |
| return this; |
| } |
| |
| @Override |
| public Builder typeConsumed(long typeConsumed[]) { |
| super.typeConsumed(typeConsumed); |
| return this; |
| } |
| |
| @Override |
| public Builder typeQuota(StorageType type, long quota) { |
| super.typeQuota(type, quota); |
| return this; |
| } |
| |
| @Override |
| public Builder typeConsumed(StorageType type, long consumed) { |
| super.typeConsumed(type, consumed); |
| return this; |
| } |
| |
| @Override |
| public Builder typeQuota(long typeQuota[]) { |
| super.typeQuota(typeQuota); |
| return this; |
| } |
| |
| public ContentSummary build() { |
| // Set it in case applications call QuotaUsage#getFileAndDirectoryCount. |
| super.fileAndDirectoryCount(this.fileCount + this.directoryCount); |
| return new ContentSummary(this); |
| } |
| |
| private long length; |
| private long fileCount; |
| private long directoryCount; |
| private long snapshotLength; |
| private long snapshotFileCount; |
| private long snapshotDirectoryCount; |
| private long snapshotSpaceConsumed; |
| private String erasureCodingPolicy; |
| } |
| |
| /** Constructor deprecated by ContentSummary.Builder*/ |
| @Deprecated |
| public ContentSummary() {} |
| |
| /** Constructor, deprecated by ContentSummary.Builder |
| * This constructor implicitly set spaceConsumed the same as length. |
| * spaceConsumed and length must be set explicitly with |
| * ContentSummary.Builder |
| * */ |
| @Deprecated |
| public ContentSummary(long length, long fileCount, long directoryCount) { |
| this(length, fileCount, directoryCount, -1L, length, -1L); |
| } |
| |
| /** Constructor, deprecated by ContentSummary.Builder */ |
| @Deprecated |
| public ContentSummary( |
| long length, long fileCount, long directoryCount, long quota, |
| long spaceConsumed, long spaceQuota) { |
| this.length = length; |
| this.fileCount = fileCount; |
| this.directoryCount = directoryCount; |
| setQuota(quota); |
| setSpaceConsumed(spaceConsumed); |
| setSpaceQuota(spaceQuota); |
| } |
| |
| /** Constructor for ContentSummary.Builder*/ |
| private ContentSummary(Builder builder) { |
| super(builder); |
| this.length = builder.length; |
| this.fileCount = builder.fileCount; |
| this.directoryCount = builder.directoryCount; |
| this.snapshotLength = builder.snapshotLength; |
| this.snapshotFileCount = builder.snapshotFileCount; |
| this.snapshotDirectoryCount = builder.snapshotDirectoryCount; |
| this.snapshotSpaceConsumed = builder.snapshotSpaceConsumed; |
| this.erasureCodingPolicy = builder.erasureCodingPolicy; |
| } |
| |
| /** @return the length */ |
| public long getLength() {return length;} |
| |
| public long getSnapshotLength() { |
| return snapshotLength; |
| } |
| |
| /** @return the directory count */ |
| public long getDirectoryCount() {return directoryCount;} |
| |
| public long getSnapshotDirectoryCount() { |
| return snapshotDirectoryCount; |
| } |
| |
| /** @return the file count */ |
| public long getFileCount() {return fileCount;} |
| |
| public long getSnapshotFileCount() { |
| return snapshotFileCount; |
| } |
| |
| public long getSnapshotSpaceConsumed() { |
| return snapshotSpaceConsumed; |
| } |
| |
| public String getErasureCodingPolicy() { |
| return erasureCodingPolicy; |
| } |
| |
| @Override |
| @InterfaceAudience.Private |
| public void write(DataOutput out) throws IOException { |
| out.writeLong(length); |
| out.writeLong(fileCount); |
| out.writeLong(directoryCount); |
| out.writeLong(getQuota()); |
| out.writeLong(getSpaceConsumed()); |
| out.writeLong(getSpaceQuota()); |
| } |
| |
| @Override |
| @InterfaceAudience.Private |
| public void readFields(DataInput in) throws IOException { |
| this.length = in.readLong(); |
| this.fileCount = in.readLong(); |
| this.directoryCount = in.readLong(); |
| setQuota(in.readLong()); |
| setSpaceConsumed(in.readLong()); |
| setSpaceQuota(in.readLong()); |
| } |
| |
| @Override |
| public boolean equals(Object to) { |
| if (this == to) { |
| return true; |
| } else if (to instanceof ContentSummary) { |
| ContentSummary right = (ContentSummary) to; |
| return getLength() == right.getLength() && |
| getFileCount() == right.getFileCount() && |
| getDirectoryCount() == right.getDirectoryCount() && |
| getSnapshotLength() == right.getSnapshotLength() && |
| getSnapshotFileCount() == right.getSnapshotFileCount() && |
| getSnapshotDirectoryCount() == right.getSnapshotDirectoryCount() && |
| getSnapshotSpaceConsumed() == right.getSnapshotSpaceConsumed() && |
| getErasureCodingPolicy().equals(right.getErasureCodingPolicy()) && |
| super.equals(to); |
| } else { |
| return super.equals(to); |
| } |
| } |
| |
| @Override |
| public int hashCode() { |
| long result = getLength() ^ getFileCount() ^ getDirectoryCount() |
| ^ getSnapshotLength() ^ getSnapshotFileCount() |
| ^ getSnapshotDirectoryCount() ^ getSnapshotSpaceConsumed() |
| ^ getErasureCodingPolicy().hashCode(); |
| return ((int) result) ^ super.hashCode(); |
| } |
| |
| /** |
| * Output format: |
| * <----12----> <----12----> <-------18-------> |
| * DIR_COUNT FILE_COUNT CONTENT_SIZE |
| */ |
| private static final String SUMMARY_FORMAT = "%12s %12s %18s "; |
| |
| private static final String[] SUMMARY_HEADER_FIELDS = |
| new String[] {"DIR_COUNT", "FILE_COUNT", "CONTENT_SIZE"}; |
| |
| /** The header string */ |
| private static final String SUMMARY_HEADER = String.format( |
| SUMMARY_FORMAT, (Object[]) SUMMARY_HEADER_FIELDS); |
| |
| private static final String ALL_HEADER = QUOTA_HEADER + SUMMARY_HEADER; |
| |
| /** |
| * Output format:<-------18-------> <----------24----------> |
| * <----------24---------->. <-------------28------------> SNAPSHOT_LENGTH |
| * SNAPSHOT_FILE_COUNT SNAPSHOT_DIR_COUNT SNAPSHOT_SPACE_CONSUMED |
| */ |
| private static final String SNAPSHOT_FORMAT = "%18s %24s %24s %28s "; |
| |
| private static final String[] SNAPSHOT_HEADER_FIELDS = |
| new String[] {"SNAPSHOT_LENGTH", "SNAPSHOT_FILE_COUNT", |
| "SNAPSHOT_DIR_COUNT", "SNAPSHOT_SPACE_CONSUMED"}; |
| |
| /** The header string. */ |
| private static final String SNAPSHOT_HEADER = |
| String.format(SNAPSHOT_FORMAT, (Object[]) SNAPSHOT_HEADER_FIELDS); |
| |
| |
| /** Return the header of the output. |
| * if qOption is false, output directory count, file count, and content size; |
| * if qOption is true, output quota and remaining quota as well. |
| * |
| * @param qOption a flag indicating if quota needs to be printed or not |
| * @return the header of the output |
| */ |
| public static String getHeader(boolean qOption) { |
| return qOption ? ALL_HEADER : SUMMARY_HEADER; |
| } |
| |
| public static String getSnapshotHeader() { |
| return SNAPSHOT_HEADER; |
| } |
| |
| /** |
| * Returns the names of the fields from the summary header. |
| * |
| * @return names of fields as displayed in the header |
| */ |
| public static String[] getHeaderFields() { |
| return SUMMARY_HEADER_FIELDS; |
| } |
| |
| /** |
| * Returns the names of the fields used in the quota summary. |
| * |
| * @return names of quota fields as displayed in the header |
| */ |
| public static String[] getQuotaHeaderFields() { |
| return QUOTA_HEADER_FIELDS; |
| } |
| |
| @Override |
| public String toString() { |
| return toString(true); |
| } |
| |
| /** Return the string representation of the object in the output format. |
| * if qOption is false, output directory count, file count, and content size; |
| * if qOption is true, output quota and remaining quota as well. |
| * |
| * @param qOption a flag indicating if quota needs to be printed or not |
| * @return the string representation of the object |
| */ |
| @Override |
| public String toString(boolean qOption) { |
| return toString(qOption, false); |
| } |
| |
| /** Return the string representation of the object in the output format. |
| * For description of the options, |
| * @see #toString(boolean, boolean, boolean, boolean, List) |
| * |
| * @param qOption a flag indicating if quota needs to be printed or not |
| * @param hOption a flag indicating if human readable output if to be used |
| * @return the string representation of the object |
| */ |
| public String toString(boolean qOption, boolean hOption) { |
| return toString(qOption, hOption, false, null); |
| } |
| |
| /** Return the string representation of the object in the output format. |
| * For description of the options, |
| * @see #toString(boolean, boolean, boolean, boolean, List) |
| * |
| * @param qOption a flag indicating if quota needs to be printed or not |
| * @param hOption a flag indicating if human readable output is to be used |
| * @param xOption a flag indicating if calculation from snapshots is to be |
| * included in the output |
| * @return the string representation of the object |
| */ |
| public String toString(boolean qOption, boolean hOption, boolean xOption) { |
| return toString(qOption, hOption, false, xOption, null); |
| } |
| |
| /** |
| * Return the string representation of the object in the output format. |
| * For description of the options, |
| * @see #toString(boolean, boolean, boolean, boolean, List) |
| * |
| * @param qOption a flag indicating if quota needs to be printed or not |
| * @param hOption a flag indicating if human readable output if to be used |
| * @param tOption a flag indicating if display quota by storage types |
| * @param types Storage types to display |
| * @return the string representation of the object |
| */ |
| public String toString(boolean qOption, boolean hOption, |
| boolean tOption, List<StorageType> types) { |
| return toString(qOption, hOption, tOption, false, types); |
| } |
| |
| /** Return the string representation of the object in the output format. |
| * if qOption is false, output directory count, file count, and content size; |
| * if qOption is true, output quota and remaining quota as well. |
| * if hOption is false, file sizes are returned in bytes |
| * if hOption is true, file sizes are returned in human readable |
| * if tOption is true, display the quota by storage types |
| * if tOption is false, same logic with #toString(boolean,boolean) |
| * if xOption is false, output includes the calculation from snapshots |
| * if xOption is true, output excludes the calculation from snapshots |
| * |
| * @param qOption a flag indicating if quota needs to be printed or not |
| * @param hOption a flag indicating if human readable output is to be used |
| * @param tOption a flag indicating if display quota by storage types |
| * @param xOption a flag indicating if calculation from snapshots is to be |
| * included in the output |
| * @param types Storage types to display |
| * @return the string representation of the object |
| */ |
| public String toString(boolean qOption, boolean hOption, boolean tOption, |
| boolean xOption, List<StorageType> types) { |
| String prefix = ""; |
| |
| if (tOption) { |
| return getTypesQuotaUsage(hOption, types); |
| } |
| |
| if (qOption) { |
| prefix = getQuotaUsage(hOption); |
| } |
| |
| if (xOption) { |
| return prefix + String.format(SUMMARY_FORMAT, |
| formatSize(directoryCount - snapshotDirectoryCount, hOption), |
| formatSize(fileCount - snapshotFileCount, hOption), |
| formatSize(length - snapshotLength, hOption)); |
| } else { |
| return prefix + String.format(SUMMARY_FORMAT, |
| formatSize(directoryCount, hOption), |
| formatSize(fileCount, hOption), |
| formatSize(length, hOption)); |
| } |
| } |
| |
| /** |
| * Formats a size to be human readable or in bytes. |
| * @param size value to be formatted |
| * @param humanReadable flag indicating human readable or not |
| * @return String representation of the size |
| */ |
| private String formatSize(long size, boolean humanReadable) { |
| return humanReadable |
| ? StringUtils.TraditionalBinaryPrefix.long2String(size, "", 1) |
| : String.valueOf(size); |
| } |
| |
| /** |
| * Return the string representation of the snapshot counts in the output |
| * format. |
| * @param hOption flag indicating human readable or not |
| * @return String representation of the snapshot counts |
| */ |
| public String toSnapshot(boolean hOption) { |
| return String.format(SNAPSHOT_FORMAT, formatSize(snapshotLength, hOption), |
| formatSize(snapshotFileCount, hOption), |
| formatSize(snapshotDirectoryCount, hOption), |
| formatSize(snapshotSpaceConsumed, hOption)); |
| } |
| } |